diff options
602 files changed, 6017 insertions, 4477 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 2861055afd7..c2791589397 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
| @@ -73,8 +73,8 @@ | |||
| 73 | services. | 73 | services. |
| 74 | </para> | 74 | </para> |
| 75 | <para> | 75 | <para> |
| 76 | The core of every DRM driver is struct drm_device. Drivers | 76 | The core of every DRM driver is struct drm_driver. Drivers |
| 77 | will typically statically initialize a drm_device structure, | 77 | will typically statically initialize a drm_driver structure, |
| 78 | then pass it to drm_init() at load time. | 78 | then pass it to drm_init() at load time. |
| 79 | </para> | 79 | </para> |
| 80 | 80 | ||
| @@ -84,7 +84,7 @@ | |||
| 84 | <title>Driver initialization</title> | 84 | <title>Driver initialization</title> |
| 85 | <para> | 85 | <para> |
| 86 | Before calling the DRM initialization routines, the driver must | 86 | Before calling the DRM initialization routines, the driver must |
| 87 | first create and fill out a struct drm_device structure. | 87 | first create and fill out a struct drm_driver structure. |
| 88 | </para> | 88 | </para> |
| 89 | <programlisting> | 89 | <programlisting> |
| 90 | static struct drm_driver driver = { | 90 | static struct drm_driver driver = { |
diff --git a/Documentation/powerpc/dts-bindings/fsl/sata.txt b/Documentation/devicetree/bindings/ata/fsl-sata.txt index b46bcf46c3d..b46bcf46c3d 100644 --- a/Documentation/powerpc/dts-bindings/fsl/sata.txt +++ b/Documentation/devicetree/bindings/ata/fsl-sata.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/eeprom.txt b/Documentation/devicetree/bindings/eeprom.txt index 4342c10de1b..4342c10de1b 100644 --- a/Documentation/powerpc/dts-bindings/eeprom.txt +++ b/Documentation/devicetree/bindings/eeprom.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt b/Documentation/devicetree/bindings/gpio/8xxx_gpio.txt index b0019eb5330..b0019eb5330 100644 --- a/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt +++ b/Documentation/devicetree/bindings/gpio/8xxx_gpio.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index edaa84d288a..edaa84d288a 100644 --- a/Documentation/powerpc/dts-bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/devicetree/bindings/gpio/led.txt index 064db928c3c..064db928c3c 100644 --- a/Documentation/powerpc/dts-bindings/gpio/led.txt +++ b/Documentation/devicetree/bindings/gpio/led.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/devicetree/bindings/i2c/fsl-i2c.txt index 1eacd6b20ed..1eacd6b20ed 100644 --- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt +++ b/Documentation/devicetree/bindings/i2c/fsl-i2c.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/marvell.txt b/Documentation/devicetree/bindings/marvell.txt index f1533d91953..f1533d91953 100644 --- a/Documentation/powerpc/dts-bindings/marvell.txt +++ b/Documentation/devicetree/bindings/marvell.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index 64bcb8be973..64bcb8be973 100644 --- a/Documentation/powerpc/dts-bindings/fsl/esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt b/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt index c39ac289195..c39ac289195 100644 --- a/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt +++ b/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt index a48b2cadc7f..a48b2cadc7f 100644 --- a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt +++ b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt index 80152cb567d..80152cb567d 100644 --- a/Documentation/powerpc/dts-bindings/mtd-physmap.txt +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/can.txt b/Documentation/devicetree/bindings/net/can/mpc5xxx-mscan.txt index 2fa4fcd38fd..2fa4fcd38fd 100644 --- a/Documentation/powerpc/dts-bindings/fsl/can.txt +++ b/Documentation/devicetree/bindings/net/can/mpc5xxx-mscan.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/can/sja1000.txt b/Documentation/devicetree/bindings/net/can/sja1000.txt index d6d209ded93..d6d209ded93 100644 --- a/Documentation/powerpc/dts-bindings/can/sja1000.txt +++ b/Documentation/devicetree/bindings/net/can/sja1000.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/tsec.txt b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt index edb7ae19e86..edb7ae19e86 100644 --- a/Documentation/powerpc/dts-bindings/fsl/tsec.txt +++ b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/gpio/mdio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt index bc954952901..bc954952901 100644 --- a/Documentation/powerpc/dts-bindings/gpio/mdio.txt +++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index bb8c742eb8c..bb8c742eb8c 100644 --- a/Documentation/powerpc/dts-bindings/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt index 35a46536240..35a46536240 100644 --- a/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt +++ b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/4xx/cpm.txt b/Documentation/devicetree/bindings/powerpc/4xx/cpm.txt index ee459806d35..ee459806d35 100644 --- a/Documentation/powerpc/dts-bindings/4xx/cpm.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/cpm.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/4xx/emac.txt b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt index 2161334a7ca..2161334a7ca 100644 --- a/Documentation/powerpc/dts-bindings/4xx/emac.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/4xx/ndfc.txt b/Documentation/devicetree/bindings/powerpc/4xx/ndfc.txt index 869f0b5f16e..869f0b5f16e 100644 --- a/Documentation/powerpc/dts-bindings/4xx/ndfc.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/ndfc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt b/Documentation/devicetree/bindings/powerpc/4xx/ppc440spe-adma.txt index 515ebcf1b97..515ebcf1b97 100644 --- a/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/ppc440spe-adma.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/4xx/reboot.txt b/Documentation/devicetree/bindings/powerpc/4xx/reboot.txt index d7217260589..d7217260589 100644 --- a/Documentation/powerpc/dts-bindings/4xx/reboot.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/reboot.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/board.txt b/Documentation/devicetree/bindings/powerpc/fsl/board.txt index 39e941515a3..39e941515a3 100644 --- a/Documentation/powerpc/dts-bindings/fsl/board.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm.txt index 160c752484b..160c752484b 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/brg.txt index 4c7d45eaf02..4c7d45eaf02 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/brg.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/i2c.txt index 87bc6048667..87bc6048667 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/i2c.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/pic.txt index 8e3ee168161..8e3ee168161 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/pic.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/usb.txt index 74bfda4bb82..74bfda4bb82 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/usb.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/gpio.txt index 349f79fd707..349f79fd707 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/gpio.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt index 0e426944658..0e426944658 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe.txt index 4f8930263dd..4f8930263dd 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/firmware.txt index 249db3a15d1..249db3a15d1 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/firmware.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/par_io.txt index 60984260207..60984260207 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/par_io.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt index c5b43061db3..c5b43061db3 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/ucc.txt index e47734bee3f..e47734bee3f 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/ucc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/usb.txt index 9ccd5f30405..9ccd5f30405 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/usb.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/serial.txt index 2ea76d9d137..2ea76d9d137 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/serial.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/diu.txt b/Documentation/devicetree/bindings/powerpc/fsl/diu.txt index b66cb6d31d6..b66cb6d31d6 100644 --- a/Documentation/powerpc/dts-bindings/fsl/diu.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/diu.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/dma.txt b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt index 2a4b4bce611..2a4b4bce611 100644 --- a/Documentation/powerpc/dts-bindings/fsl/dma.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/ecm.txt b/Documentation/devicetree/bindings/powerpc/fsl/ecm.txt index f514f29c67d..f514f29c67d 100644 --- a/Documentation/powerpc/dts-bindings/ecm.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/ecm.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/gtm.txt b/Documentation/devicetree/bindings/powerpc/fsl/gtm.txt index 9a33efded4b..9a33efded4b 100644 --- a/Documentation/powerpc/dts-bindings/fsl/gtm.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/gtm.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/guts.txt b/Documentation/devicetree/bindings/powerpc/fsl/guts.txt index 9e7a2417dac..9e7a2417dac 100644 --- a/Documentation/powerpc/dts-bindings/fsl/guts.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/guts.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/lbc.txt b/Documentation/devicetree/bindings/powerpc/fsl/lbc.txt index 3300fec501c..3300fec501c 100644 --- a/Documentation/powerpc/dts-bindings/fsl/lbc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/lbc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcm.txt b/Documentation/devicetree/bindings/powerpc/fsl/mcm.txt index 4ceda9b3b41..4ceda9b3b41 100644 --- a/Documentation/powerpc/dts-bindings/fsl/mcm.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mcm.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt b/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt index 0f766333b6e..0f766333b6e 100644 --- a/Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpc5121-psc.txt index 8832e879891..8832e879891 100644 --- a/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5121-psc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt index 4ccb2cd5df9..4ccb2cd5df9 100644 --- a/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt index 71e39cf3215..71e39cf3215 100644 --- a/Documentation/powerpc/dts-bindings/fsl/mpic.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/msi-pic.txt b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt index bcc30bac683..bcc30bac683 100644 --- a/Documentation/powerpc/dts-bindings/fsl/msi-pic.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/pmc.txt b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt index 07256b7ffca..07256b7ffca 100644 --- a/Documentation/powerpc/dts-bindings/fsl/pmc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/sec.txt b/Documentation/devicetree/bindings/powerpc/fsl/sec.txt index 2b6f2d45c45..2b6f2d45c45 100644 --- a/Documentation/powerpc/dts-bindings/fsl/sec.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/sec.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/ssi.txt b/Documentation/devicetree/bindings/powerpc/fsl/ssi.txt index 5ff76c9c57d..5ff76c9c57d 100644 --- a/Documentation/powerpc/dts-bindings/fsl/ssi.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/ssi.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt b/Documentation/devicetree/bindings/powerpc/nintendo/gamecube.txt index b558585b1aa..b558585b1aa 100644 --- a/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt +++ b/Documentation/devicetree/bindings/powerpc/nintendo/gamecube.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/nintendo/wii.txt b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt index a7e155a023b..a7e155a023b 100644 --- a/Documentation/powerpc/dts-bindings/nintendo/wii.txt +++ b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt b/Documentation/devicetree/bindings/spi/fsl-spi.txt index 777abd7399d..777abd7399d 100644 --- a/Documentation/powerpc/dts-bindings/fsl/spi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-spi.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index e782add2e45..e782add2e45 100644 --- a/Documentation/powerpc/dts-bindings/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentation/devicetree/bindings/usb/fsl-usb.txt index bd5723f0b67..bd5723f0b67 100644 --- a/Documentation/powerpc/dts-bindings/fsl/usb.txt +++ b/Documentation/devicetree/bindings/usb/fsl-usb.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index fa18612f757..fa18612f757 100644 --- a/Documentation/powerpc/dts-bindings/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt | |||
diff --git a/Documentation/powerpc/dts-bindings/xilinx.txt b/Documentation/devicetree/bindings/xilinx.txt index 299d0923537..299d0923537 100644 --- a/Documentation/powerpc/dts-bindings/xilinx.txt +++ b/Documentation/devicetree/bindings/xilinx.txt | |||
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index 7400d7555dc..28b1c9d3d35 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt | |||
| @@ -13,7 +13,6 @@ Table of Contents | |||
| 13 | 13 | ||
| 14 | I - Introduction | 14 | I - Introduction |
| 15 | 1) Entry point for arch/powerpc | 15 | 1) Entry point for arch/powerpc |
| 16 | 2) Board support | ||
| 17 | 16 | ||
| 18 | II - The DT block format | 17 | II - The DT block format |
| 19 | 1) Header | 18 | 1) Header |
| @@ -41,13 +40,6 @@ Table of Contents | |||
| 41 | VI - System-on-a-chip devices and nodes | 40 | VI - System-on-a-chip devices and nodes |
| 42 | 1) Defining child nodes of an SOC | 41 | 1) Defining child nodes of an SOC |
| 43 | 2) Representing devices without a current OF specification | 42 | 2) Representing devices without a current OF specification |
| 44 | a) PHY nodes | ||
| 45 | b) Interrupt controllers | ||
| 46 | c) 4xx/Axon EMAC ethernet nodes | ||
| 47 | d) Xilinx IP cores | ||
| 48 | e) USB EHCI controllers | ||
| 49 | f) MDIO on GPIOs | ||
| 50 | g) SPI busses | ||
| 51 | 43 | ||
| 52 | VII - Specifying interrupt information for devices | 44 | VII - Specifying interrupt information for devices |
| 53 | 1) interrupts property | 45 | 1) interrupts property |
| @@ -123,7 +115,7 @@ Revision Information | |||
| 123 | I - Introduction | 115 | I - Introduction |
| 124 | ================ | 116 | ================ |
| 125 | 117 | ||
| 126 | During the recent development of the Linux/ppc64 kernel, and more | 118 | During the development of the Linux/ppc64 kernel, and more |
| 127 | specifically, the addition of new platform types outside of the old | 119 | specifically, the addition of new platform types outside of the old |
| 128 | IBM pSeries/iSeries pair, it was decided to enforce some strict rules | 120 | IBM pSeries/iSeries pair, it was decided to enforce some strict rules |
| 129 | regarding the kernel entry and bootloader <-> kernel interfaces, in | 121 | regarding the kernel entry and bootloader <-> kernel interfaces, in |
| @@ -146,7 +138,7 @@ section III, but, for example, the kernel does not require you to | |||
| 146 | create a node for every PCI device in the system. It is a requirement | 138 | create a node for every PCI device in the system. It is a requirement |
| 147 | to have a node for PCI host bridges in order to provide interrupt | 139 | to have a node for PCI host bridges in order to provide interrupt |
| 148 | routing informations and memory/IO ranges, among others. It is also | 140 | routing informations and memory/IO ranges, among others. It is also |
| 149 | recommended to define nodes for on chip devices and other busses that | 141 | recommended to define nodes for on chip devices and other buses that |
| 150 | don't specifically fit in an existing OF specification. This creates a | 142 | don't specifically fit in an existing OF specification. This creates a |
| 151 | great flexibility in the way the kernel can then probe those and match | 143 | great flexibility in the way the kernel can then probe those and match |
| 152 | drivers to device, without having to hard code all sorts of tables. It | 144 | drivers to device, without having to hard code all sorts of tables. It |
| @@ -158,7 +150,7 @@ it with special cases. | |||
| 158 | 1) Entry point for arch/powerpc | 150 | 1) Entry point for arch/powerpc |
| 159 | ------------------------------- | 151 | ------------------------------- |
| 160 | 152 | ||
| 161 | There is one and one single entry point to the kernel, at the start | 153 | There is one single entry point to the kernel, at the start |
| 162 | of the kernel image. That entry point supports two calling | 154 | of the kernel image. That entry point supports two calling |
| 163 | conventions: | 155 | conventions: |
| 164 | 156 | ||
| @@ -210,12 +202,6 @@ it with special cases. | |||
| 210 | with all CPUs. The way to do that with method b) will be | 202 | with all CPUs. The way to do that with method b) will be |
| 211 | described in a later revision of this document. | 203 | described in a later revision of this document. |
| 212 | 204 | ||
| 213 | |||
| 214 | 2) Board support | ||
| 215 | ---------------- | ||
| 216 | |||
| 217 | 64-bit kernels: | ||
| 218 | |||
| 219 | Board supports (platforms) are not exclusive config options. An | 205 | Board supports (platforms) are not exclusive config options. An |
| 220 | arbitrary set of board supports can be built in a single kernel | 206 | arbitrary set of board supports can be built in a single kernel |
| 221 | image. The kernel will "know" what set of functions to use for a | 207 | image. The kernel will "know" what set of functions to use for a |
| @@ -234,48 +220,11 @@ it with special cases. | |||
| 234 | containing the various callbacks that the generic code will | 220 | containing the various callbacks that the generic code will |
| 235 | use to get to your platform specific code | 221 | use to get to your platform specific code |
| 236 | 222 | ||
| 237 | c) Add a reference to your "ppc_md" structure in the | 223 | A kernel image may support multiple platforms, but only if the |
| 238 | "machines" table in arch/powerpc/kernel/setup_64.c if you are | ||
| 239 | a 64-bit platform. | ||
| 240 | |||
| 241 | d) request and get assigned a platform number (see PLATFORM_* | ||
| 242 | constants in arch/powerpc/include/asm/processor.h | ||
| 243 | |||
| 244 | 32-bit embedded kernels: | ||
| 245 | |||
| 246 | Currently, board support is essentially an exclusive config option. | ||
| 247 | The kernel is configured for a single platform. Part of the reason | ||
| 248 | for this is to keep kernels on embedded systems small and efficient; | ||
| 249 | part of this is due to the fact the code is already that way. In the | ||
| 250 | future, a kernel may support multiple platforms, but only if the | ||
| 251 | platforms feature the same core architecture. A single kernel build | 224 | platforms feature the same core architecture. A single kernel build |
| 252 | cannot support both configurations with Book E and configurations | 225 | cannot support both configurations with Book E and configurations |
| 253 | with classic Powerpc architectures. | 226 | with classic Powerpc architectures. |
| 254 | 227 | ||
| 255 | 32-bit embedded platforms that are moved into arch/powerpc using a | ||
| 256 | flattened device tree should adopt the merged tree practice of | ||
| 257 | setting ppc_md up dynamically, even though the kernel is currently | ||
| 258 | built with support for only a single platform at a time. This allows | ||
| 259 | unification of the setup code, and will make it easier to go to a | ||
| 260 | multiple-platform-support model in the future. | ||
| 261 | |||
| 262 | NOTE: I believe the above will be true once Ben's done with the merge | ||
| 263 | of the boot sequences.... someone speak up if this is wrong! | ||
| 264 | |||
| 265 | To add a 32-bit embedded platform support, follow the instructions | ||
| 266 | for 64-bit platforms above, with the exception that the Kconfig | ||
| 267 | option should be set up such that the kernel builds exclusively for | ||
| 268 | the platform selected. The processor type for the platform should | ||
| 269 | enable another config option to select the specific board | ||
| 270 | supported. | ||
| 271 | |||
| 272 | NOTE: If Ben doesn't merge the setup files, may need to change this to | ||
| 273 | point to setup_32.c | ||
| 274 | |||
| 275 | |||
| 276 | I will describe later the boot process and various callbacks that | ||
| 277 | your platform should implement. | ||
| 278 | |||
| 279 | 228 | ||
| 280 | II - The DT block format | 229 | II - The DT block format |
| 281 | ======================== | 230 | ======================== |
| @@ -300,8 +249,8 @@ the block to RAM before passing it to the kernel. | |||
| 300 | 1) Header | 249 | 1) Header |
| 301 | --------- | 250 | --------- |
| 302 | 251 | ||
| 303 | The kernel is entered with r3 pointing to an area of memory that is | 252 | The kernel is passed the physical address pointing to an area of memory |
| 304 | roughly described in arch/powerpc/include/asm/prom.h by the structure | 253 | that is roughly described in include/linux/of_fdt.h by the structure |
| 305 | boot_param_header: | 254 | boot_param_header: |
| 306 | 255 | ||
| 307 | struct boot_param_header { | 256 | struct boot_param_header { |
| @@ -339,7 +288,7 @@ struct boot_param_header { | |||
| 339 | All values in this header are in big endian format, the various | 288 | All values in this header are in big endian format, the various |
| 340 | fields in this header are defined more precisely below. All | 289 | fields in this header are defined more precisely below. All |
| 341 | "offset" values are in bytes from the start of the header; that is | 290 | "offset" values are in bytes from the start of the header; that is |
| 342 | from the value of r3. | 291 | from the physical base address of the device tree block. |
| 343 | 292 | ||
| 344 | - magic | 293 | - magic |
| 345 | 294 | ||
| @@ -437,7 +386,7 @@ struct boot_param_header { | |||
| 437 | 386 | ||
| 438 | 387 | ||
| 439 | ------------------------------ | 388 | ------------------------------ |
| 440 | r3 -> | struct boot_param_header | | 389 | base -> | struct boot_param_header | |
| 441 | ------------------------------ | 390 | ------------------------------ |
| 442 | | (alignment gap) (*) | | 391 | | (alignment gap) (*) | |
| 443 | ------------------------------ | 392 | ------------------------------ |
| @@ -457,7 +406,7 @@ struct boot_param_header { | |||
| 457 | -----> ------------------------------ | 406 | -----> ------------------------------ |
| 458 | | | 407 | | |
| 459 | | | 408 | | |
| 460 | --- (r3 + totalsize) | 409 | --- (base + totalsize) |
| 461 | 410 | ||
| 462 | (*) The alignment gaps are not necessarily present; their presence | 411 | (*) The alignment gaps are not necessarily present; their presence |
| 463 | and size are dependent on the various alignment requirements of | 412 | and size are dependent on the various alignment requirements of |
| @@ -500,7 +449,7 @@ the device-tree structure. It is typically used to represent "path" in | |||
| 500 | the device-tree. More details about the actual format of these will be | 449 | the device-tree. More details about the actual format of these will be |
| 501 | below. | 450 | below. |
| 502 | 451 | ||
| 503 | The kernel powerpc generic code does not make any formal use of the | 452 | The kernel generic code does not make any formal use of the |
| 504 | unit address (though some board support code may do) so the only real | 453 | unit address (though some board support code may do) so the only real |
| 505 | requirement here for the unit address is to ensure uniqueness of | 454 | requirement here for the unit address is to ensure uniqueness of |
| 506 | the node unit name at a given level of the tree. Nodes with no notion | 455 | the node unit name at a given level of the tree. Nodes with no notion |
| @@ -518,20 +467,21 @@ path to the root node is "/". | |||
| 518 | 467 | ||
| 519 | Every node which actually represents an actual device (that is, a node | 468 | Every node which actually represents an actual device (that is, a node |
| 520 | which isn't only a virtual "container" for more nodes, like "/cpus" | 469 | which isn't only a virtual "container" for more nodes, like "/cpus" |
| 521 | is) is also required to have a "device_type" property indicating the | 470 | is) is also required to have a "compatible" property indicating the |
| 522 | type of node . | 471 | specific hardware and an optional list of devices it is fully |
| 472 | backwards compatible with. | ||
| 523 | 473 | ||
| 524 | Finally, every node that can be referenced from a property in another | 474 | Finally, every node that can be referenced from a property in another |
| 525 | node is required to have a "linux,phandle" property. Real open | 475 | node is required to have either a "phandle" or a "linux,phandle" |
| 526 | firmware implementations provide a unique "phandle" value for every | 476 | property. Real Open Firmware implementations provide a unique |
| 527 | node that the "prom_init()" trampoline code turns into | 477 | "phandle" value for every node that the "prom_init()" trampoline code |
| 528 | "linux,phandle" properties. However, this is made optional if the | 478 | turns into "linux,phandle" properties. However, this is made optional |
| 529 | flattened device tree is used directly. An example of a node | 479 | if the flattened device tree is used directly. An example of a node |
| 530 | referencing another node via "phandle" is when laying out the | 480 | referencing another node via "phandle" is when laying out the |
| 531 | interrupt tree which will be described in a further version of this | 481 | interrupt tree which will be described in a further version of this |
| 532 | document. | 482 | document. |
| 533 | 483 | ||
| 534 | This "linux, phandle" property is a 32-bit value that uniquely | 484 | The "phandle" property is a 32-bit value that uniquely |
| 535 | identifies a node. You are free to use whatever values or system of | 485 | identifies a node. You are free to use whatever values or system of |
| 536 | values, internal pointers, or whatever to generate these, the only | 486 | values, internal pointers, or whatever to generate these, the only |
| 537 | requirement is that every node for which you provide that property has | 487 | requirement is that every node for which you provide that property has |
| @@ -694,7 +644,7 @@ made of 3 cells, the bottom two containing the actual address itself | |||
| 694 | while the top cell contains address space indication, flags, and pci | 644 | while the top cell contains address space indication, flags, and pci |
| 695 | bus & device numbers. | 645 | bus & device numbers. |
| 696 | 646 | ||
| 697 | For busses that support dynamic allocation, it's the accepted practice | 647 | For buses that support dynamic allocation, it's the accepted practice |
| 698 | to then not provide the address in "reg" (keep it 0) though while | 648 | to then not provide the address in "reg" (keep it 0) though while |
| 699 | providing a flag indicating the address is dynamically allocated, and | 649 | providing a flag indicating the address is dynamically allocated, and |
| 700 | then, to provide a separate "assigned-addresses" property that | 650 | then, to provide a separate "assigned-addresses" property that |
| @@ -711,7 +661,7 @@ prom_parse.c file of the recent kernels for your bus type. | |||
| 711 | The "reg" property only defines addresses and sizes (if #size-cells is | 661 | The "reg" property only defines addresses and sizes (if #size-cells is |
| 712 | non-0) within a given bus. In order to translate addresses upward | 662 | non-0) within a given bus. In order to translate addresses upward |
| 713 | (that is into parent bus addresses, and possibly into CPU physical | 663 | (that is into parent bus addresses, and possibly into CPU physical |
| 714 | addresses), all busses must contain a "ranges" property. If the | 664 | addresses), all buses must contain a "ranges" property. If the |
| 715 | "ranges" property is missing at a given level, it's assumed that | 665 | "ranges" property is missing at a given level, it's assumed that |
| 716 | translation isn't possible, i.e., the registers are not visible on the | 666 | translation isn't possible, i.e., the registers are not visible on the |
| 717 | parent bus. The format of the "ranges" property for a bus is a list | 667 | parent bus. The format of the "ranges" property for a bus is a list |
| @@ -727,9 +677,9 @@ example, for a PCI host controller, that would be a CPU address. For a | |||
| 727 | PCI<->ISA bridge, that would be a PCI address. It defines the base | 677 | PCI<->ISA bridge, that would be a PCI address. It defines the base |
| 728 | address in the parent bus where the beginning of that range is mapped. | 678 | address in the parent bus where the beginning of that range is mapped. |
| 729 | 679 | ||
| 730 | For a new 64-bit powerpc board, I recommend either the 2/2 format or | 680 | For new 64-bit board support, I recommend either the 2/2 format or |
| 731 | Apple's 2/1 format which is slightly more compact since sizes usually | 681 | Apple's 2/1 format which is slightly more compact since sizes usually |
| 732 | fit in a single 32-bit word. New 32-bit powerpc boards should use a | 682 | fit in a single 32-bit word. New 32-bit board support should use a |
| 733 | 1/1 format, unless the processor supports physical addresses greater | 683 | 1/1 format, unless the processor supports physical addresses greater |
| 734 | than 32-bits, in which case a 2/1 format is recommended. | 684 | than 32-bits, in which case a 2/1 format is recommended. |
| 735 | 685 | ||
| @@ -754,7 +704,7 @@ of their actual names. | |||
| 754 | While earlier users of Open Firmware like OldWorld macintoshes tended | 704 | While earlier users of Open Firmware like OldWorld macintoshes tended |
| 755 | to use the actual device name for the "name" property, it's nowadays | 705 | to use the actual device name for the "name" property, it's nowadays |
| 756 | considered a good practice to use a name that is closer to the device | 706 | considered a good practice to use a name that is closer to the device |
| 757 | class (often equal to device_type). For example, nowadays, ethernet | 707 | class (often equal to device_type). For example, nowadays, Ethernet |
| 758 | controllers are named "ethernet", an additional "model" property | 708 | controllers are named "ethernet", an additional "model" property |
| 759 | defining precisely the chip type/model, and "compatible" property | 709 | defining precisely the chip type/model, and "compatible" property |
| 760 | defining the family in case a single driver can driver more than one | 710 | defining the family in case a single driver can driver more than one |
| @@ -772,7 +722,7 @@ is present). | |||
| 772 | 4) Note about node and property names and character set | 722 | 4) Note about node and property names and character set |
| 773 | ------------------------------------------------------- | 723 | ------------------------------------------------------- |
| 774 | 724 | ||
| 775 | While open firmware provides more flexible usage of 8859-1, this | 725 | While Open Firmware provides more flexible usage of 8859-1, this |
| 776 | specification enforces more strict rules. Nodes and properties should | 726 | specification enforces more strict rules. Nodes and properties should |
| 777 | be comprised only of ASCII characters 'a' to 'z', '0' to | 727 | be comprised only of ASCII characters 'a' to 'z', '0' to |
| 778 | '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally | 728 | '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally |
| @@ -792,7 +742,7 @@ address which can extend beyond that limit. | |||
| 792 | -------------------------------- | 742 | -------------------------------- |
| 793 | These are all that are currently required. However, it is strongly | 743 | These are all that are currently required. However, it is strongly |
| 794 | recommended that you expose PCI host bridges as documented in the | 744 | recommended that you expose PCI host bridges as documented in the |
| 795 | PCI binding to open firmware, and your interrupt tree as documented | 745 | PCI binding to Open Firmware, and your interrupt tree as documented |
| 796 | in OF interrupt tree specification. | 746 | in OF interrupt tree specification. |
| 797 | 747 | ||
| 798 | a) The root node | 748 | a) The root node |
| @@ -802,20 +752,12 @@ address which can extend beyond that limit. | |||
| 802 | - model : this is your board name/model | 752 | - model : this is your board name/model |
| 803 | - #address-cells : address representation for "root" devices | 753 | - #address-cells : address representation for "root" devices |
| 804 | - #size-cells: the size representation for "root" devices | 754 | - #size-cells: the size representation for "root" devices |
| 805 | - device_type : This property shouldn't be necessary. However, if | ||
| 806 | you decide to create a device_type for your root node, make sure it | ||
| 807 | is _not_ "chrp" unless your platform is a pSeries or PAPR compliant | ||
| 808 | one for 64-bit, or a CHRP-type machine for 32-bit as this will | ||
| 809 | matched by the kernel this way. | ||
| 810 | |||
| 811 | Additionally, some recommended properties are: | ||
| 812 | |||
| 813 | - compatible : the board "family" generally finds its way here, | 755 | - compatible : the board "family" generally finds its way here, |
| 814 | for example, if you have 2 board models with a similar layout, | 756 | for example, if you have 2 board models with a similar layout, |
| 815 | that typically get driven by the same platform code in the | 757 | that typically get driven by the same platform code in the |
| 816 | kernel, you would use a different "model" property but put a | 758 | kernel, you would specify the exact board model in the |
| 817 | value in "compatible". The kernel doesn't directly use that | 759 | compatible property followed by an entry that represents the SoC |
| 818 | value but it is generally useful. | 760 | model. |
| 819 | 761 | ||
| 820 | The root node is also generally where you add additional properties | 762 | The root node is also generally where you add additional properties |
| 821 | specific to your board like the serial number if any, that sort of | 763 | specific to your board like the serial number if any, that sort of |
| @@ -841,8 +783,11 @@ address which can extend beyond that limit. | |||
| 841 | 783 | ||
| 842 | So under /cpus, you are supposed to create a node for every CPU on | 784 | So under /cpus, you are supposed to create a node for every CPU on |
| 843 | the machine. There is no specific restriction on the name of the | 785 | the machine. There is no specific restriction on the name of the |
| 844 | CPU, though It's common practice to call it PowerPC,<name>. For | 786 | CPU, though it's common to call it <architecture>,<core>. For |
| 845 | example, Apple uses PowerPC,G5 while IBM uses PowerPC,970FX. | 787 | example, Apple uses PowerPC,G5 while IBM uses PowerPC,970FX. |
| 788 | However, the Generic Names convention suggests that it would be | ||
| 789 | better to simply use 'cpu' for each cpu node and use the compatible | ||
| 790 | property to identify the specific cpu core. | ||
| 846 | 791 | ||
| 847 | Required properties: | 792 | Required properties: |
| 848 | 793 | ||
| @@ -923,7 +868,7 @@ compatibility. | |||
| 923 | 868 | ||
| 924 | e) The /chosen node | 869 | e) The /chosen node |
| 925 | 870 | ||
| 926 | This node is a bit "special". Normally, that's where open firmware | 871 | This node is a bit "special". Normally, that's where Open Firmware |
| 927 | puts some variable environment information, like the arguments, or | 872 | puts some variable environment information, like the arguments, or |
| 928 | the default input/output devices. | 873 | the default input/output devices. |
| 929 | 874 | ||
| @@ -940,11 +885,7 @@ compatibility. | |||
| 940 | console device if any. Typically, if you have serial devices on | 885 | console device if any. Typically, if you have serial devices on |
| 941 | your board, you may want to put the full path to the one set as | 886 | your board, you may want to put the full path to the one set as |
| 942 | the default console in the firmware here, for the kernel to pick | 887 | the default console in the firmware here, for the kernel to pick |
| 943 | it up as its own default console. If you look at the function | 888 | it up as its own default console. |
| 944 | set_preferred_console() in arch/ppc64/kernel/setup.c, you'll see | ||
| 945 | that the kernel tries to find out the default console and has | ||
| 946 | knowledge of various types like 8250 serial ports. You may want | ||
| 947 | to extend this function to add your own. | ||
| 948 | 889 | ||
| 949 | Note that u-boot creates and fills in the chosen node for platforms | 890 | Note that u-boot creates and fills in the chosen node for platforms |
| 950 | that use it. | 891 | that use it. |
| @@ -955,23 +896,23 @@ compatibility. | |||
| 955 | 896 | ||
| 956 | f) the /soc<SOCname> node | 897 | f) the /soc<SOCname> node |
| 957 | 898 | ||
| 958 | This node is used to represent a system-on-a-chip (SOC) and must be | 899 | This node is used to represent a system-on-a-chip (SoC) and must be |
| 959 | present if the processor is a SOC. The top-level soc node contains | 900 | present if the processor is a SoC. The top-level soc node contains |
| 960 | information that is global to all devices on the SOC. The node name | 901 | information that is global to all devices on the SoC. The node name |
| 961 | should contain a unit address for the SOC, which is the base address | 902 | should contain a unit address for the SoC, which is the base address |
| 962 | of the memory-mapped register set for the SOC. The name of an soc | 903 | of the memory-mapped register set for the SoC. The name of an SoC |
| 963 | node should start with "soc", and the remainder of the name should | 904 | node should start with "soc", and the remainder of the name should |
| 964 | represent the part number for the soc. For example, the MPC8540's | 905 | represent the part number for the soc. For example, the MPC8540's |
| 965 | soc node would be called "soc8540". | 906 | soc node would be called "soc8540". |
| 966 | 907 | ||
| 967 | Required properties: | 908 | Required properties: |
| 968 | 909 | ||
| 969 | - device_type : Should be "soc" | ||
| 970 | - ranges : Should be defined as specified in 1) to describe the | 910 | - ranges : Should be defined as specified in 1) to describe the |
| 971 | translation of SOC addresses for memory mapped SOC registers. | 911 | translation of SoC addresses for memory mapped SoC registers. |
| 972 | - bus-frequency: Contains the bus frequency for the SOC node. | 912 | - bus-frequency: Contains the bus frequency for the SoC node. |
| 973 | Typically, the value of this field is filled in by the boot | 913 | Typically, the value of this field is filled in by the boot |
| 974 | loader. | 914 | loader. |
| 915 | - compatible : Exact model of the SoC | ||
| 975 | 916 | ||
| 976 | 917 | ||
| 977 | Recommended properties: | 918 | Recommended properties: |
| @@ -1155,12 +1096,13 @@ while all this has been defined and implemented. | |||
| 1155 | 1096 | ||
| 1156 | - An example of code for iterating nodes & retrieving properties | 1097 | - An example of code for iterating nodes & retrieving properties |
| 1157 | directly from the flattened tree format can be found in the kernel | 1098 | directly from the flattened tree format can be found in the kernel |
| 1158 | file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function, | 1099 | file drivers/of/fdt.c. Look at the of_scan_flat_dt() function, |
| 1159 | its usage in early_init_devtree(), and the corresponding various | 1100 | its usage in early_init_devtree(), and the corresponding various |
| 1160 | early_init_dt_scan_*() callbacks. That code can be re-used in a | 1101 | early_init_dt_scan_*() callbacks. That code can be re-used in a |
| 1161 | GPL bootloader, and as the author of that code, I would be happy | 1102 | GPL bootloader, and as the author of that code, I would be happy |
| 1162 | to discuss possible free licensing to any vendor who wishes to | 1103 | to discuss possible free licensing to any vendor who wishes to |
| 1163 | integrate all or part of this code into a non-GPL bootloader. | 1104 | integrate all or part of this code into a non-GPL bootloader. |
| 1105 | (reference needed; who is 'I' here? ---gcl Jan 31, 2011) | ||
| 1164 | 1106 | ||
| 1165 | 1107 | ||
| 1166 | 1108 | ||
| @@ -1203,18 +1145,19 @@ MPC8540. | |||
| 1203 | 2) Representing devices without a current OF specification | 1145 | 2) Representing devices without a current OF specification |
| 1204 | ---------------------------------------------------------- | 1146 | ---------------------------------------------------------- |
| 1205 | 1147 | ||
| 1206 | Currently, there are many devices on SOCs that do not have a standard | 1148 | Currently, there are many devices on SoCs that do not have a standard |
| 1207 | representation pre-defined as part of the open firmware | 1149 | representation defined as part of the Open Firmware specifications, |
| 1208 | specifications, mainly because the boards that contain these SOCs are | 1150 | mainly because the boards that contain these SoCs are not currently |
| 1209 | not currently booted using open firmware. This section contains | 1151 | booted using Open Firmware. Binding documentation for new devices |
| 1210 | descriptions for the SOC devices for which new nodes have been | 1152 | should be added to the Documentation/devicetree/bindings directory. |
| 1211 | defined; this list will expand as more and more SOC-containing | 1153 | That directory will expand as device tree support is added to more and |
| 1212 | platforms are moved over to use the flattened-device-tree model. | 1154 | more SoCs. |
| 1155 | |||
| 1213 | 1156 | ||
| 1214 | VII - Specifying interrupt information for devices | 1157 | VII - Specifying interrupt information for devices |
| 1215 | =================================================== | 1158 | =================================================== |
| 1216 | 1159 | ||
| 1217 | The device tree represents the busses and devices of a hardware | 1160 | The device tree represents the buses and devices of a hardware |
| 1218 | system in a form similar to the physical bus topology of the | 1161 | system in a form similar to the physical bus topology of the |
| 1219 | hardware. | 1162 | hardware. |
| 1220 | 1163 | ||
diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile index 5aba7a33aee..24c308dd3fd 100644 --- a/Documentation/networking/Makefile +++ b/Documentation/networking/Makefile | |||
| @@ -4,6 +4,8 @@ obj- := dummy.o | |||
| 4 | # List of programs to build | 4 | # List of programs to build |
| 5 | hostprogs-y := ifenslave | 5 | hostprogs-y := ifenslave |
| 6 | 6 | ||
| 7 | HOSTCFLAGS_ifenslave.o += -I$(objtree)/usr/include | ||
| 8 | |||
| 7 | # Tell kbuild to always build the programs | 9 | # Tell kbuild to always build the programs |
| 8 | always := $(hostprogs-y) | 10 | always := $(hostprogs-y) |
| 9 | 11 | ||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index d99940dcfc4..ac3b4a726a1 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -187,7 +187,7 @@ tcp_cookie_size - INTEGER | |||
| 187 | tcp_dsack - BOOLEAN | 187 | tcp_dsack - BOOLEAN |
| 188 | Allows TCP to send "duplicate" SACKs. | 188 | Allows TCP to send "duplicate" SACKs. |
| 189 | 189 | ||
| 190 | tcp_ecn - BOOLEAN | 190 | tcp_ecn - INTEGER |
| 191 | Enable Explicit Congestion Notification (ECN) in TCP. ECN is only | 191 | Enable Explicit Congestion Notification (ECN) in TCP. ECN is only |
| 192 | used when both ends of the TCP flow support it. It is useful to | 192 | used when both ends of the TCP flow support it. It is useful to |
| 193 | avoid losses due to congestion (when the bottleneck router supports | 193 | avoid losses due to congestion (when the bottleneck router supports |
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 16ae4300c74..0caf77e59be 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
| @@ -296,6 +296,7 @@ Conexant 5066 | |||
| 296 | ============= | 296 | ============= |
| 297 | laptop Basic Laptop config (default) | 297 | laptop Basic Laptop config (default) |
| 298 | hp-laptop HP laptops, e g G60 | 298 | hp-laptop HP laptops, e g G60 |
| 299 | asus Asus K52JU, Lenovo G560 | ||
| 299 | dell-laptop Dell laptops | 300 | dell-laptop Dell laptops |
| 300 | dell-vostro Dell Vostro | 301 | dell-vostro Dell Vostro |
| 301 | olpc-xo-1_5 OLPC XO 1.5 | 302 | olpc-xo-1_5 OLPC XO 1.5 |
diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt index 996a27d9b8d..01c513fac40 100644 --- a/Documentation/workqueue.txt +++ b/Documentation/workqueue.txt | |||
| @@ -190,9 +190,9 @@ resources, scheduled and executed. | |||
| 190 | * Long running CPU intensive workloads which can be better | 190 | * Long running CPU intensive workloads which can be better |
| 191 | managed by the system scheduler. | 191 | managed by the system scheduler. |
| 192 | 192 | ||
| 193 | WQ_FREEZEABLE | 193 | WQ_FREEZABLE |
| 194 | 194 | ||
| 195 | A freezeable wq participates in the freeze phase of the system | 195 | A freezable wq participates in the freeze phase of the system |
| 196 | suspend operations. Work items on the wq are drained and no | 196 | suspend operations. Work items on the wq are drained and no |
| 197 | new work item starts execution until thawed. | 197 | new work item starts execution until thawed. |
| 198 | 198 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 9511bff301c..5dd6c751e6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2126,6 +2126,7 @@ S: Supported | |||
| 2126 | F: fs/dlm/ | 2126 | F: fs/dlm/ |
| 2127 | 2127 | ||
| 2128 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | 2128 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM |
| 2129 | M: Vinod Koul <vinod.koul@intel.com> | ||
| 2129 | M: Dan Williams <dan.j.williams@intel.com> | 2130 | M: Dan Williams <dan.j.williams@intel.com> |
| 2130 | S: Supported | 2131 | S: Supported |
| 2131 | F: drivers/dma/ | 2132 | F: drivers/dma/ |
| @@ -2774,6 +2775,15 @@ F: Documentation/isdn/README.gigaset | |||
| 2774 | F: drivers/isdn/gigaset/ | 2775 | F: drivers/isdn/gigaset/ |
| 2775 | F: include/linux/gigaset_dev.h | 2776 | F: include/linux/gigaset_dev.h |
| 2776 | 2777 | ||
| 2778 | GPIO SUBSYSTEM | ||
| 2779 | M: Grant Likely <grant.likely@secretlab.ca> | ||
| 2780 | L: linux-kernel@vger.kernel.org | ||
| 2781 | S: Maintained | ||
| 2782 | T: git git://git.secretlab.ca/git/linux-2.6.git | ||
| 2783 | F: Documentation/gpio/gpio.txt | ||
| 2784 | F: drivers/gpio/ | ||
| 2785 | F: include/linux/gpio* | ||
| 2786 | |||
| 2777 | GRETH 10/100/1G Ethernet MAC device driver | 2787 | GRETH 10/100/1G Ethernet MAC device driver |
| 2778 | M: Kristoffer Glembo <kristoffer@gaisler.com> | 2788 | M: Kristoffer Glembo <kristoffer@gaisler.com> |
| 2779 | L: netdev@vger.kernel.org | 2789 | L: netdev@vger.kernel.org |
| @@ -4591,7 +4601,7 @@ F: drivers/i2c/busses/i2c-ocores.c | |||
| 4591 | 4601 | ||
| 4592 | OPEN FIRMWARE AND FLATTENED DEVICE TREE | 4602 | OPEN FIRMWARE AND FLATTENED DEVICE TREE |
| 4593 | M: Grant Likely <grant.likely@secretlab.ca> | 4603 | M: Grant Likely <grant.likely@secretlab.ca> |
| 4594 | L: devicetree-discuss@lists.ozlabs.org | 4604 | L: devicetree-discuss@lists.ozlabs.org (moderated for non-subscribers) |
| 4595 | W: http://fdt.secretlab.ca | 4605 | W: http://fdt.secretlab.ca |
| 4596 | T: git git://git.secretlab.ca/git/linux-2.6.git | 4606 | T: git git://git.secretlab.ca/git/linux-2.6.git |
| 4597 | S: Maintained | 4607 | S: Maintained |
| @@ -5551,12 +5561,11 @@ S: Supported | |||
| 5551 | F: drivers/scsi/be2iscsi/ | 5561 | F: drivers/scsi/be2iscsi/ |
| 5552 | 5562 | ||
| 5553 | SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER | 5563 | SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER |
| 5554 | M: Sathya Perla <sathyap@serverengines.com> | 5564 | M: Sathya Perla <sathya.perla@emulex.com> |
| 5555 | M: Subbu Seetharaman <subbus@serverengines.com> | 5565 | M: Subbu Seetharaman <subbu.seetharaman@emulex.com> |
| 5556 | M: Sarveshwar Bandi <sarveshwarb@serverengines.com> | 5566 | M: Ajit Khaparde <ajit.khaparde@emulex.com> |
| 5557 | M: Ajit Khaparde <ajitk@serverengines.com> | ||
| 5558 | L: netdev@vger.kernel.org | 5567 | L: netdev@vger.kernel.org |
| 5559 | W: http://www.serverengines.com | 5568 | W: http://www.emulex.com |
| 5560 | S: Supported | 5569 | S: Supported |
| 5561 | F: drivers/net/benet/ | 5570 | F: drivers/net/benet/ |
| 5562 | 5571 | ||
| @@ -6787,12 +6796,12 @@ S: Maintained | |||
| 6787 | F: drivers/net/wireless/wl1251/* | 6796 | F: drivers/net/wireless/wl1251/* |
| 6788 | 6797 | ||
| 6789 | WL1271 WIRELESS DRIVER | 6798 | WL1271 WIRELESS DRIVER |
| 6790 | M: Luciano Coelho <luciano.coelho@nokia.com> | 6799 | M: Luciano Coelho <coelho@ti.com> |
| 6791 | L: linux-wireless@vger.kernel.org | 6800 | L: linux-wireless@vger.kernel.org |
| 6792 | W: http://wireless.kernel.org | 6801 | W: http://wireless.kernel.org/en/users/Drivers/wl12xx |
| 6793 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git | 6802 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git |
| 6794 | S: Maintained | 6803 | S: Maintained |
| 6795 | F: drivers/net/wireless/wl12xx/wl1271* | 6804 | F: drivers/net/wireless/wl12xx/ |
| 6796 | F: include/linux/wl12xx.h | 6805 | F: include/linux/wl12xx.h |
| 6797 | 6806 | ||
| 6798 | WL3501 WIRELESS PCMCIA CARD DRIVER | 6807 | WL3501 WIRELESS PCMCIA CARD DRIVER |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 2 | 1 | VERSION = 2 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 38 | 3 | SUBLEVEL = 38 |
| 4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc5 |
| 5 | NAME = Flesh-Eating Bats with Fangs | 5 | NAME = Flesh-Eating Bats with Fangs |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5cff165b7eb..26d45e5b636 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -1391,7 +1391,7 @@ config AEABI | |||
| 1391 | 1391 | ||
| 1392 | config OABI_COMPAT | 1392 | config OABI_COMPAT |
| 1393 | bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" | 1393 | bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" |
| 1394 | depends on AEABI && EXPERIMENTAL | 1394 | depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL |
| 1395 | default y | 1395 | default y |
| 1396 | help | 1396 | help |
| 1397 | This option preserves the old syscall interface along with the | 1397 | This option preserves the old syscall interface along with the |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index c0225da3fb2..f06ff9feb0d 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -391,6 +391,7 @@ ENDPROC(__turn_mmu_on) | |||
| 391 | 391 | ||
| 392 | 392 | ||
| 393 | #ifdef CONFIG_SMP_ON_UP | 393 | #ifdef CONFIG_SMP_ON_UP |
| 394 | __INIT | ||
| 394 | __fixup_smp: | 395 | __fixup_smp: |
| 395 | and r3, r9, #0x000f0000 @ architecture version | 396 | and r3, r9, #0x000f0000 @ architecture version |
| 396 | teq r3, #0x000f0000 @ CPU ID supported? | 397 | teq r3, #0x000f0000 @ CPU ID supported? |
| @@ -415,18 +416,7 @@ __fixup_smp_on_up: | |||
| 415 | sub r3, r0, r3 | 416 | sub r3, r0, r3 |
| 416 | add r4, r4, r3 | 417 | add r4, r4, r3 |
| 417 | add r5, r5, r3 | 418 | add r5, r5, r3 |
| 418 | 2: cmp r4, r5 | 419 | b __do_fixup_smp_on_up |
| 419 | movhs pc, lr | ||
| 420 | ldmia r4!, {r0, r6} | ||
| 421 | ARM( str r6, [r0, r3] ) | ||
| 422 | THUMB( add r0, r0, r3 ) | ||
| 423 | #ifdef __ARMEB__ | ||
| 424 | THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. | ||
| 425 | #endif | ||
| 426 | THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords | ||
| 427 | THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. | ||
| 428 | THUMB( strh r6, [r0] ) | ||
| 429 | b 2b | ||
| 430 | ENDPROC(__fixup_smp) | 420 | ENDPROC(__fixup_smp) |
| 431 | 421 | ||
| 432 | .align | 422 | .align |
| @@ -440,7 +430,31 @@ smp_on_up: | |||
| 440 | ALT_SMP(.long 1) | 430 | ALT_SMP(.long 1) |
| 441 | ALT_UP(.long 0) | 431 | ALT_UP(.long 0) |
| 442 | .popsection | 432 | .popsection |
| 433 | #endif | ||
| 443 | 434 | ||
| 435 | .text | ||
| 436 | __do_fixup_smp_on_up: | ||
| 437 | cmp r4, r5 | ||
| 438 | movhs pc, lr | ||
| 439 | ldmia r4!, {r0, r6} | ||
| 440 | ARM( str r6, [r0, r3] ) | ||
| 441 | THUMB( add r0, r0, r3 ) | ||
| 442 | #ifdef __ARMEB__ | ||
| 443 | THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. | ||
| 444 | #endif | 444 | #endif |
| 445 | THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords | ||
| 446 | THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. | ||
| 447 | THUMB( strh r6, [r0] ) | ||
| 448 | b __do_fixup_smp_on_up | ||
| 449 | ENDPROC(__do_fixup_smp_on_up) | ||
| 450 | |||
| 451 | ENTRY(fixup_smp) | ||
| 452 | stmfd sp!, {r4 - r6, lr} | ||
| 453 | mov r4, r0 | ||
| 454 | add r5, r0, r1 | ||
| 455 | mov r3, #0 | ||
| 456 | bl __do_fixup_smp_on_up | ||
| 457 | ldmfd sp!, {r4 - r6, pc} | ||
| 458 | ENDPROC(fixup_smp) | ||
| 445 | 459 | ||
| 446 | #include "head-common.S" | 460 | #include "head-common.S" |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index c9f3f046757..d600bd35070 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
| @@ -137,11 +137,10 @@ static u8 get_debug_arch(void) | |||
| 137 | u32 didr; | 137 | u32 didr; |
| 138 | 138 | ||
| 139 | /* Do we implement the extended CPUID interface? */ | 139 | /* Do we implement the extended CPUID interface? */ |
| 140 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | 140 | if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), |
| 141 | pr_warning("CPUID feature registers not supported. " | 141 | "CPUID feature registers not supported. " |
| 142 | "Assuming v6 debug is present.\n"); | 142 | "Assuming v6 debug is present.\n")) |
| 143 | return ARM_DEBUG_ARCH_V6; | 143 | return ARM_DEBUG_ARCH_V6; |
| 144 | } | ||
| 145 | 144 | ||
| 146 | ARM_DBG_READ(c0, 0, didr); | 145 | ARM_DBG_READ(c0, 0, didr); |
| 147 | return (didr >> 16) & 0xf; | 146 | return (didr >> 16) & 0xf; |
| @@ -152,6 +151,12 @@ u8 arch_get_debug_arch(void) | |||
| 152 | return debug_arch; | 151 | return debug_arch; |
| 153 | } | 152 | } |
| 154 | 153 | ||
| 154 | static int debug_arch_supported(void) | ||
| 155 | { | ||
| 156 | u8 arch = get_debug_arch(); | ||
| 157 | return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; | ||
| 158 | } | ||
| 159 | |||
| 155 | /* Determine number of BRP register available. */ | 160 | /* Determine number of BRP register available. */ |
| 156 | static int get_num_brp_resources(void) | 161 | static int get_num_brp_resources(void) |
| 157 | { | 162 | { |
| @@ -268,6 +273,9 @@ out: | |||
| 268 | 273 | ||
| 269 | int hw_breakpoint_slots(int type) | 274 | int hw_breakpoint_slots(int type) |
| 270 | { | 275 | { |
| 276 | if (!debug_arch_supported()) | ||
| 277 | return 0; | ||
| 278 | |||
| 271 | /* | 279 | /* |
| 272 | * We can be called early, so don't rely on | 280 | * We can be called early, so don't rely on |
| 273 | * our static variables being initialised. | 281 | * our static variables being initialised. |
| @@ -834,11 +842,11 @@ static void reset_ctrl_regs(void *unused) | |||
| 834 | 842 | ||
| 835 | /* | 843 | /* |
| 836 | * v7 debug contains save and restore registers so that debug state | 844 | * v7 debug contains save and restore registers so that debug state |
| 837 | * can be maintained across low-power modes without leaving | 845 | * can be maintained across low-power modes without leaving the debug |
| 838 | * the debug logic powered up. It is IMPLEMENTATION DEFINED whether | 846 | * logic powered up. It is IMPLEMENTATION DEFINED whether we can access |
| 839 | * we can write to the debug registers out of reset, so we must | 847 | * the debug registers out of reset, so we must unlock the OS Lock |
| 840 | * unlock the OS Lock Access Register to avoid taking undefined | 848 | * Access Register to avoid taking undefined instruction exceptions |
| 841 | * instruction exceptions later on. | 849 | * later on. |
| 842 | */ | 850 | */ |
| 843 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | 851 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { |
| 844 | /* | 852 | /* |
| @@ -882,7 +890,7 @@ static int __init arch_hw_breakpoint_init(void) | |||
| 882 | 890 | ||
| 883 | debug_arch = get_debug_arch(); | 891 | debug_arch = get_debug_arch(); |
| 884 | 892 | ||
| 885 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | 893 | if (!debug_arch_supported()) { |
| 886 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | 894 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); |
| 887 | return 0; | 895 | return 0; |
| 888 | } | 896 | } |
| @@ -899,18 +907,18 @@ static int __init arch_hw_breakpoint_init(void) | |||
| 899 | pr_info("%d breakpoint(s) reserved for watchpoint " | 907 | pr_info("%d breakpoint(s) reserved for watchpoint " |
| 900 | "single-step.\n", core_num_reserved_brps); | 908 | "single-step.\n", core_num_reserved_brps); |
| 901 | 909 | ||
| 910 | /* | ||
| 911 | * Reset the breakpoint resources. We assume that a halting | ||
| 912 | * debugger will leave the world in a nice state for us. | ||
| 913 | */ | ||
| 914 | on_each_cpu(reset_ctrl_regs, NULL, 1); | ||
| 915 | |||
| 902 | ARM_DBG_READ(c1, 0, dscr); | 916 | ARM_DBG_READ(c1, 0, dscr); |
| 903 | if (dscr & ARM_DSCR_HDBGEN) { | 917 | if (dscr & ARM_DSCR_HDBGEN) { |
| 918 | max_watchpoint_len = 4; | ||
| 904 | pr_warning("halting debug mode enabled. Assuming maximum " | 919 | pr_warning("halting debug mode enabled. Assuming maximum " |
| 905 | "watchpoint size of 4 bytes."); | 920 | "watchpoint size of %u bytes.", max_watchpoint_len); |
| 906 | } else { | 921 | } else { |
| 907 | /* | ||
| 908 | * Reset the breakpoint resources. We assume that a halting | ||
| 909 | * debugger will leave the world in a nice state for us. | ||
| 910 | */ | ||
| 911 | smp_call_function(reset_ctrl_regs, NULL, 1); | ||
| 912 | reset_ctrl_regs(NULL); | ||
| 913 | |||
| 914 | /* Work out the maximum supported watchpoint length. */ | 922 | /* Work out the maximum supported watchpoint length. */ |
| 915 | max_watchpoint_len = get_max_wp_len(); | 923 | max_watchpoint_len = get_max_wp_len(); |
| 916 | pr_info("maximum watchpoint size is %u bytes.\n", | 924 | pr_info("maximum watchpoint size is %u bytes.\n", |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 2cfe8161b47..6d4105e6872 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
| 24 | #include <asm/sections.h> | 24 | #include <asm/sections.h> |
| 25 | #include <asm/smp_plat.h> | ||
| 25 | #include <asm/unwind.h> | 26 | #include <asm/unwind.h> |
| 26 | 27 | ||
| 27 | #ifdef CONFIG_XIP_KERNEL | 28 | #ifdef CONFIG_XIP_KERNEL |
| @@ -268,12 +269,28 @@ struct mod_unwind_map { | |||
| 268 | const Elf_Shdr *txt_sec; | 269 | const Elf_Shdr *txt_sec; |
| 269 | }; | 270 | }; |
| 270 | 271 | ||
| 272 | static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr, | ||
| 273 | const Elf_Shdr *sechdrs, const char *name) | ||
| 274 | { | ||
| 275 | const Elf_Shdr *s, *se; | ||
| 276 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 277 | |||
| 278 | for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) | ||
| 279 | if (strcmp(name, secstrs + s->sh_name) == 0) | ||
| 280 | return s; | ||
| 281 | |||
| 282 | return NULL; | ||
| 283 | } | ||
| 284 | |||
| 285 | extern void fixup_smp(const void *, unsigned long); | ||
| 286 | |||
| 271 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | 287 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, |
| 272 | struct module *mod) | 288 | struct module *mod) |
| 273 | { | 289 | { |
| 290 | const Elf_Shdr * __maybe_unused s = NULL; | ||
| 274 | #ifdef CONFIG_ARM_UNWIND | 291 | #ifdef CONFIG_ARM_UNWIND |
| 275 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 292 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
| 276 | const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | 293 | const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; |
| 277 | struct mod_unwind_map maps[ARM_SEC_MAX]; | 294 | struct mod_unwind_map maps[ARM_SEC_MAX]; |
| 278 | int i; | 295 | int i; |
| 279 | 296 | ||
| @@ -315,6 +332,9 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
| 315 | maps[i].txt_sec->sh_addr, | 332 | maps[i].txt_sec->sh_addr, |
| 316 | maps[i].txt_sec->sh_size); | 333 | maps[i].txt_sec->sh_size); |
| 317 | #endif | 334 | #endif |
| 335 | s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); | ||
| 336 | if (s && !is_smp()) | ||
| 337 | fixup_smp((void *)s->sh_addr, s->sh_size); | ||
| 318 | return 0; | 338 | return 0; |
| 319 | } | 339 | } |
| 320 | 340 | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 5efa2647a2f..d150ad1ccb5 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
| @@ -700,7 +700,7 @@ user_backtrace(struct frame_tail __user *tail, | |||
| 700 | * Frame pointers should strictly progress back up the stack | 700 | * Frame pointers should strictly progress back up the stack |
| 701 | * (towards higher addresses). | 701 | * (towards higher addresses). |
| 702 | */ | 702 | */ |
| 703 | if (tail >= buftail.fp) | 703 | if (tail + 1 >= buftail.fp) |
| 704 | return NULL; | 704 | return NULL; |
| 705 | 705 | ||
| 706 | return buftail.fp - 1; | 706 | return buftail.fp - 1; |
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index ffdf87be295..82079545adc 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
| @@ -838,7 +838,7 @@ EXPORT_SYMBOL(ep93xx_i2s_release); | |||
| 838 | static struct resource ep93xx_ac97_resources[] = { | 838 | static struct resource ep93xx_ac97_resources[] = { |
| 839 | { | 839 | { |
| 840 | .start = EP93XX_AAC_PHYS_BASE, | 840 | .start = EP93XX_AAC_PHYS_BASE, |
| 841 | .end = EP93XX_AAC_PHYS_BASE + 0xb0 - 1, | 841 | .end = EP93XX_AAC_PHYS_BASE + 0xac - 1, |
| 842 | .flags = IORESOURCE_MEM, | 842 | .flags = IORESOURCE_MEM, |
| 843 | }, | 843 | }, |
| 844 | { | 844 | { |
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c index aa76cfd9f34..8382e790207 100644 --- a/arch/arm/mach-imx/mach-mx25_3ds.c +++ b/arch/arm/mach-imx/mach-mx25_3ds.c | |||
| @@ -180,7 +180,7 @@ static const uint32_t mx25pdk_keymap[] = { | |||
| 180 | KEY(3, 3, KEY_POWER), | 180 | KEY(3, 3, KEY_POWER), |
| 181 | }; | 181 | }; |
| 182 | 182 | ||
| 183 | static const struct matrix_keymap_data mx25pdk_keymap_data __initdata = { | 183 | static const struct matrix_keymap_data mx25pdk_keymap_data __initconst = { |
| 184 | .keymap = mx25pdk_keymap, | 184 | .keymap = mx25pdk_keymap, |
| 185 | .keymap_size = ARRAY_SIZE(mx25pdk_keymap), | 185 | .keymap_size = ARRAY_SIZE(mx25pdk_keymap), |
| 186 | }; | 186 | }; |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 4dc68d6bb6b..9fd894271d5 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
| @@ -432,7 +432,7 @@ static struct clocksource clocksource_ixp4xx = { | |||
| 432 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 432 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
| 433 | }; | 433 | }; |
| 434 | 434 | ||
| 435 | unsigned long ixp4xx_timer_freq = FREQ; | 435 | unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; |
| 436 | EXPORT_SYMBOL(ixp4xx_timer_freq); | 436 | EXPORT_SYMBOL(ixp4xx_timer_freq); |
| 437 | static void __init ixp4xx_clocksource_init(void) | 437 | static void __init ixp4xx_clocksource_init(void) |
| 438 | { | 438 | { |
| @@ -496,7 +496,7 @@ static struct clock_event_device clockevent_ixp4xx = { | |||
| 496 | 496 | ||
| 497 | static void __init ixp4xx_clockevent_init(void) | 497 | static void __init ixp4xx_clockevent_init(void) |
| 498 | { | 498 | { |
| 499 | clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC, | 499 | clockevent_ixp4xx.mult = div_sc(IXP4XX_TIMER_FREQ, NSEC_PER_SEC, |
| 500 | clockevent_ixp4xx.shift); | 500 | clockevent_ixp4xx.shift); |
| 501 | clockevent_ixp4xx.max_delta_ns = | 501 | clockevent_ixp4xx.max_delta_ns = |
| 502 | clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx); | 502 | clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx); |
diff --git a/arch/arm/mach-ixp4xx/include/mach/timex.h b/arch/arm/mach-ixp4xx/include/mach/timex.h index 2c3f93c3eb7..c9e930f2933 100644 --- a/arch/arm/mach-ixp4xx/include/mach/timex.h +++ b/arch/arm/mach-ixp4xx/include/mach/timex.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the | 10 | * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the |
| 11 | * timer register ignores the bottom 2 bits of the LATCH value. | 11 | * timer register ignores the bottom 2 bits of the LATCH value. |
| 12 | */ | 12 | */ |
| 13 | #define FREQ 66666000 | 13 | #define IXP4XX_TIMER_FREQ 66666000 |
| 14 | #define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ) | 14 | #define CLOCK_TICK_RATE \ |
| 15 | (((IXP4XX_TIMER_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ) | ||
| 15 | 16 | ||
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index bfdbe4b5a3c..852f7c9f87d 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | |||
| @@ -265,6 +265,11 @@ void qmgr_release_queue(unsigned int queue) | |||
| 265 | qmgr_queue_descs[queue], queue); | 265 | qmgr_queue_descs[queue], queue); |
| 266 | qmgr_queue_descs[queue][0] = '\x0'; | 266 | qmgr_queue_descs[queue][0] = '\x0'; |
| 267 | #endif | 267 | #endif |
| 268 | |||
| 269 | while ((addr = qmgr_get_entry(queue))) | ||
| 270 | printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n", | ||
| 271 | queue, addr); | ||
| 272 | |||
| 268 | __raw_writel(0, &qmgr_regs->sram[queue]); | 273 | __raw_writel(0, &qmgr_regs->sram[queue]); |
| 269 | 274 | ||
| 270 | used_sram_bitmap[0] &= ~mask[0]; | 275 | used_sram_bitmap[0] &= ~mask[0]; |
| @@ -275,10 +280,6 @@ void qmgr_release_queue(unsigned int queue) | |||
| 275 | spin_unlock_irq(&qmgr_lock); | 280 | spin_unlock_irq(&qmgr_lock); |
| 276 | 281 | ||
| 277 | module_put(THIS_MODULE); | 282 | module_put(THIS_MODULE); |
| 278 | |||
| 279 | while ((addr = qmgr_get_entry(queue))) | ||
| 280 | printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n", | ||
| 281 | queue, addr); | ||
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | static int qmgr_init(void) | 285 | static int qmgr_init(void) |
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index b1a362ebfde..ca72a05ed9c 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c | |||
| @@ -304,7 +304,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ | |||
| 304 | reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ | 304 | reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ |
| 305 | reg &= ~BM_CLKCTRL_##dr##_DIV; \ | 305 | reg &= ~BM_CLKCTRL_##dr##_DIV; \ |
| 306 | reg |= div << BP_CLKCTRL_##dr##_DIV; \ | 306 | reg |= div << BP_CLKCTRL_##dr##_DIV; \ |
| 307 | if (reg | (1 << clk->enable_shift)) { \ | 307 | if (reg & (1 << clk->enable_shift)) { \ |
| 308 | pr_err("%s: clock is gated\n", __func__); \ | 308 | pr_err("%s: clock is gated\n", __func__); \ |
| 309 | return -EINVAL; \ | 309 | return -EINVAL; \ |
| 310 | } \ | 310 | } \ |
| @@ -347,7 +347,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent) \ | |||
| 347 | { \ | 347 | { \ |
| 348 | if (parent != clk->parent) { \ | 348 | if (parent != clk->parent) { \ |
| 349 | __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \ | 349 | __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \ |
| 350 | HW_CLKCTRL_CLKSEQ_TOG); \ | 350 | CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \ |
| 351 | clk->parent = parent; \ | 351 | clk->parent = parent; \ |
| 352 | } \ | 352 | } \ |
| 353 | \ | 353 | \ |
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 56312c092a9..fd1c4c54b8e 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c | |||
| @@ -355,12 +355,12 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ | |||
| 355 | } else { \ | 355 | } else { \ |
| 356 | reg &= ~BM_CLKCTRL_##dr##_DIV; \ | 356 | reg &= ~BM_CLKCTRL_##dr##_DIV; \ |
| 357 | reg |= div << BP_CLKCTRL_##dr##_DIV; \ | 357 | reg |= div << BP_CLKCTRL_##dr##_DIV; \ |
| 358 | if (reg | (1 << clk->enable_shift)) { \ | 358 | if (reg & (1 << clk->enable_shift)) { \ |
| 359 | pr_err("%s: clock is gated\n", __func__); \ | 359 | pr_err("%s: clock is gated\n", __func__); \ |
| 360 | return -EINVAL; \ | 360 | return -EINVAL; \ |
| 361 | } \ | 361 | } \ |
| 362 | } \ | 362 | } \ |
| 363 | __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); \ | 363 | __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ |
| 364 | \ | 364 | \ |
| 365 | for (i = 10000; i; i--) \ | 365 | for (i = 10000; i; i--) \ |
| 366 | if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ | 366 | if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ |
| @@ -483,7 +483,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent) \ | |||
| 483 | { \ | 483 | { \ |
| 484 | if (parent != clk->parent) { \ | 484 | if (parent != clk->parent) { \ |
| 485 | __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \ | 485 | __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \ |
| 486 | HW_CLKCTRL_CLKSEQ_TOG); \ | 486 | CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \ |
| 487 | clk->parent = parent; \ | 487 | clk->parent = parent; \ |
| 488 | } \ | 488 | } \ |
| 489 | \ | 489 | \ |
| @@ -609,7 +609,6 @@ static struct clk_lookup lookups[] = { | |||
| 609 | _REGISTER_CLOCK("duart", NULL, uart_clk) | 609 | _REGISTER_CLOCK("duart", NULL, uart_clk) |
| 610 | _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk) | 610 | _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk) |
| 611 | _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk) | 611 | _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk) |
| 612 | _REGISTER_CLOCK("fec.0", NULL, fec_clk) | ||
| 613 | _REGISTER_CLOCK("rtc", NULL, rtc_clk) | 612 | _REGISTER_CLOCK("rtc", NULL, rtc_clk) |
| 614 | _REGISTER_CLOCK("pll2", NULL, pll2_clk) | 613 | _REGISTER_CLOCK("pll2", NULL, pll2_clk) |
| 615 | _REGISTER_CLOCK(NULL, "hclk", hbus_clk) | 614 | _REGISTER_CLOCK(NULL, "hclk", hbus_clk) |
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c index e7d2269cf70..a7093c88e6a 100644 --- a/arch/arm/mach-mxs/clock.c +++ b/arch/arm/mach-mxs/clock.c | |||
| @@ -57,7 +57,6 @@ static void __clk_disable(struct clk *clk) | |||
| 57 | if (clk->disable) | 57 | if (clk->disable) |
| 58 | clk->disable(clk); | 58 | clk->disable(clk); |
| 59 | __clk_disable(clk->parent); | 59 | __clk_disable(clk->parent); |
| 60 | __clk_disable(clk->secondary); | ||
| 61 | } | 60 | } |
| 62 | } | 61 | } |
| 63 | 62 | ||
| @@ -68,7 +67,6 @@ static int __clk_enable(struct clk *clk) | |||
| 68 | 67 | ||
| 69 | if (clk->usecount++ == 0) { | 68 | if (clk->usecount++ == 0) { |
| 70 | __clk_enable(clk->parent); | 69 | __clk_enable(clk->parent); |
| 71 | __clk_enable(clk->secondary); | ||
| 72 | 70 | ||
| 73 | if (clk->enable) | 71 | if (clk->enable) |
| 74 | clk->enable(clk); | 72 | clk->enable(clk); |
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c index d7ad7a61366..cb0c0e83a52 100644 --- a/arch/arm/mach-mxs/gpio.c +++ b/arch/arm/mach-mxs/gpio.c | |||
| @@ -139,6 +139,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
| 139 | struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq); | 139 | struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq); |
| 140 | u32 gpio_irq_no_base = port->virtual_irq_start; | 140 | u32 gpio_irq_no_base = port->virtual_irq_start; |
| 141 | 141 | ||
| 142 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
| 143 | |||
| 142 | irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) & | 144 | irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) & |
| 143 | __raw_readl(port->base + PINCTRL_IRQEN(port->id)); | 145 | __raw_readl(port->base + PINCTRL_IRQEN(port->id)); |
| 144 | 146 | ||
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h index 041e276d8a3..592c9ab5d76 100644 --- a/arch/arm/mach-mxs/include/mach/clock.h +++ b/arch/arm/mach-mxs/include/mach/clock.h | |||
| @@ -29,8 +29,6 @@ struct clk { | |||
| 29 | int id; | 29 | int id; |
| 30 | /* Source clock this clk depends on */ | 30 | /* Source clock this clk depends on */ |
| 31 | struct clk *parent; | 31 | struct clk *parent; |
| 32 | /* Secondary clock to enable/disable with this clock */ | ||
| 33 | struct clk *secondary; | ||
| 34 | /* Reference count of clock enable/disable */ | 32 | /* Reference count of clock enable/disable */ |
| 35 | __s8 usecount; | 33 | __s8 usecount; |
| 36 | /* Register bit position for clock's enable/disable control. */ | 34 | /* Register bit position for clock's enable/disable control. */ |
diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c index c9088d85da0..453809359ba 100644 --- a/arch/arm/mach-omap1/lcd_dma.c +++ b/arch/arm/mach-omap1/lcd_dma.c | |||
| @@ -37,7 +37,7 @@ int omap_lcd_dma_running(void) | |||
| 37 | * On OMAP1510, internal LCD controller will start the transfer | 37 | * On OMAP1510, internal LCD controller will start the transfer |
| 38 | * when it gets enabled, so assume DMA running if LCD enabled. | 38 | * when it gets enabled, so assume DMA running if LCD enabled. |
| 39 | */ | 39 | */ |
| 40 | if (cpu_is_omap1510()) | 40 | if (cpu_is_omap15xx()) |
| 41 | if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN) | 41 | if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN) |
| 42 | return 1; | 42 | return 1; |
| 43 | 43 | ||
| @@ -95,7 +95,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); | |||
| 95 | 95 | ||
| 96 | void omap_set_lcd_dma_b1_rotation(int rotate) | 96 | void omap_set_lcd_dma_b1_rotation(int rotate) |
| 97 | { | 97 | { |
| 98 | if (cpu_is_omap1510()) { | 98 | if (cpu_is_omap15xx()) { |
| 99 | printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n"); | 99 | printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n"); |
| 100 | BUG(); | 100 | BUG(); |
| 101 | return; | 101 | return; |
| @@ -106,7 +106,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); | |||
| 106 | 106 | ||
| 107 | void omap_set_lcd_dma_b1_mirror(int mirror) | 107 | void omap_set_lcd_dma_b1_mirror(int mirror) |
| 108 | { | 108 | { |
| 109 | if (cpu_is_omap1510()) { | 109 | if (cpu_is_omap15xx()) { |
| 110 | printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n"); | 110 | printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n"); |
| 111 | BUG(); | 111 | BUG(); |
| 112 | } | 112 | } |
| @@ -116,7 +116,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); | |||
| 116 | 116 | ||
| 117 | void omap_set_lcd_dma_b1_vxres(unsigned long vxres) | 117 | void omap_set_lcd_dma_b1_vxres(unsigned long vxres) |
| 118 | { | 118 | { |
| 119 | if (cpu_is_omap1510()) { | 119 | if (cpu_is_omap15xx()) { |
| 120 | printk(KERN_ERR "DMA virtual resulotion is not supported " | 120 | printk(KERN_ERR "DMA virtual resulotion is not supported " |
| 121 | "in 1510 mode\n"); | 121 | "in 1510 mode\n"); |
| 122 | BUG(); | 122 | BUG(); |
| @@ -127,7 +127,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); | |||
| 127 | 127 | ||
| 128 | void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) | 128 | void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) |
| 129 | { | 129 | { |
| 130 | if (cpu_is_omap1510()) { | 130 | if (cpu_is_omap15xx()) { |
| 131 | printk(KERN_ERR "DMA scale is not supported in 1510 mode\n"); | 131 | printk(KERN_ERR "DMA scale is not supported in 1510 mode\n"); |
| 132 | BUG(); | 132 | BUG(); |
| 133 | } | 133 | } |
| @@ -177,7 +177,7 @@ static void set_b1_regs(void) | |||
| 177 | bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); | 177 | bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); |
| 178 | /* 1510 DMA requires the bottom address to be 2 more | 178 | /* 1510 DMA requires the bottom address to be 2 more |
| 179 | * than the actual last memory access location. */ | 179 | * than the actual last memory access location. */ |
| 180 | if (cpu_is_omap1510() && | 180 | if (cpu_is_omap15xx() && |
| 181 | lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) | 181 | lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) |
| 182 | bottom += 2; | 182 | bottom += 2; |
| 183 | ei = PIXSTEP(0, 0, 1, 0); | 183 | ei = PIXSTEP(0, 0, 1, 0); |
| @@ -241,7 +241,7 @@ static void set_b1_regs(void) | |||
| 241 | return; /* Suppress warning about uninitialized vars */ | 241 | return; /* Suppress warning about uninitialized vars */ |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | if (cpu_is_omap1510()) { | 244 | if (cpu_is_omap15xx()) { |
| 245 | omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U); | 245 | omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U); |
| 246 | omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L); | 246 | omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L); |
| 247 | omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U); | 247 | omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U); |
| @@ -343,7 +343,7 @@ void omap_free_lcd_dma(void) | |||
| 343 | BUG(); | 343 | BUG(); |
| 344 | return; | 344 | return; |
| 345 | } | 345 | } |
| 346 | if (!cpu_is_omap1510()) | 346 | if (!cpu_is_omap15xx()) |
| 347 | omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, | 347 | omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, |
| 348 | OMAP1610_DMA_LCD_CCR); | 348 | OMAP1610_DMA_LCD_CCR); |
| 349 | lcd_dma.reserved = 0; | 349 | lcd_dma.reserved = 0; |
| @@ -360,7 +360,7 @@ void omap_enable_lcd_dma(void) | |||
| 360 | * connected. Otherwise the OMAP internal controller will | 360 | * connected. Otherwise the OMAP internal controller will |
| 361 | * start the transfer when it gets enabled. | 361 | * start the transfer when it gets enabled. |
| 362 | */ | 362 | */ |
| 363 | if (cpu_is_omap1510() || !lcd_dma.ext_ctrl) | 363 | if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl) |
| 364 | return; | 364 | return; |
| 365 | 365 | ||
| 366 | w = omap_readw(OMAP1610_DMA_LCD_CTRL); | 366 | w = omap_readw(OMAP1610_DMA_LCD_CTRL); |
| @@ -378,14 +378,14 @@ EXPORT_SYMBOL(omap_enable_lcd_dma); | |||
| 378 | void omap_setup_lcd_dma(void) | 378 | void omap_setup_lcd_dma(void) |
| 379 | { | 379 | { |
| 380 | BUG_ON(lcd_dma.active); | 380 | BUG_ON(lcd_dma.active); |
| 381 | if (!cpu_is_omap1510()) { | 381 | if (!cpu_is_omap15xx()) { |
| 382 | /* Set some reasonable defaults */ | 382 | /* Set some reasonable defaults */ |
| 383 | omap_writew(0x5440, OMAP1610_DMA_LCD_CCR); | 383 | omap_writew(0x5440, OMAP1610_DMA_LCD_CCR); |
| 384 | omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP); | 384 | omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP); |
| 385 | omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL); | 385 | omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL); |
| 386 | } | 386 | } |
| 387 | set_b1_regs(); | 387 | set_b1_regs(); |
| 388 | if (!cpu_is_omap1510()) { | 388 | if (!cpu_is_omap15xx()) { |
| 389 | u16 w; | 389 | u16 w; |
| 390 | 390 | ||
| 391 | w = omap_readw(OMAP1610_DMA_LCD_CCR); | 391 | w = omap_readw(OMAP1610_DMA_LCD_CCR); |
| @@ -407,7 +407,7 @@ void omap_stop_lcd_dma(void) | |||
| 407 | u16 w; | 407 | u16 w; |
| 408 | 408 | ||
| 409 | lcd_dma.active = 0; | 409 | lcd_dma.active = 0; |
| 410 | if (cpu_is_omap1510() || !lcd_dma.ext_ctrl) | 410 | if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl) |
| 411 | return; | 411 | return; |
| 412 | 412 | ||
| 413 | w = omap_readw(OMAP1610_DMA_LCD_CCR); | 413 | w = omap_readw(OMAP1610_DMA_LCD_CCR); |
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index f83fc335c61..6885d2fac18 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #include <linux/clocksource.h> | 44 | #include <linux/clocksource.h> |
| 45 | #include <linux/clockchips.h> | 45 | #include <linux/clockchips.h> |
| 46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
| 47 | #include <linux/sched.h> | ||
| 48 | 47 | ||
| 49 | #include <asm/system.h> | 48 | #include <asm/system.h> |
| 50 | #include <mach/hardware.h> | 49 | #include <mach/hardware.h> |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index e906e05bb41..9a2a31e011c 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
| @@ -115,9 +115,6 @@ static struct omap2_hsmmc_info mmc[] = { | |||
| 115 | 115 | ||
| 116 | static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev) | 116 | static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev) |
| 117 | { | 117 | { |
| 118 | twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1); | ||
| 119 | twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0); | ||
| 120 | |||
| 121 | if (gpio_is_valid(dssdev->reset_gpio)) | 118 | if (gpio_is_valid(dssdev->reset_gpio)) |
| 122 | gpio_set_value_cansleep(dssdev->reset_gpio, 1); | 119 | gpio_set_value_cansleep(dssdev->reset_gpio, 1); |
| 123 | return 0; | 120 | return 0; |
| @@ -247,6 +244,8 @@ static struct gpio_led gpio_leds[]; | |||
| 247 | static int devkit8000_twl_gpio_setup(struct device *dev, | 244 | static int devkit8000_twl_gpio_setup(struct device *dev, |
| 248 | unsigned gpio, unsigned ngpio) | 245 | unsigned gpio, unsigned ngpio) |
| 249 | { | 246 | { |
| 247 | int ret; | ||
| 248 | |||
| 250 | omap_mux_init_gpio(29, OMAP_PIN_INPUT); | 249 | omap_mux_init_gpio(29, OMAP_PIN_INPUT); |
| 251 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ | 250 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ |
| 252 | mmc[0].gpio_cd = gpio + 0; | 251 | mmc[0].gpio_cd = gpio + 0; |
| @@ -255,17 +254,23 @@ static int devkit8000_twl_gpio_setup(struct device *dev, | |||
| 255 | /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ | 254 | /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ |
| 256 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; | 255 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; |
| 257 | 256 | ||
| 258 | /* gpio + 1 is "LCD_PWREN" (out, active high) */ | 257 | /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */ |
| 259 | devkit8000_lcd_device.reset_gpio = gpio + 1; | 258 | devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0; |
| 260 | gpio_request(devkit8000_lcd_device.reset_gpio, "LCD_PWREN"); | 259 | ret = gpio_request_one(devkit8000_lcd_device.reset_gpio, |
| 261 | /* Disable until needed */ | 260 | GPIOF_DIR_OUT | GPIOF_INIT_LOW, "LCD_PWREN"); |
| 262 | gpio_direction_output(devkit8000_lcd_device.reset_gpio, 0); | 261 | if (ret < 0) { |
| 262 | devkit8000_lcd_device.reset_gpio = -EINVAL; | ||
| 263 | printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n"); | ||
| 264 | } | ||
| 263 | 265 | ||
| 264 | /* gpio + 7 is "DVI_PD" (out, active low) */ | 266 | /* gpio + 7 is "DVI_PD" (out, active low) */ |
| 265 | devkit8000_dvi_device.reset_gpio = gpio + 7; | 267 | devkit8000_dvi_device.reset_gpio = gpio + 7; |
| 266 | gpio_request(devkit8000_dvi_device.reset_gpio, "DVI PowerDown"); | 268 | ret = gpio_request_one(devkit8000_dvi_device.reset_gpio, |
| 267 | /* Disable until needed */ | 269 | GPIOF_DIR_OUT | GPIOF_INIT_LOW, "DVI PowerDown"); |
| 268 | gpio_direction_output(devkit8000_dvi_device.reset_gpio, 0); | 270 | if (ret < 0) { |
| 271 | devkit8000_dvi_device.reset_gpio = -EINVAL; | ||
| 272 | printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n"); | ||
| 273 | } | ||
| 269 | 274 | ||
| 270 | return 0; | 275 | return 0; |
| 271 | } | 276 | } |
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index e001a048dc0..e944025d5ef 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
| @@ -409,8 +409,6 @@ static void __init omap4_panda_init(void) | |||
| 409 | platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); | 409 | platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); |
| 410 | omap_serial_init(); | 410 | omap_serial_init(); |
| 411 | omap4_twl6030_hsmmc_init(mmc); | 411 | omap4_twl6030_hsmmc_init(mmc); |
| 412 | /* OMAP4 Panda uses internal transceiver so register nop transceiver */ | ||
| 413 | usb_nop_xceiv_register(); | ||
| 414 | omap4_ehci_init(); | 412 | omap4_ehci_init(); |
| 415 | usb_musb_init(&musb_board_data); | 413 | usb_musb_init(&musb_board_data); |
| 416 | } | 414 | } |
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c index cb77be7ac44..39a71bb8a30 100644 --- a/arch/arm/mach-omap2/board-rm680.c +++ b/arch/arm/mach-omap2/board-rm680.c | |||
| @@ -40,9 +40,6 @@ static struct regulator_consumer_supply rm680_vemmc_consumers[] = { | |||
| 40 | static struct regulator_init_data rm680_vemmc = { | 40 | static struct regulator_init_data rm680_vemmc = { |
| 41 | .constraints = { | 41 | .constraints = { |
| 42 | .name = "rm680_vemmc", | 42 | .name = "rm680_vemmc", |
| 43 | .min_uV = 2900000, | ||
| 44 | .max_uV = 2900000, | ||
| 45 | .apply_uV = 1, | ||
| 46 | .valid_modes_mask = REGULATOR_MODE_NORMAL | 43 | .valid_modes_mask = REGULATOR_MODE_NORMAL |
| 47 | | REGULATOR_MODE_STANDBY, | 44 | | REGULATOR_MODE_STANDBY, |
| 48 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | 45 | .valid_ops_mask = REGULATOR_CHANGE_STATUS |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index fae49d12bc7..98148b6c36e 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
| @@ -1000,6 +1000,7 @@ int __init omap_mux_init(const char *name, u32 flags, | |||
| 1000 | if (!partition->base) { | 1000 | if (!partition->base) { |
| 1001 | pr_err("%s: Could not ioremap mux partition at 0x%08x\n", | 1001 | pr_err("%s: Could not ioremap mux partition at 0x%08x\n", |
| 1002 | __func__, partition->phys); | 1002 | __func__, partition->phys); |
| 1003 | kfree(partition); | ||
| 1003 | return -ENODEV; | 1004 | return -ENODEV; |
| 1004 | } | 1005 | } |
| 1005 | 1006 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a4aa1920a75..2f864e4b085 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
| @@ -168,9 +168,10 @@ static void omap3_core_restore_context(void) | |||
| 168 | * once during boot sequence, but this works as we are not using secure | 168 | * once during boot sequence, but this works as we are not using secure |
| 169 | * services. | 169 | * services. |
| 170 | */ | 170 | */ |
| 171 | static void omap3_save_secure_ram_context(u32 target_mpu_state) | 171 | static void omap3_save_secure_ram_context(void) |
| 172 | { | 172 | { |
| 173 | u32 ret; | 173 | u32 ret; |
| 174 | int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); | ||
| 174 | 175 | ||
| 175 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { | 176 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { |
| 176 | /* | 177 | /* |
| @@ -181,7 +182,7 @@ static void omap3_save_secure_ram_context(u32 target_mpu_state) | |||
| 181 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); | 182 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); |
| 182 | ret = _omap_save_secure_sram((u32 *) | 183 | ret = _omap_save_secure_sram((u32 *) |
| 183 | __pa(omap3_secure_ram_storage)); | 184 | __pa(omap3_secure_ram_storage)); |
| 184 | pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state); | 185 | pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); |
| 185 | /* Following is for error tracking, it should not happen */ | 186 | /* Following is for error tracking, it should not happen */ |
| 186 | if (ret) { | 187 | if (ret) { |
| 187 | printk(KERN_ERR "save_secure_sram() returns %08x\n", | 188 | printk(KERN_ERR "save_secure_sram() returns %08x\n", |
| @@ -1094,7 +1095,7 @@ static int __init omap3_pm_init(void) | |||
| 1094 | local_fiq_disable(); | 1095 | local_fiq_disable(); |
| 1095 | 1096 | ||
| 1096 | omap_dma_global_context_save(); | 1097 | omap_dma_global_context_save(); |
| 1097 | omap3_save_secure_ram_context(PWRDM_POWER_ON); | 1098 | omap3_save_secure_ram_context(); |
| 1098 | omap_dma_global_context_restore(); | 1099 | omap_dma_global_context_restore(); |
| 1099 | 1100 | ||
| 1100 | local_irq_enable(); | 1101 | local_irq_enable(); |
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 77ecebf3fae..c37e823266d 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c | |||
| @@ -780,8 +780,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val) | |||
| 780 | struct omap_sr *sr_info = (struct omap_sr *) data; | 780 | struct omap_sr *sr_info = (struct omap_sr *) data; |
| 781 | 781 | ||
| 782 | if (!sr_info) { | 782 | if (!sr_info) { |
| 783 | pr_warning("%s: omap_sr struct for sr_%s not found\n", | 783 | pr_warning("%s: omap_sr struct not found\n", __func__); |
| 784 | __func__, sr_info->voltdm->name); | ||
| 785 | return -EINVAL; | 784 | return -EINVAL; |
| 786 | } | 785 | } |
| 787 | 786 | ||
| @@ -795,8 +794,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) | |||
| 795 | struct omap_sr *sr_info = (struct omap_sr *) data; | 794 | struct omap_sr *sr_info = (struct omap_sr *) data; |
| 796 | 795 | ||
| 797 | if (!sr_info) { | 796 | if (!sr_info) { |
| 798 | pr_warning("%s: omap_sr struct for sr_%s not found\n", | 797 | pr_warning("%s: omap_sr struct not found\n", __func__); |
| 799 | __func__, sr_info->voltdm->name); | ||
| 800 | return -EINVAL; | 798 | return -EINVAL; |
| 801 | } | 799 | } |
| 802 | 800 | ||
| @@ -834,7 +832,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) | |||
| 834 | 832 | ||
| 835 | if (!pdata) { | 833 | if (!pdata) { |
| 836 | dev_err(&pdev->dev, "%s: platform data missing\n", __func__); | 834 | dev_err(&pdev->dev, "%s: platform data missing\n", __func__); |
| 837 | return -EINVAL; | 835 | ret = -EINVAL; |
| 836 | goto err_free_devinfo; | ||
| 838 | } | 837 | } |
| 839 | 838 | ||
| 840 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 839 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -966,7 +965,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) | |||
| 966 | } | 965 | } |
| 967 | 966 | ||
| 968 | sr_info = _sr_lookup(pdata->voltdm); | 967 | sr_info = _sr_lookup(pdata->voltdm); |
| 969 | if (!sr_info) { | 968 | if (IS_ERR(sr_info)) { |
| 970 | dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", | 969 | dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", |
| 971 | __func__); | 970 | __func__); |
| 972 | return -EINVAL; | 971 | return -EINVAL; |
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index ed6079c94c5..12be525b8df 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c | |||
| @@ -471,6 +471,7 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd) | |||
| 471 | strcat(name, vdd->voltdm.name); | 471 | strcat(name, vdd->voltdm.name); |
| 472 | 472 | ||
| 473 | vdd->debug_dir = debugfs_create_dir(name, voltage_dir); | 473 | vdd->debug_dir = debugfs_create_dir(name, voltage_dir); |
| 474 | kfree(name); | ||
| 474 | if (IS_ERR(vdd->debug_dir)) { | 475 | if (IS_ERR(vdd->debug_dir)) { |
| 475 | pr_warning("%s: Unable to create debugfs directory for" | 476 | pr_warning("%s: Unable to create debugfs directory for" |
| 476 | " vdd_%s\n", __func__, vdd->voltdm.name); | 477 | " vdd_%s\n", __func__, vdd->voltdm.name); |
diff --git a/arch/arm/mach-pxa/colibri-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c index 6b2c800a113..28f667e52ef 100644 --- a/arch/arm/mach-pxa/colibri-evalboard.c +++ b/arch/arm/mach-pxa/colibri-evalboard.c | |||
| @@ -50,7 +50,7 @@ static void __init colibri_mmc_init(void) | |||
| 50 | GPIO0_COLIBRI_PXA270_SD_DETECT; | 50 | GPIO0_COLIBRI_PXA270_SD_DETECT; |
| 51 | if (machine_is_colibri300()) /* PXA300 Colibri */ | 51 | if (machine_is_colibri300()) /* PXA300 Colibri */ |
| 52 | colibri_mci_platform_data.gpio_card_detect = | 52 | colibri_mci_platform_data.gpio_card_detect = |
| 53 | GPIO39_COLIBRI_PXA300_SD_DETECT; | 53 | GPIO13_COLIBRI_PXA300_SD_DETECT; |
| 54 | else /* PXA320 Colibri */ | 54 | else /* PXA320 Colibri */ |
| 55 | colibri_mci_platform_data.gpio_card_detect = | 55 | colibri_mci_platform_data.gpio_card_detect = |
| 56 | GPIO28_COLIBRI_PXA320_SD_DETECT; | 56 | GPIO28_COLIBRI_PXA320_SD_DETECT; |
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index fddb16d07eb..66dd81cbc8a 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c | |||
| @@ -41,7 +41,7 @@ static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = { | |||
| 41 | GPIO4_MMC1_DAT1, | 41 | GPIO4_MMC1_DAT1, |
| 42 | GPIO5_MMC1_DAT2, | 42 | GPIO5_MMC1_DAT2, |
| 43 | GPIO6_MMC1_DAT3, | 43 | GPIO6_MMC1_DAT3, |
| 44 | GPIO39_GPIO, /* SD detect */ | 44 | GPIO13_GPIO, /* GPIO13_COLIBRI_PXA300_SD_DETECT */ |
| 45 | 45 | ||
| 46 | /* UHC */ | 46 | /* UHC */ |
| 47 | GPIO0_2_USBH_PEN, | 47 | GPIO0_2_USBH_PEN, |
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h index 388a96f1ef9..cb4236e98a0 100644 --- a/arch/arm/mach-pxa/include/mach/colibri.h +++ b/arch/arm/mach-pxa/include/mach/colibri.h | |||
| @@ -60,7 +60,7 @@ static inline void colibri_pxa3xx_init_nand(void) {} | |||
| 60 | #define GPIO113_COLIBRI_PXA270_TS_IRQ 113 | 60 | #define GPIO113_COLIBRI_PXA270_TS_IRQ 113 |
| 61 | 61 | ||
| 62 | /* GPIO definitions for Colibri PXA300/310 */ | 62 | /* GPIO definitions for Colibri PXA300/310 */ |
| 63 | #define GPIO39_COLIBRI_PXA300_SD_DETECT 39 | 63 | #define GPIO13_COLIBRI_PXA300_SD_DETECT 13 |
| 64 | 64 | ||
| 65 | /* GPIO definitions for Colibri PXA320 */ | 65 | /* GPIO definitions for Colibri PXA320 */ |
| 66 | #define GPIO28_COLIBRI_PXA320_SD_DETECT 28 | 66 | #define GPIO28_COLIBRI_PXA320_SD_DETECT 28 |
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 405b92a2979..35572c427fa 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c | |||
| @@ -323,7 +323,7 @@ static struct platform_pwm_backlight_data palm27x_backlight_data = { | |||
| 323 | .pwm_id = 0, | 323 | .pwm_id = 0, |
| 324 | .max_brightness = 0xfe, | 324 | .max_brightness = 0xfe, |
| 325 | .dft_brightness = 0x7e, | 325 | .dft_brightness = 0x7e, |
| 326 | .pwm_period_ns = 3500, | 326 | .pwm_period_ns = 3500 * 1024, |
| 327 | .init = palm27x_backlight_init, | 327 | .init = palm27x_backlight_init, |
| 328 | .notify = palm27x_backlight_notify, | 328 | .notify = palm27x_backlight_notify, |
| 329 | .exit = palm27x_backlight_exit, | 329 | .exit = palm27x_backlight_exit, |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 978e1b28954..1807c9abdde 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
| @@ -33,7 +33,7 @@ int pxa_pm_enter(suspend_state_t state) | |||
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | /* skip registers saving for standby */ | 35 | /* skip registers saving for standby */ |
| 36 | if (state != PM_SUSPEND_STANDBY) { | 36 | if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) { |
| 37 | pxa_cpu_pm_fns->save(sleep_save); | 37 | pxa_cpu_pm_fns->save(sleep_save); |
| 38 | /* before sleeping, calculate and save a checksum */ | 38 | /* before sleeping, calculate and save a checksum */ |
| 39 | for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) | 39 | for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) |
| @@ -44,7 +44,7 @@ int pxa_pm_enter(suspend_state_t state) | |||
| 44 | pxa_cpu_pm_fns->enter(state); | 44 | pxa_cpu_pm_fns->enter(state); |
| 45 | cpu_init(); | 45 | cpu_init(); |
| 46 | 46 | ||
| 47 | if (state != PM_SUSPEND_STANDBY) { | 47 | if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { |
| 48 | /* after sleeping, validate the checksum */ | 48 | /* after sleeping, validate the checksum */ |
| 49 | for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) | 49 | for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) |
| 50 | checksum += sleep_save[i]; | 50 | checksum += sleep_save[i]; |
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 09c4c21b70c..b2a9acc5185 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig | |||
| @@ -122,6 +122,7 @@ config MACH_SMDKV310 | |||
| 122 | select S3C_DEV_HSMMC2 | 122 | select S3C_DEV_HSMMC2 |
| 123 | select S3C_DEV_HSMMC3 | 123 | select S3C_DEV_HSMMC3 |
| 124 | select S5PV310_DEV_PD | 124 | select S5PV310_DEV_PD |
| 125 | select S5PV310_DEV_SYSMMU | ||
| 125 | select S5PV310_SETUP_I2C1 | 126 | select S5PV310_SETUP_I2C1 |
| 126 | select S5PV310_SETUP_SDHCI | 127 | select S5PV310_SETUP_SDHCI |
| 127 | help | 128 | help |
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 74d400625a2..3060f78e12a 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h | |||
| @@ -124,8 +124,6 @@ | |||
| 124 | #define S5PV310_PA_SYSMMU_TV 0x12E20000 | 124 | #define S5PV310_PA_SYSMMU_TV 0x12E20000 |
| 125 | #define S5PV310_PA_SYSMMU_MFC_L 0x13620000 | 125 | #define S5PV310_PA_SYSMMU_MFC_L 0x13620000 |
| 126 | #define S5PV310_PA_SYSMMU_MFC_R 0x13630000 | 126 | #define S5PV310_PA_SYSMMU_MFC_R 0x13630000 |
| 127 | #define S5PV310_SYSMMU_TOTAL_IPNUM 16 | ||
| 128 | #define S5P_SYSMMU_TOTAL_IPNUM S5PV310_SYSMMU_TOTAL_IPNUM | ||
| 129 | 127 | ||
| 130 | /* compatibiltiy defines. */ | 128 | /* compatibiltiy defines. */ |
| 131 | #define S3C_PA_UART S5PV310_PA_UART | 129 | #define S3C_PA_UART S5PV310_PA_UART |
diff --git a/arch/arm/mach-s5pv310/include/mach/sysmmu.h b/arch/arm/mach-s5pv310/include/mach/sysmmu.h index 662fe85ff4d..598fc5c9211 100644 --- a/arch/arm/mach-s5pv310/include/mach/sysmmu.h +++ b/arch/arm/mach-s5pv310/include/mach/sysmmu.h | |||
| @@ -13,6 +13,9 @@ | |||
| 13 | #ifndef __ASM_ARM_ARCH_SYSMMU_H | 13 | #ifndef __ASM_ARM_ARCH_SYSMMU_H |
| 14 | #define __ASM_ARM_ARCH_SYSMMU_H __FILE__ | 14 | #define __ASM_ARM_ARCH_SYSMMU_H __FILE__ |
| 15 | 15 | ||
| 16 | #define S5PV310_SYSMMU_TOTAL_IPNUM 16 | ||
| 17 | #define S5P_SYSMMU_TOTAL_IPNUM S5PV310_SYSMMU_TOTAL_IPNUM | ||
| 18 | |||
| 16 | enum s5pv310_sysmmu_ips { | 19 | enum s5pv310_sysmmu_ips { |
| 17 | SYSMMU_MDMA, | 20 | SYSMMU_MDMA, |
| 18 | SYSMMU_SSS, | 21 | SYSMMU_SSS, |
| @@ -32,7 +35,7 @@ enum s5pv310_sysmmu_ips { | |||
| 32 | SYSMMU_MFC_R, | 35 | SYSMMU_MFC_R, |
| 33 | }; | 36 | }; |
| 34 | 37 | ||
| 35 | static char *sysmmu_ips_name[S5P_SYSMMU_TOTAL_IPNUM] = { | 38 | static char *sysmmu_ips_name[S5PV310_SYSMMU_TOTAL_IPNUM] = { |
| 36 | "SYSMMU_MDMA" , | 39 | "SYSMMU_MDMA" , |
| 37 | "SYSMMU_SSS" , | 40 | "SYSMMU_SSS" , |
| 38 | "SYSMMU_FIMC0" , | 41 | "SYSMMU_FIMC0" , |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index d43c5ef58eb..bd3e1bfdd6a 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
| @@ -241,6 +241,9 @@ static struct locomo_platform_data locomo_info = { | |||
| 241 | struct platform_device collie_locomo_device = { | 241 | struct platform_device collie_locomo_device = { |
| 242 | .name = "locomo", | 242 | .name = "locomo", |
| 243 | .id = 0, | 243 | .id = 0, |
| 244 | .dev = { | ||
| 245 | .platform_data = &locomo_info, | ||
| 246 | }, | ||
| 244 | .num_resources = ARRAY_SIZE(locomo_resources), | 247 | .num_resources = ARRAY_SIZE(locomo_resources), |
| 245 | .resource = locomo_resources, | 248 | .resource = locomo_resources, |
| 246 | }; | 249 | }; |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 9d30c6f804b..e4509bae8fc 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -405,7 +405,7 @@ config CPU_V6 | |||
| 405 | config CPU_32v6K | 405 | config CPU_32v6K |
| 406 | bool "Support ARM V6K processor extensions" if !SMP | 406 | bool "Support ARM V6K processor extensions" if !SMP |
| 407 | depends on CPU_V6 || CPU_V7 | 407 | depends on CPU_V6 || CPU_V7 |
| 408 | default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) | 408 | default y if SMP |
| 409 | help | 409 | help |
| 410 | Say Y here if your ARMv6 processor supports the 'K' extension. | 410 | Say Y here if your ARMv6 processor supports the 'K' extension. |
| 411 | This enables the kernel to use some instructions not present | 411 | This enables the kernel to use some instructions not present |
| @@ -416,7 +416,7 @@ config CPU_32v6K | |||
| 416 | # ARMv7 | 416 | # ARMv7 |
| 417 | config CPU_V7 | 417 | config CPU_V7 |
| 418 | bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX | 418 | bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX |
| 419 | select CPU_32v6K if !ARCH_OMAP2 | 419 | select CPU_32v6K |
| 420 | select CPU_32v7 | 420 | select CPU_32v7 |
| 421 | select CPU_ABRT_EV7 | 421 | select CPU_ABRT_EV7 |
| 422 | select CPU_PABRT_V7 | 422 | select CPU_PABRT_V7 |
| @@ -644,7 +644,7 @@ config ARM_THUMBEE | |||
| 644 | 644 | ||
| 645 | config SWP_EMULATE | 645 | config SWP_EMULATE |
| 646 | bool "Emulate SWP/SWPB instructions" | 646 | bool "Emulate SWP/SWPB instructions" |
| 647 | depends on CPU_V7 && !CPU_V6 | 647 | depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6 |
| 648 | select HAVE_PROC_CPU if PROC_FS | 648 | select HAVE_PROC_CPU if PROC_FS |
| 649 | default y if SMP | 649 | default y if SMP |
| 650 | help | 650 | help |
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 8aa974491df..c074e66ad22 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/errno.h> | ||
| 15 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 16 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
| 17 | #include <linux/oprofile.h> | 15 | #include <linux/oprofile.h> |
| @@ -46,6 +44,7 @@ char *op_name_from_perf_id(void) | |||
| 46 | return NULL; | 44 | return NULL; |
| 47 | } | 45 | } |
| 48 | } | 46 | } |
| 47 | #endif | ||
| 49 | 48 | ||
| 50 | static int report_trace(struct stackframe *frame, void *d) | 49 | static int report_trace(struct stackframe *frame, void *d) |
| 51 | { | 50 | { |
| @@ -85,7 +84,7 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail) | |||
| 85 | 84 | ||
| 86 | /* frame pointers should strictly progress back up the stack | 85 | /* frame pointers should strictly progress back up the stack |
| 87 | * (towards higher addresses) */ | 86 | * (towards higher addresses) */ |
| 88 | if (tail >= buftail[0].fp) | 87 | if (tail + 1 >= buftail[0].fp) |
| 89 | return NULL; | 88 | return NULL; |
| 90 | 89 | ||
| 91 | return buftail[0].fp-1; | 90 | return buftail[0].fp-1; |
| @@ -111,6 +110,7 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
| 111 | 110 | ||
| 112 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 111 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
| 113 | { | 112 | { |
| 113 | /* provide backtrace support also in timer mode: */ | ||
| 114 | ops->backtrace = arm_backtrace; | 114 | ops->backtrace = arm_backtrace; |
| 115 | 115 | ||
| 116 | return oprofile_perf_init(ops); | 116 | return oprofile_perf_init(ops); |
| @@ -120,11 +120,3 @@ void __exit oprofile_arch_exit(void) | |||
| 120 | { | 120 | { |
| 121 | oprofile_perf_exit(); | 121 | oprofile_perf_exit(); |
| 122 | } | 122 | } |
| 123 | #else | ||
| 124 | int __init oprofile_arch_init(struct oprofile_operations *ops) | ||
| 125 | { | ||
| 126 | pr_info("oprofile: hardware counters not available\n"); | ||
| 127 | return -ENODEV; | ||
| 128 | } | ||
| 129 | void __exit oprofile_arch_exit(void) {} | ||
| 130 | #endif /* CONFIG_HW_PERF_EVENTS */ | ||
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index 3a70ebf0477..ff469c4f1d7 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h | |||
| @@ -95,6 +95,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) | |||
| 95 | case MACH_TYPE_MX35_3DS: | 95 | case MACH_TYPE_MX35_3DS: |
| 96 | case MACH_TYPE_PCM043: | 96 | case MACH_TYPE_PCM043: |
| 97 | case MACH_TYPE_LILLY1131: | 97 | case MACH_TYPE_LILLY1131: |
| 98 | case MACH_TYPE_VPR200: | ||
| 98 | uart_base = MX3X_UART1_BASE_ADDR; | 99 | uart_base = MX3X_UART1_BASE_ADDR; |
| 99 | break; | 100 | break; |
| 100 | case MACH_TYPE_MAGX_ZN5: | 101 | case MACH_TYPE_MAGX_ZN5: |
| @@ -102,6 +103,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) | |||
| 102 | break; | 103 | break; |
| 103 | case MACH_TYPE_MX51_BABBAGE: | 104 | case MACH_TYPE_MX51_BABBAGE: |
| 104 | case MACH_TYPE_EUKREA_CPUIMX51SD: | 105 | case MACH_TYPE_EUKREA_CPUIMX51SD: |
| 106 | case MACH_TYPE_MX51_3DS: | ||
| 105 | uart_base = MX51_UART1_BASE_ADDR; | 107 | uart_base = MX51_UART1_BASE_ADDR; |
| 106 | break; | 108 | break; |
| 107 | case MACH_TYPE_MX50_RDP: | 109 | case MACH_TYPE_MX50_RDP: |
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c index b77e018d36c..a9aa5ad3f4e 100644 --- a/arch/arm/plat-pxa/mfp.c +++ b/arch/arm/plat-pxa/mfp.c | |||
| @@ -139,10 +139,11 @@ static const unsigned long mfpr_edge[] = { | |||
| 139 | #define mfp_configured(p) ((p)->config != -1) | 139 | #define mfp_configured(p) ((p)->config != -1) |
| 140 | 140 | ||
| 141 | /* | 141 | /* |
| 142 | * perform a read-back of any MFPR register to make sure the | 142 | * perform a read-back of any valid MFPR register to make sure the |
| 143 | * previous writings are finished | 143 | * previous writings are finished |
| 144 | */ | 144 | */ |
| 145 | #define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) | 145 | static unsigned long mfpr_off_readback; |
| 146 | #define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + mfpr_off_readback) | ||
| 146 | 147 | ||
| 147 | static inline void __mfp_config_run(struct mfp_pin *p) | 148 | static inline void __mfp_config_run(struct mfp_pin *p) |
| 148 | { | 149 | { |
| @@ -248,6 +249,9 @@ void __init mfp_init_addr(struct mfp_addr_map *map) | |||
| 248 | 249 | ||
| 249 | spin_lock_irqsave(&mfp_spin_lock, flags); | 250 | spin_lock_irqsave(&mfp_spin_lock, flags); |
| 250 | 251 | ||
| 252 | /* mfp offset for readback */ | ||
| 253 | mfpr_off_readback = map[0].offset; | ||
| 254 | |||
| 251 | for (p = map; p->start != MFP_PIN_INVALID; p++) { | 255 | for (p = map; p->start != MFP_PIN_INVALID; p++) { |
| 252 | offset = p->offset; | 256 | offset = p->offset; |
| 253 | i = p->start; | 257 | i = p->start; |
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index deb39951a22..557f8c507f6 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig | |||
| @@ -37,6 +37,14 @@ config S5P_GPIO_INT | |||
| 37 | help | 37 | help |
| 38 | Common code for the GPIO interrupts (other than external interrupts.) | 38 | Common code for the GPIO interrupts (other than external interrupts.) |
| 39 | 39 | ||
| 40 | comment "System MMU" | ||
| 41 | |||
| 42 | config S5P_SYSTEM_MMU | ||
| 43 | bool "S5P SYSTEM MMU" | ||
| 44 | depends on ARCH_S5PV310 | ||
| 45 | help | ||
| 46 | Say Y here if you want to enable System MMU | ||
| 47 | |||
| 40 | config S5P_DEV_FIMC0 | 48 | config S5P_DEV_FIMC0 |
| 41 | bool | 49 | bool |
| 42 | help | 50 | help |
| @@ -66,19 +74,3 @@ config S5P_DEV_CSIS1 | |||
| 66 | bool | 74 | bool |
| 67 | help | 75 | help |
| 68 | Compile in platform device definitions for MIPI-CSIS channel 1 | 76 | Compile in platform device definitions for MIPI-CSIS channel 1 |
| 69 | |||
| 70 | menuconfig S5P_SYSMMU | ||
| 71 | bool "SYSMMU support" | ||
| 72 | depends on ARCH_S5PV310 | ||
| 73 | help | ||
| 74 | This is a System MMU driver for Samsung ARM based Soc. | ||
| 75 | |||
| 76 | if S5P_SYSMMU | ||
| 77 | |||
| 78 | config S5P_SYSMMU_DEBUG | ||
| 79 | bool "Enables debug messages" | ||
| 80 | depends on S5P_SYSMMU | ||
| 81 | help | ||
| 82 | This enables SYSMMU driver debug massages. | ||
| 83 | |||
| 84 | endif | ||
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 92efe1adcfd..4bd5cf90897 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile | |||
| @@ -19,6 +19,7 @@ obj-y += clock.o | |||
| 19 | obj-y += irq.o | 19 | obj-y += irq.o |
| 20 | obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o | 20 | obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o |
| 21 | obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o | 21 | obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o |
| 22 | obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o | ||
| 22 | obj-$(CONFIG_PM) += pm.o | 23 | obj-$(CONFIG_PM) += pm.o |
| 23 | obj-$(CONFIG_PM) += irq-pm.o | 24 | obj-$(CONFIG_PM) += irq-pm.o |
| 24 | 25 | ||
| @@ -30,4 +31,3 @@ obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o | |||
| 30 | obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o | 31 | obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o |
| 31 | obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o | 32 | obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o |
| 32 | obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o | 33 | obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o |
| 33 | obj-$(CONFIG_S5P_SYSMMU) += sysmmu.o | ||
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h deleted file mode 100644 index db298fc5438..00000000000 --- a/arch/arm/plat-s5p/include/plat/sysmmu.h +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* linux/arch/arm/plat-s5p/include/plat/sysmmu.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com/ | ||
| 5 | * | ||
| 6 | * Samsung sysmmu driver | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_PLAT_S5P_SYSMMU_H | ||
| 14 | #define __ASM_PLAT_S5P_SYSMMU_H __FILE__ | ||
| 15 | |||
| 16 | /* debug macro */ | ||
| 17 | #ifdef CONFIG_S5P_SYSMMU_DEBUG | ||
| 18 | #define sysmmu_debug(fmt, arg...) printk(KERN_INFO "[%s] " fmt, __func__, ## arg) | ||
| 19 | #else | ||
| 20 | #define sysmmu_debug(fmt, arg...) do { } while (0) | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #endif /* __ASM_PLAT_S5P_SYSMMU_H */ | ||
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c index d804914dc2e..ffe8a48bc3c 100644 --- a/arch/arm/plat-s5p/sysmmu.c +++ b/arch/arm/plat-s5p/sysmmu.c | |||
| @@ -16,8 +16,6 @@ | |||
| 16 | #include <mach/regs-sysmmu.h> | 16 | #include <mach/regs-sysmmu.h> |
| 17 | #include <mach/sysmmu.h> | 17 | #include <mach/sysmmu.h> |
| 18 | 18 | ||
| 19 | #include <plat/sysmmu.h> | ||
| 20 | |||
| 21 | struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM]; | 19 | struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM]; |
| 22 | 20 | ||
| 23 | void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp) | 21 | void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp) |
| @@ -123,7 +121,7 @@ static int s5p_sysmmu_set_tablebase(sysmmu_ips ips) | |||
| 123 | : "=r" (pg) : : "cc"); \ | 121 | : "=r" (pg) : : "cc"); \ |
| 124 | pg &= ~0x3fff; | 122 | pg &= ~0x3fff; |
| 125 | 123 | ||
| 126 | sysmmu_debug("CP15 TTBR0 : 0x%x\n", pg); | 124 | printk(KERN_INFO "%s: CP15 TTBR0 : 0x%x\n", __func__, pg); |
| 127 | 125 | ||
| 128 | /* Set sysmmu page table base address */ | 126 | /* Set sysmmu page table base address */ |
| 129 | __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR); | 127 | __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR); |
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index d9025e37767..30518cc9a67 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
| 19 | 19 | ||
| 20 | struct sys_device; | ||
| 21 | |||
| 20 | #ifdef CONFIG_PM | 22 | #ifdef CONFIG_PM |
| 21 | 23 | ||
| 22 | extern __init int s3c_pm_init(void); | 24 | extern __init int s3c_pm_init(void); |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 2fea897ebeb..9d6feaabbe7 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | # | 12 | # |
| 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
| 14 | # | 14 | # |
| 15 | # Last update: Sun Dec 12 23:24:27 2010 | 15 | # Last update: Mon Feb 7 08:59:27 2011 |
| 16 | # | 16 | # |
| 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
| 18 | # | 18 | # |
| @@ -2240,7 +2240,7 @@ arm_ultimator2 MACH_ARM_ULTIMATOR2 ARM_ULTIMATOR2 2250 | |||
| 2240 | vs_v210 MACH_VS_V210 VS_V210 2252 | 2240 | vs_v210 MACH_VS_V210 VS_V210 2252 |
| 2241 | vs_v212 MACH_VS_V212 VS_V212 2253 | 2241 | vs_v212 MACH_VS_V212 VS_V212 2253 |
| 2242 | hmt MACH_HMT HMT 2254 | 2242 | hmt MACH_HMT HMT 2254 |
| 2243 | suen3 MACH_SUEN3 SUEN3 2255 | 2243 | km_kirkwood MACH_KM_KIRKWOOD KM_KIRKWOOD 2255 |
| 2244 | vesper MACH_VESPER VESPER 2256 | 2244 | vesper MACH_VESPER VESPER 2256 |
| 2245 | str9 MACH_STR9 STR9 2257 | 2245 | str9 MACH_STR9 STR9 2257 |
| 2246 | omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258 | 2246 | omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258 |
| @@ -2987,7 +2987,7 @@ pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001 | |||
| 2987 | ea20 MACH_EA20 EA20 3002 | 2987 | ea20 MACH_EA20 EA20 3002 |
| 2988 | awm2 MACH_AWM2 AWM2 3003 | 2988 | awm2 MACH_AWM2 AWM2 3003 |
| 2989 | ti8148evm MACH_TI8148EVM TI8148EVM 3004 | 2989 | ti8148evm MACH_TI8148EVM TI8148EVM 3004 |
| 2990 | tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_SEABOARD 3005 | 2990 | seaboard MACH_SEABOARD SEABOARD 3005 |
| 2991 | linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006 | 2991 | linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006 |
| 2992 | tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007 | 2992 | tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007 |
| 2993 | rubys MACH_RUBYS RUBYS 3008 | 2993 | rubys MACH_RUBYS RUBYS 3008 |
| @@ -3190,7 +3190,7 @@ synergy MACH_SYNERGY SYNERGY 3205 | |||
| 3190 | ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 | 3190 | ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 |
| 3191 | wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 | 3191 | wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 |
| 3192 | punica MACH_PUNICA PUNICA 3208 | 3192 | punica MACH_PUNICA PUNICA 3208 |
| 3193 | sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209 | 3193 | trimslice MACH_TRIMSLICE TRIMSLICE 3209 |
| 3194 | mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 | 3194 | mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 |
| 3195 | mackerel MACH_MACKEREL MACKEREL 3211 | 3195 | mackerel MACH_MACKEREL MACKEREL 3211 |
| 3196 | fa9x27 MACH_FA9X27 FA9X27 3213 | 3196 | fa9x27 MACH_FA9X27 FA9X27 3213 |
| @@ -3219,3 +3219,100 @@ pivicc MACH_PIVICC PIVICC 3235 | |||
| 3219 | pcm048 MACH_PCM048 PCM048 3236 | 3219 | pcm048 MACH_PCM048 PCM048 3236 |
| 3220 | dds MACH_DDS DDS 3237 | 3220 | dds MACH_DDS DDS 3237 |
| 3221 | chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 | 3221 | chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 |
| 3222 | ts48xx MACH_TS48XX TS48XX 3239 | ||
| 3223 | tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240 | ||
| 3224 | whistler MACH_WHISTLER WHISTLER 3241 | ||
| 3225 | asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242 | ||
| 3226 | at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243 | ||
| 3227 | ddplug MACH_DDPLUG DDPLUG 3244 | ||
| 3228 | d2plug MACH_D2PLUG D2PLUG 3245 | ||
| 3229 | kzm9d MACH_KZM9D KZM9D 3246 | ||
| 3230 | verdi_lte MACH_VERDI_LTE VERDI_LTE 3247 | ||
| 3231 | nanozoom MACH_NANOZOOM NANOZOOM 3248 | ||
| 3232 | dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249 | ||
| 3233 | dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250 | ||
| 3234 | anchovy MACH_ANCHOVY ANCHOVY 3251 | ||
| 3235 | re2rev20 MACH_RE2REV20 RE2REV20 3253 | ||
| 3236 | re2rev21 MACH_RE2REV21 RE2REV21 3254 | ||
| 3237 | cns21xx MACH_CNS21XX CNS21XX 3255 | ||
| 3238 | rider MACH_RIDER RIDER 3257 | ||
| 3239 | nsk330 MACH_NSK330 NSK330 3258 | ||
| 3240 | cns2133evb MACH_CNS2133EVB CNS2133EVB 3259 | ||
| 3241 | z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260 | ||
| 3242 | z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261 | ||
| 3243 | beect MACH_BEECT BEECT 3262 | ||
| 3244 | dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263 | ||
| 3245 | omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264 | ||
| 3246 | mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265 | ||
| 3247 | mione MACH_MIONE MIONE 3266 | ||
| 3248 | top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267 | ||
| 3249 | top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268 | ||
| 3250 | kingdom MACH_KINGDOM KINGDOM 3269 | ||
| 3251 | armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270 | ||
| 3252 | lq2 MACH_LQ2 LQ2 3271 | ||
| 3253 | sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272 | ||
| 3254 | mx53_loco MACH_MX53_LOCO MX53_LOCO 3273 | ||
| 3255 | acer_a8 MACH_ACER_A8 ACER_A8 3275 | ||
| 3256 | acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276 | ||
| 3257 | guppy MACH_GUPPY GUPPY 3277 | ||
| 3258 | mx61_ard MACH_MX61_ARD MX61_ARD 3278 | ||
| 3259 | tx53 MACH_TX53 TX53 3279 | ||
| 3260 | omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280 | ||
| 3261 | uemd MACH_UEMD UEMD 3281 | ||
| 3262 | ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282 | ||
| 3263 | rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283 | ||
| 3264 | nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284 | ||
| 3265 | hkdkc100 MACH_HKDKC100 HKDKC100 3285 | ||
| 3266 | ts42xx MACH_TS42XX TS42XX 3286 | ||
| 3267 | aebl MACH_AEBL AEBL 3287 | ||
| 3268 | wario MACH_WARIO WARIO 3288 | ||
| 3269 | gfs_spm MACH_GFS_SPM GFS_SPM 3289 | ||
| 3270 | cm_t3730 MACH_CM_T3730 CM_T3730 3290 | ||
| 3271 | isc3 MACH_ISC3 ISC3 3291 | ||
| 3272 | rascal MACH_RASCAL RASCAL 3292 | ||
| 3273 | hrefv60 MACH_HREFV60 HREFV60 3293 | ||
| 3274 | tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294 | ||
| 3275 | pyramid_td MACH_PYRAMID_TD PYRAMID_TD 3295 | ||
| 3276 | splendor MACH_SPLENDOR SPLENDOR 3296 | ||
| 3277 | guf_planet MACH_GUF_PLANET GUF_PLANET 3297 | ||
| 3278 | msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298 | ||
| 3279 | htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299 | ||
| 3280 | athene MACH_ATHENE ATHENE 3300 | ||
| 3281 | deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301 | ||
| 3282 | vivow_ct MACH_VIVOW_CT VIVOW_CT 3302 | ||
| 3283 | nery_1000 MACH_NERY_1000 NERY_1000 3303 | ||
| 3284 | rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304 | ||
| 3285 | nmh MACH_NMH NMH 3305 | ||
| 3286 | wn802t MACH_WN802T WN802T 3306 | ||
| 3287 | dragonet MACH_DRAGONET DRAGONET 3307 | ||
| 3288 | geneva_b MACH_GENEVA_B GENEVA_B 3308 | ||
| 3289 | at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309 | ||
| 3290 | bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310 | ||
| 3291 | bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311 | ||
| 3292 | koi MACH_KOI KOI 3312 | ||
| 3293 | ts4800 MACH_TS4800 TS4800 3313 | ||
| 3294 | tqma9263 MACH_TQMA9263 TQMA9263 3314 | ||
| 3295 | holiday MACH_HOLIDAY HOLIDAY 3315 | ||
| 3296 | dma_6410 MACH_DMA6410 DMA6410 3316 | ||
| 3297 | pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317 | ||
| 3298 | hwgw6410 MACH_HWGW6410 HWGW6410 3318 | ||
| 3299 | shenzhou MACH_SHENZHOU SHENZHOU 3319 | ||
| 3300 | cwme9210 MACH_CWME9210 CWME9210 3320 | ||
| 3301 | cwme9210js MACH_CWME9210JS CWME9210JS 3321 | ||
| 3302 | pgs_v1 MACH_PGS_SITARA PGS_SITARA 3322 | ||
| 3303 | colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323 | ||
| 3304 | w21 MACH_W21 W21 3324 | ||
| 3305 | polysat1 MACH_POLYSAT1 POLYSAT1 3325 | ||
| 3306 | dataway MACH_DATAWAY DATAWAY 3326 | ||
| 3307 | cobral138 MACH_COBRAL138 COBRAL138 3327 | ||
| 3308 | roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328 | ||
| 3309 | marvelc MACH_MARVELC MARVELC 3329 | ||
| 3310 | navefihid MACH_NAVEFIHID NAVEFIHID 3330 | ||
| 3311 | dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331 | ||
| 3312 | able MACH_ABLE ABLE 3332 | ||
| 3313 | legacy MACH_LEGACY LEGACY 3333 | ||
| 3314 | icong MACH_ICONG ICONG 3334 | ||
| 3315 | rover_g8 MACH_ROVER_G8 ROVER_G8 3335 | ||
| 3316 | t5388p MACH_T5388P T5388P 3336 | ||
| 3317 | dingo MACH_DINGO DINGO 3337 | ||
| 3318 | goflexhome MACH_GOFLEXHOME GOFLEXHOME 3338 | ||
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index 1ff9f1468c0..7dbc664eab1 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #define __BFIN_ASM_SERIAL_H__ | 10 | #define __BFIN_ASM_SERIAL_H__ |
| 11 | 11 | ||
| 12 | #include <linux/serial_core.h> | 12 | #include <linux/serial_core.h> |
| 13 | #include <linux/spinlock.h> | ||
| 13 | #include <mach/anomaly.h> | 14 | #include <mach/anomaly.h> |
| 14 | #include <mach/bfin_serial.h> | 15 | #include <mach/bfin_serial.h> |
| 15 | 16 | ||
| @@ -41,6 +42,7 @@ struct bfin_serial_port { | |||
| 41 | struct circ_buf rx_dma_buf; | 42 | struct circ_buf rx_dma_buf; |
| 42 | struct timer_list rx_dma_timer; | 43 | struct timer_list rx_dma_timer; |
| 43 | int rx_dma_nrows; | 44 | int rx_dma_nrows; |
| 45 | spinlock_t rx_lock; | ||
| 44 | unsigned int tx_dma_channel; | 46 | unsigned int tx_dma_channel; |
| 45 | unsigned int rx_dma_channel; | 47 | unsigned int rx_dma_channel; |
| 46 | struct work_struct tx_dma_workqueue; | 48 | struct work_struct tx_dma_workqueue; |
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index f745c1287f3..76eaf3883fb 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c | |||
| @@ -80,7 +80,7 @@ asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs) | |||
| 80 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 80 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
| 81 | /* FIXME M32R */ | 81 | /* FIXME M32R */ |
| 82 | #endif | 82 | #endif |
| 83 | __do_IRQ(irq); | 83 | generic_handle_irq(irq); |
| 84 | irq_exit(); | 84 | irq_exit(); |
| 85 | set_irq_regs(old_regs); | 85 | set_irq_regs(old_regs); |
| 86 | 86 | ||
diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h index 65b13128283..32198454da7 100644 --- a/arch/m68k/include/asm/string.h +++ b/arch/m68k/include/asm/string.h | |||
| @@ -99,14 +99,12 @@ static inline int strcmp(const char *cs, const char *ct) | |||
| 99 | : "+a" (cs), "+a" (ct), "=d" (res)); | 99 | : "+a" (cs), "+a" (ct), "=d" (res)); |
| 100 | return res; | 100 | return res; |
| 101 | } | 101 | } |
| 102 | #endif /* CONFIG_COLDFIRE */ | ||
| 102 | 103 | ||
| 103 | #define __HAVE_ARCH_MEMMOVE | 104 | #define __HAVE_ARCH_MEMMOVE |
| 104 | extern void *memmove(void *, const void *, __kernel_size_t); | 105 | extern void *memmove(void *, const void *, __kernel_size_t); |
| 105 | 106 | ||
| 106 | #define __HAVE_ARCH_MEMCMP | ||
| 107 | extern int memcmp(const void *, const void *, __kernel_size_t); | ||
| 108 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) | 107 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) |
| 109 | #endif /* CONFIG_COLDFIRE */ | ||
| 110 | 108 | ||
| 111 | #define __HAVE_ARCH_MEMSET | 109 | #define __HAVE_ARCH_MEMSET |
| 112 | extern void *memset(void *, int, __kernel_size_t); | 110 | extern void *memset(void *, int, __kernel_size_t); |
diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c index 4253f870e54..d399c5f2563 100644 --- a/arch/m68k/lib/string.c +++ b/arch/m68k/lib/string.c | |||
| @@ -243,14 +243,3 @@ void *memmove(void *dest, const void *src, size_t n) | |||
| 243 | return xdest; | 243 | return xdest; |
| 244 | } | 244 | } |
| 245 | EXPORT_SYMBOL(memmove); | 245 | EXPORT_SYMBOL(memmove); |
| 246 | |||
| 247 | int memcmp(const void *cs, const void *ct, size_t count) | ||
| 248 | { | ||
| 249 | const unsigned char *su1, *su2; | ||
| 250 | |||
| 251 | for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) | ||
| 252 | if (*su1 != *su2) | ||
| 253 | return *su1 < *su2 ? -1 : +1; | ||
| 254 | return 0; | ||
| 255 | } | ||
| 256 | EXPORT_SYMBOL(memcmp); | ||
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index ef332136f96..47e15ebfd89 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S | |||
| @@ -141,6 +141,12 @@ SECTIONS { | |||
| 141 | *(__param) | 141 | *(__param) |
| 142 | __stop___param = .; | 142 | __stop___param = .; |
| 143 | 143 | ||
| 144 | /* Built-in module versions */ | ||
| 145 | . = ALIGN(4) ; | ||
| 146 | __start___modver = .; | ||
| 147 | *(__modver) | ||
| 148 | __stop___modver = .; | ||
| 149 | |||
| 144 | . = ALIGN(4) ; | 150 | . = ALIGN(4) ; |
| 145 | _etext = . ; | 151 | _etext = . ; |
| 146 | } > TEXT | 152 | } > TEXT |
diff --git a/arch/m68knommu/lib/Makefile b/arch/m68knommu/lib/Makefile index d94d709665a..32d852e586d 100644 --- a/arch/m68knommu/lib/Makefile +++ b/arch/m68knommu/lib/Makefile | |||
| @@ -4,4 +4,4 @@ | |||
| 4 | 4 | ||
| 5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ | 5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ |
| 6 | muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ | 6 | muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ |
| 7 | checksum.o memcpy.o memset.o delay.o | 7 | checksum.o memcpy.o memmove.o memset.o delay.o |
diff --git a/arch/m68knommu/lib/memmove.c b/arch/m68knommu/lib/memmove.c new file mode 100644 index 00000000000..b3dcfe9dab7 --- /dev/null +++ b/arch/m68knommu/lib/memmove.c | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file COPYING in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #define __IN_STRING_C | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/string.h> | ||
| 11 | |||
| 12 | void *memmove(void *dest, const void *src, size_t n) | ||
| 13 | { | ||
| 14 | void *xdest = dest; | ||
| 15 | size_t temp; | ||
| 16 | |||
| 17 | if (!n) | ||
| 18 | return xdest; | ||
| 19 | |||
| 20 | if (dest < src) { | ||
| 21 | if ((long)dest & 1) { | ||
| 22 | char *cdest = dest; | ||
| 23 | const char *csrc = src; | ||
| 24 | *cdest++ = *csrc++; | ||
| 25 | dest = cdest; | ||
| 26 | src = csrc; | ||
| 27 | n--; | ||
| 28 | } | ||
| 29 | if (n > 2 && (long)dest & 2) { | ||
| 30 | short *sdest = dest; | ||
| 31 | const short *ssrc = src; | ||
| 32 | *sdest++ = *ssrc++; | ||
| 33 | dest = sdest; | ||
| 34 | src = ssrc; | ||
| 35 | n -= 2; | ||
| 36 | } | ||
| 37 | temp = n >> 2; | ||
| 38 | if (temp) { | ||
| 39 | long *ldest = dest; | ||
| 40 | const long *lsrc = src; | ||
| 41 | temp--; | ||
| 42 | do | ||
| 43 | *ldest++ = *lsrc++; | ||
| 44 | while (temp--); | ||
| 45 | dest = ldest; | ||
| 46 | src = lsrc; | ||
| 47 | } | ||
| 48 | if (n & 2) { | ||
| 49 | short *sdest = dest; | ||
| 50 | const short *ssrc = src; | ||
| 51 | *sdest++ = *ssrc++; | ||
| 52 | dest = sdest; | ||
| 53 | src = ssrc; | ||
| 54 | } | ||
| 55 | if (n & 1) { | ||
| 56 | char *cdest = dest; | ||
| 57 | const char *csrc = src; | ||
| 58 | *cdest = *csrc; | ||
| 59 | } | ||
| 60 | } else { | ||
| 61 | dest = (char *)dest + n; | ||
| 62 | src = (const char *)src + n; | ||
| 63 | if ((long)dest & 1) { | ||
| 64 | char *cdest = dest; | ||
| 65 | const char *csrc = src; | ||
| 66 | *--cdest = *--csrc; | ||
| 67 | dest = cdest; | ||
| 68 | src = csrc; | ||
| 69 | n--; | ||
| 70 | } | ||
| 71 | if (n > 2 && (long)dest & 2) { | ||
| 72 | short *sdest = dest; | ||
| 73 | const short *ssrc = src; | ||
| 74 | *--sdest = *--ssrc; | ||
| 75 | dest = sdest; | ||
| 76 | src = ssrc; | ||
| 77 | n -= 2; | ||
| 78 | } | ||
| 79 | temp = n >> 2; | ||
| 80 | if (temp) { | ||
| 81 | long *ldest = dest; | ||
| 82 | const long *lsrc = src; | ||
| 83 | temp--; | ||
| 84 | do | ||
| 85 | *--ldest = *--lsrc; | ||
| 86 | while (temp--); | ||
| 87 | dest = ldest; | ||
| 88 | src = lsrc; | ||
| 89 | } | ||
| 90 | if (n & 2) { | ||
| 91 | short *sdest = dest; | ||
| 92 | const short *ssrc = src; | ||
| 93 | *--sdest = *--ssrc; | ||
| 94 | dest = sdest; | ||
| 95 | src = ssrc; | ||
| 96 | } | ||
| 97 | if (n & 1) { | ||
| 98 | char *cdest = dest; | ||
| 99 | const char *csrc = src; | ||
| 100 | *--cdest = *--csrc; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | return xdest; | ||
| 104 | } | ||
| 105 | EXPORT_SYMBOL(memmove); | ||
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c index d09d9da0453..c5151f84659 100644 --- a/arch/m68knommu/platform/5249/intc2.c +++ b/arch/m68knommu/platform/5249/intc2.c | |||
| @@ -50,8 +50,10 @@ static int __init mcf_intc2_init(void) | |||
| 50 | int irq; | 50 | int irq; |
| 51 | 51 | ||
| 52 | /* GPIO interrupt sources */ | 52 | /* GPIO interrupt sources */ |
| 53 | for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) | 53 | for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) { |
| 54 | irq_desc[irq].chip = &intc2_irq_gpio_chip; | 54 | irq_desc[irq].chip = &intc2_irq_gpio_chip; |
| 55 | set_irq_handler(irq, handle_edge_irq); | ||
| 56 | } | ||
| 55 | 57 | ||
| 56 | return 0; | 58 | return 0; |
| 57 | } | 59 | } |
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S index 240a7a6e25c..676960cf022 100644 --- a/arch/m68knommu/platform/68328/entry.S +++ b/arch/m68knommu/platform/68328/entry.S | |||
| @@ -108,7 +108,6 @@ Luser_return: | |||
| 108 | movel %d1,%a2 | 108 | movel %d1,%a2 |
| 109 | 1: | 109 | 1: |
| 110 | move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ | 110 | move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ |
| 111 | andl #_TIF_WORK_MASK,%d1 | ||
| 112 | jne Lwork_to_do | 111 | jne Lwork_to_do |
| 113 | RESTORE_ALL | 112 | RESTORE_ALL |
| 114 | 113 | ||
diff --git a/arch/m68knommu/platform/68360/commproc.c b/arch/m68knommu/platform/68360/commproc.c index f27e688c404..8e4e10cc008 100644 --- a/arch/m68knommu/platform/68360/commproc.c +++ b/arch/m68knommu/platform/68360/commproc.c | |||
| @@ -210,7 +210,7 @@ void | |||
| 210 | cpm_install_handler(int vec, void (*handler)(), void *dev_id) | 210 | cpm_install_handler(int vec, void (*handler)(), void *dev_id) |
| 211 | { | 211 | { |
| 212 | 212 | ||
| 213 | request_irq(vec, handler, IRQ_FLG_LOCK, "timer", dev_id); | 213 | request_irq(vec, handler, 0, "timer", dev_id); |
| 214 | 214 | ||
| 215 | /* if (cpm_vecs[vec].handler != 0) */ | 215 | /* if (cpm_vecs[vec].handler != 0) */ |
| 216 | /* printk(KERN_INFO "CPM interrupt %x replacing %x\n", */ | 216 | /* printk(KERN_INFO "CPM interrupt %x replacing %x\n", */ |
diff --git a/arch/m68knommu/platform/68360/config.c b/arch/m68knommu/platform/68360/config.c index ac629fa3009..9dd5bca3874 100644 --- a/arch/m68knommu/platform/68360/config.c +++ b/arch/m68knommu/platform/68360/config.c | |||
| @@ -75,7 +75,7 @@ void hw_timer_init(void) | |||
| 75 | /* Set compare register 32Khz / 32 / 10 = 100 */ | 75 | /* Set compare register 32Khz / 32 / 10 = 100 */ |
| 76 | TCMP = 10; | 76 | TCMP = 10; |
| 77 | 77 | ||
| 78 | request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL); | 78 | request_irq(IRQ_MACHSPEC | 1, timer_routine, 0, "timer", NULL); |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | /* General purpose quicc timers: MC68360UM p7-20 */ | 81 | /* General purpose quicc timers: MC68360UM p7-20 */ |
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S index 8a28788c0ee..46c1b18c9dc 100644 --- a/arch/m68knommu/platform/68360/entry.S +++ b/arch/m68knommu/platform/68360/entry.S | |||
| @@ -104,7 +104,6 @@ Luser_return: | |||
| 104 | movel %d1,%a2 | 104 | movel %d1,%a2 |
| 105 | 1: | 105 | 1: |
| 106 | move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ | 106 | move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ |
| 107 | andl #_TIF_WORK_MASK,%d1 | ||
| 108 | jne Lwork_to_do | 107 | jne Lwork_to_do |
| 109 | RESTORE_ALL | 108 | RESTORE_ALL |
| 110 | 109 | ||
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index ad96ab1051f..a29041c1a8a 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c | |||
| @@ -132,8 +132,8 @@ void init_IRQ(void) | |||
| 132 | pquicc->intr_cimr = 0x00000000; | 132 | pquicc->intr_cimr = 0x00000000; |
| 133 | 133 | ||
| 134 | for (i = 0; (i < NR_IRQS); i++) { | 134 | for (i = 0; (i < NR_IRQS); i++) { |
| 135 | set_irq_chip(irq, &intc_irq_chip); | 135 | set_irq_chip(i, &intc_irq_chip); |
| 136 | set_irq_handler(irq, handle_level_irq); | 136 | set_irq_handler(i, handle_level_irq); |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| 139 | 139 | ||
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S index 4ddfc3da70d..5837cf080b6 100644 --- a/arch/m68knommu/platform/coldfire/entry.S +++ b/arch/m68knommu/platform/coldfire/entry.S | |||
| @@ -138,7 +138,6 @@ Luser_return: | |||
| 138 | andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ | 138 | andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ |
| 139 | movel %d1,%a0 | 139 | movel %d1,%a0 |
| 140 | movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ | 140 | movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ |
| 141 | andl #0xefff,%d1 | ||
| 142 | jne Lwork_to_do /* still work to do */ | 141 | jne Lwork_to_do /* still work to do */ |
| 143 | 142 | ||
| 144 | Lreturn: | 143 | Lreturn: |
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h index 5fd31905775..c4532f032b3 100644 --- a/arch/microblaze/include/asm/irqflags.h +++ b/arch/microblaze/include/asm/irqflags.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #include <asm/registers.h> | 13 | #include <asm/registers.h> |
| 14 | 14 | ||
| 15 | #ifdef CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | 15 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR |
| 16 | 16 | ||
| 17 | static inline unsigned long arch_local_irq_save(void) | 17 | static inline unsigned long arch_local_irq_save(void) |
| 18 | { | 18 | { |
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index b23f6807587..885574a73f0 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h | |||
| @@ -411,20 +411,19 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
| 411 | static inline unsigned long pte_update(pte_t *p, unsigned long clr, | 411 | static inline unsigned long pte_update(pte_t *p, unsigned long clr, |
| 412 | unsigned long set) | 412 | unsigned long set) |
| 413 | { | 413 | { |
| 414 | unsigned long old, tmp, msr; | 414 | unsigned long flags, old, tmp; |
| 415 | 415 | ||
| 416 | __asm__ __volatile__("\ | 416 | raw_local_irq_save(flags); |
| 417 | msrclr %2, 0x2\n\ | 417 | |
| 418 | nop\n\ | 418 | __asm__ __volatile__( "lw %0, %2, r0 \n" |
| 419 | lw %0, %4, r0\n\ | 419 | "andn %1, %0, %3 \n" |
| 420 | andn %1, %0, %5\n\ | 420 | "or %1, %1, %4 \n" |
| 421 | or %1, %1, %6\n\ | 421 | "sw %1, %2, r0 \n" |
| 422 | sw %1, %4, r0\n\ | 422 | : "=&r" (old), "=&r" (tmp) |
| 423 | mts rmsr, %2\n\ | 423 | : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set) |
| 424 | nop" | 424 | : "cc"); |
| 425 | : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p) | 425 | |
| 426 | : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p) | 426 | raw_local_irq_restore(flags); |
| 427 | : "cc"); | ||
| 428 | 427 | ||
| 429 | return old; | 428 | return old; |
| 430 | } | 429 | } |
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c index e01afa68273..488c1ed24e3 100644 --- a/arch/microblaze/kernel/cpu/pvr.c +++ b/arch/microblaze/kernel/cpu/pvr.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | register unsigned tmp __asm__("r3"); \ | 27 | register unsigned tmp __asm__("r3"); \ |
| 28 | tmp = 0x0; /* Prevent warning about unused */ \ | 28 | tmp = 0x0; /* Prevent warning about unused */ \ |
| 29 | __asm__ __volatile__ ( \ | 29 | __asm__ __volatile__ ( \ |
| 30 | "mfs %0, rpvr" #pvrid ";" \ | 30 | "mfs %0, rpvr" #pvrid ";" \ |
| 31 | : "=r" (tmp) : : "memory"); \ | 31 | : "=r" (tmp) : : "memory"); \ |
| 32 | val = tmp; \ | 32 | val = tmp; \ |
| 33 | } | 33 | } |
| @@ -54,7 +54,7 @@ int cpu_has_pvr(void) | |||
| 54 | if (!(flags & PVR_MSR_BIT)) | 54 | if (!(flags & PVR_MSR_BIT)) |
| 55 | return 0; | 55 | return 0; |
| 56 | 56 | ||
| 57 | get_single_pvr(0x00, pvr0); | 57 | get_single_pvr(0, pvr0); |
| 58 | pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); | 58 | pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); |
| 59 | 59 | ||
| 60 | if (pvr0 & PVR0_PVR_FULL_MASK) | 60 | if (pvr0 & PVR0_PVR_FULL_MASK) |
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index 0db20b5abb5..778a5ce2e4f 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S | |||
| @@ -62,15 +62,14 @@ real_start: | |||
| 62 | andi r1, r1, ~2 | 62 | andi r1, r1, ~2 |
| 63 | mts rmsr, r1 | 63 | mts rmsr, r1 |
| 64 | /* | 64 | /* |
| 65 | * Here is checking mechanism which check if Microblaze has msr instructions | 65 | * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc' |
| 66 | * We load msr and compare it with previous r1 value - if is the same, | 66 | * if the msrclr instruction is not enabled. We use this to detect |
| 67 | * msr instructions works if not - cpu don't have them. | 67 | * if the opcode is available, by issuing msrclr and then testing the result. |
| 68 | * r8 == 0 - msr instructions are implemented | ||
| 69 | * r8 != 0 - msr instructions are not implemented | ||
| 68 | */ | 70 | */ |
| 69 | /* r8=0 - I have msr instr, 1 - I don't have them */ | 71 | msrclr r8, 0 /* clear nothing - just read msr for test */ |
| 70 | rsubi r0, r0, 1 /* set the carry bit */ | 72 | cmpu r8, r8, r1 /* r1 must contain msr reg content */ |
| 71 | msrclr r0, 0x4 /* try to clear it */ | ||
| 72 | /* read the carry bit, r8 will be '0' if msrclr exists */ | ||
| 73 | addik r8, r0, 0 | ||
| 74 | 73 | ||
| 75 | /* r7 may point to an FDT, or there may be one linked in. | 74 | /* r7 may point to an FDT, or there may be one linked in. |
| 76 | if it's in r7, we've got to save it away ASAP. | 75 | if it's in r7, we've got to save it away ASAP. |
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index bb1558e4b28..9312fbb37ef 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
| @@ -161,11 +161,11 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
| 161 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | 161 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR |
| 162 | if (msr) | 162 | if (msr) |
| 163 | eprintk("!!!Your kernel has setup MSR instruction but " | 163 | eprintk("!!!Your kernel has setup MSR instruction but " |
| 164 | "CPU don't have it %d\n", msr); | 164 | "CPU don't have it %x\n", msr); |
| 165 | #else | 165 | #else |
| 166 | if (!msr) | 166 | if (!msr) |
| 167 | eprintk("!!!Your kernel not setup MSR instruction but " | 167 | eprintk("!!!Your kernel not setup MSR instruction but " |
| 168 | "CPU have it %d\n", msr); | 168 | "CPU have it %x\n", msr); |
| 169 | #endif | 169 | #endif |
| 170 | 170 | ||
| 171 | for (src = __ivt_start; src < __ivt_end; src++, dst++) | 171 | for (src = __ivt_start; src < __ivt_end; src++, dst++) |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 8eaed81ea64..17194fcd404 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
| @@ -40,8 +40,8 @@ | |||
| 40 | 40 | ||
| 41 | /* MAS registers bit definitions */ | 41 | /* MAS registers bit definitions */ |
| 42 | 42 | ||
| 43 | #define MAS0_TLBSEL(x) ((x << 28) & 0x30000000) | 43 | #define MAS0_TLBSEL(x) (((x) << 28) & 0x30000000) |
| 44 | #define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000) | 44 | #define MAS0_ESEL(x) (((x) << 16) & 0x0FFF0000) |
| 45 | #define MAS0_NV(x) ((x) & 0x00000FFF) | 45 | #define MAS0_NV(x) ((x) & 0x00000FFF) |
| 46 | #define MAS0_HES 0x00004000 | 46 | #define MAS0_HES 0x00004000 |
| 47 | #define MAS0_WQ_ALLWAYS 0x00000000 | 47 | #define MAS0_WQ_ALLWAYS 0x00000000 |
| @@ -50,12 +50,12 @@ | |||
| 50 | 50 | ||
| 51 | #define MAS1_VALID 0x80000000 | 51 | #define MAS1_VALID 0x80000000 |
| 52 | #define MAS1_IPROT 0x40000000 | 52 | #define MAS1_IPROT 0x40000000 |
| 53 | #define MAS1_TID(x) ((x << 16) & 0x3FFF0000) | 53 | #define MAS1_TID(x) (((x) << 16) & 0x3FFF0000) |
| 54 | #define MAS1_IND 0x00002000 | 54 | #define MAS1_IND 0x00002000 |
| 55 | #define MAS1_TS 0x00001000 | 55 | #define MAS1_TS 0x00001000 |
| 56 | #define MAS1_TSIZE_MASK 0x00000f80 | 56 | #define MAS1_TSIZE_MASK 0x00000f80 |
| 57 | #define MAS1_TSIZE_SHIFT 7 | 57 | #define MAS1_TSIZE_SHIFT 7 |
| 58 | #define MAS1_TSIZE(x) ((x << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) | 58 | #define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) |
| 59 | 59 | ||
| 60 | #define MAS2_EPN 0xFFFFF000 | 60 | #define MAS2_EPN 0xFFFFF000 |
| 61 | #define MAS2_X0 0x00000040 | 61 | #define MAS2_X0 0x00000040 |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 53b64be40eb..da4b2000854 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
| @@ -101,7 +101,7 @@ extern phys_addr_t kernstart_addr; | |||
| 101 | 101 | ||
| 102 | #ifdef CONFIG_FLATMEM | 102 | #ifdef CONFIG_FLATMEM |
| 103 | #define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT) | 103 | #define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT) |
| 104 | #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < (ARCH_PFN_OFFSET + max_mapnr)) | 104 | #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr) |
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | 107 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) |
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S index 55cba4a8a95..f8cd9fba4d3 100644 --- a/arch/powerpc/kernel/cpu_setup_6xx.S +++ b/arch/powerpc/kernel/cpu_setup_6xx.S | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <asm/mmu.h> | 18 | #include <asm/mmu.h> |
| 19 | 19 | ||
| 20 | _GLOBAL(__setup_cpu_603) | 20 | _GLOBAL(__setup_cpu_603) |
| 21 | mflr r4 | 21 | mflr r5 |
| 22 | BEGIN_MMU_FTR_SECTION | 22 | BEGIN_MMU_FTR_SECTION |
| 23 | li r10,0 | 23 | li r10,0 |
| 24 | mtspr SPRN_SPRG_603_LRU,r10 /* init SW LRU tracking */ | 24 | mtspr SPRN_SPRG_603_LRU,r10 /* init SW LRU tracking */ |
| @@ -27,60 +27,60 @@ BEGIN_FTR_SECTION | |||
| 27 | bl __init_fpu_registers | 27 | bl __init_fpu_registers |
| 28 | END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) | 28 | END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) |
| 29 | bl setup_common_caches | 29 | bl setup_common_caches |
| 30 | mtlr r4 | 30 | mtlr r5 |
| 31 | blr | 31 | blr |
| 32 | _GLOBAL(__setup_cpu_604) | 32 | _GLOBAL(__setup_cpu_604) |
| 33 | mflr r4 | 33 | mflr r5 |
| 34 | bl setup_common_caches | 34 | bl setup_common_caches |
| 35 | bl setup_604_hid0 | 35 | bl setup_604_hid0 |
| 36 | mtlr r4 | 36 | mtlr r5 |
| 37 | blr | 37 | blr |
| 38 | _GLOBAL(__setup_cpu_750) | 38 | _GLOBAL(__setup_cpu_750) |
| 39 | mflr r4 | 39 | mflr r5 |
| 40 | bl __init_fpu_registers | 40 | bl __init_fpu_registers |
| 41 | bl setup_common_caches | 41 | bl setup_common_caches |
| 42 | bl setup_750_7400_hid0 | 42 | bl setup_750_7400_hid0 |
| 43 | mtlr r4 | 43 | mtlr r5 |
| 44 | blr | 44 | blr |
| 45 | _GLOBAL(__setup_cpu_750cx) | 45 | _GLOBAL(__setup_cpu_750cx) |
| 46 | mflr r4 | 46 | mflr r5 |
| 47 | bl __init_fpu_registers | 47 | bl __init_fpu_registers |
| 48 | bl setup_common_caches | 48 | bl setup_common_caches |
| 49 | bl setup_750_7400_hid0 | 49 | bl setup_750_7400_hid0 |
| 50 | bl setup_750cx | 50 | bl setup_750cx |
| 51 | mtlr r4 | 51 | mtlr r5 |
| 52 | blr | 52 | blr |
| 53 | _GLOBAL(__setup_cpu_750fx) | 53 | _GLOBAL(__setup_cpu_750fx) |
| 54 | mflr r4 | 54 | mflr r5 |
| 55 | bl __init_fpu_registers | 55 | bl __init_fpu_registers |
| 56 | bl setup_common_caches | 56 | bl setup_common_caches |
| 57 | bl setup_750_7400_hid0 | 57 | bl setup_750_7400_hid0 |
| 58 | bl setup_750fx | 58 | bl setup_750fx |
| 59 | mtlr r4 | 59 | mtlr r5 |
| 60 | blr | 60 | blr |
| 61 | _GLOBAL(__setup_cpu_7400) | 61 | _GLOBAL(__setup_cpu_7400) |
| 62 | mflr r4 | 62 | mflr r5 |
| 63 | bl __init_fpu_registers | 63 | bl __init_fpu_registers |
| 64 | bl setup_7400_workarounds | 64 | bl setup_7400_workarounds |
| 65 | bl setup_common_caches | 65 | bl setup_common_caches |
| 66 | bl setup_750_7400_hid0 | 66 | bl setup_750_7400_hid0 |
| 67 | mtlr r4 | 67 | mtlr r5 |
| 68 | blr | 68 | blr |
| 69 | _GLOBAL(__setup_cpu_7410) | 69 | _GLOBAL(__setup_cpu_7410) |
| 70 | mflr r4 | 70 | mflr r5 |
| 71 | bl __init_fpu_registers | 71 | bl __init_fpu_registers |
| 72 | bl setup_7410_workarounds | 72 | bl setup_7410_workarounds |
| 73 | bl setup_common_caches | 73 | bl setup_common_caches |
| 74 | bl setup_750_7400_hid0 | 74 | bl setup_750_7400_hid0 |
| 75 | li r3,0 | 75 | li r3,0 |
| 76 | mtspr SPRN_L2CR2,r3 | 76 | mtspr SPRN_L2CR2,r3 |
| 77 | mtlr r4 | 77 | mtlr r5 |
| 78 | blr | 78 | blr |
| 79 | _GLOBAL(__setup_cpu_745x) | 79 | _GLOBAL(__setup_cpu_745x) |
| 80 | mflr r4 | 80 | mflr r5 |
| 81 | bl setup_common_caches | 81 | bl setup_common_caches |
| 82 | bl setup_745x_specifics | 82 | bl setup_745x_specifics |
| 83 | mtlr r4 | 83 | mtlr r5 |
| 84 | blr | 84 | blr |
| 85 | 85 | ||
| 86 | /* Enable caches for 603's, 604, 750 & 7400 */ | 86 | /* Enable caches for 603's, 604, 750 & 7400 */ |
| @@ -194,10 +194,10 @@ setup_750cx: | |||
| 194 | cror 4*cr0+eq,4*cr0+eq,4*cr1+eq | 194 | cror 4*cr0+eq,4*cr0+eq,4*cr1+eq |
| 195 | cror 4*cr0+eq,4*cr0+eq,4*cr2+eq | 195 | cror 4*cr0+eq,4*cr0+eq,4*cr2+eq |
| 196 | bnelr | 196 | bnelr |
| 197 | lwz r6,CPU_SPEC_FEATURES(r5) | 197 | lwz r6,CPU_SPEC_FEATURES(r4) |
| 198 | li r7,CPU_FTR_CAN_NAP | 198 | li r7,CPU_FTR_CAN_NAP |
| 199 | andc r6,r6,r7 | 199 | andc r6,r6,r7 |
| 200 | stw r6,CPU_SPEC_FEATURES(r5) | 200 | stw r6,CPU_SPEC_FEATURES(r4) |
| 201 | blr | 201 | blr |
| 202 | 202 | ||
| 203 | /* 750fx specific | 203 | /* 750fx specific |
| @@ -225,12 +225,12 @@ BEGIN_FTR_SECTION | |||
| 225 | andis. r11,r11,L3CR_L3E@h | 225 | andis. r11,r11,L3CR_L3E@h |
| 226 | beq 1f | 226 | beq 1f |
| 227 | END_FTR_SECTION_IFSET(CPU_FTR_L3CR) | 227 | END_FTR_SECTION_IFSET(CPU_FTR_L3CR) |
| 228 | lwz r6,CPU_SPEC_FEATURES(r5) | 228 | lwz r6,CPU_SPEC_FEATURES(r4) |
| 229 | andi. r0,r6,CPU_FTR_L3_DISABLE_NAP | 229 | andi. r0,r6,CPU_FTR_L3_DISABLE_NAP |
| 230 | beq 1f | 230 | beq 1f |
| 231 | li r7,CPU_FTR_CAN_NAP | 231 | li r7,CPU_FTR_CAN_NAP |
| 232 | andc r6,r6,r7 | 232 | andc r6,r6,r7 |
| 233 | stw r6,CPU_SPEC_FEATURES(r5) | 233 | stw r6,CPU_SPEC_FEATURES(r4) |
| 234 | 1: | 234 | 1: |
| 235 | mfspr r11,SPRN_HID0 | 235 | mfspr r11,SPRN_HID0 |
| 236 | 236 | ||
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 8d74a24c550..e8e915ce3d8 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -2076,8 +2076,8 @@ static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s) | |||
| 2076 | * pointer on ppc64 and booke as we are running at 0 in real mode | 2076 | * pointer on ppc64 and booke as we are running at 0 in real mode |
| 2077 | * on ppc64 and reloc_offset is always 0 on booke. | 2077 | * on ppc64 and reloc_offset is always 0 on booke. |
| 2078 | */ | 2078 | */ |
| 2079 | if (s->cpu_setup) { | 2079 | if (t->cpu_setup) { |
| 2080 | s->cpu_setup(offset, s); | 2080 | t->cpu_setup(offset, t); |
| 2081 | } | 2081 | } |
| 2082 | #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ | 2082 | #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ |
| 2083 | } | 2083 | } |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index bf5cb91f07d..fd481232957 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -186,7 +186,7 @@ static void unmap_cpu_from_node(unsigned long cpu) | |||
| 186 | dbg("removing cpu %lu from node %d\n", cpu, node); | 186 | dbg("removing cpu %lu from node %d\n", cpu, node); |
| 187 | 187 | ||
| 188 | if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) { | 188 | if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) { |
| 189 | cpumask_set_cpu(cpu, node_to_cpumask_map[node]); | 189 | cpumask_clear_cpu(cpu, node_to_cpumask_map[node]); |
| 190 | } else { | 190 | } else { |
| 191 | printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n", | 191 | printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n", |
| 192 | cpu, node); | 192 | cpu, node); |
| @@ -1289,10 +1289,9 @@ u64 memory_hotplug_max(void) | |||
| 1289 | } | 1289 | } |
| 1290 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 1290 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
| 1291 | 1291 | ||
| 1292 | /* Vrtual Processor Home Node (VPHN) support */ | 1292 | /* Virtual Processor Home Node (VPHN) support */ |
| 1293 | #ifdef CONFIG_PPC_SPLPAR | 1293 | #ifdef CONFIG_PPC_SPLPAR |
| 1294 | #define VPHN_NR_CHANGE_CTRS (8) | 1294 | static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS]; |
| 1295 | static u8 vphn_cpu_change_counts[NR_CPUS][VPHN_NR_CHANGE_CTRS]; | ||
| 1296 | static cpumask_t cpu_associativity_changes_mask; | 1295 | static cpumask_t cpu_associativity_changes_mask; |
| 1297 | static int vphn_enabled; | 1296 | static int vphn_enabled; |
| 1298 | static void set_topology_timer(void); | 1297 | static void set_topology_timer(void); |
| @@ -1303,16 +1302,18 @@ static void set_topology_timer(void); | |||
| 1303 | */ | 1302 | */ |
| 1304 | static void setup_cpu_associativity_change_counters(void) | 1303 | static void setup_cpu_associativity_change_counters(void) |
| 1305 | { | 1304 | { |
| 1306 | int cpu = 0; | 1305 | int cpu; |
| 1306 | |||
| 1307 | /* The VPHN feature supports a maximum of 8 reference points */ | ||
| 1308 | BUILD_BUG_ON(MAX_DISTANCE_REF_POINTS > 8); | ||
| 1307 | 1309 | ||
| 1308 | for_each_possible_cpu(cpu) { | 1310 | for_each_possible_cpu(cpu) { |
| 1309 | int i = 0; | 1311 | int i; |
| 1310 | u8 *counts = vphn_cpu_change_counts[cpu]; | 1312 | u8 *counts = vphn_cpu_change_counts[cpu]; |
| 1311 | volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; | 1313 | volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; |
| 1312 | 1314 | ||
| 1313 | for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) { | 1315 | for (i = 0; i < distance_ref_points_depth; i++) |
| 1314 | counts[i] = hypervisor_counts[i]; | 1316 | counts[i] = hypervisor_counts[i]; |
| 1315 | } | ||
| 1316 | } | 1317 | } |
| 1317 | } | 1318 | } |
| 1318 | 1319 | ||
| @@ -1329,7 +1330,7 @@ static void setup_cpu_associativity_change_counters(void) | |||
| 1329 | */ | 1330 | */ |
| 1330 | static int update_cpu_associativity_changes_mask(void) | 1331 | static int update_cpu_associativity_changes_mask(void) |
| 1331 | { | 1332 | { |
| 1332 | int cpu = 0, nr_cpus = 0; | 1333 | int cpu, nr_cpus = 0; |
| 1333 | cpumask_t *changes = &cpu_associativity_changes_mask; | 1334 | cpumask_t *changes = &cpu_associativity_changes_mask; |
| 1334 | 1335 | ||
| 1335 | cpumask_clear(changes); | 1336 | cpumask_clear(changes); |
| @@ -1339,8 +1340,8 @@ static int update_cpu_associativity_changes_mask(void) | |||
| 1339 | u8 *counts = vphn_cpu_change_counts[cpu]; | 1340 | u8 *counts = vphn_cpu_change_counts[cpu]; |
| 1340 | volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; | 1341 | volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; |
| 1341 | 1342 | ||
| 1342 | for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) { | 1343 | for (i = 0; i < distance_ref_points_depth; i++) { |
| 1343 | if (hypervisor_counts[i] > counts[i]) { | 1344 | if (hypervisor_counts[i] != counts[i]) { |
| 1344 | counts[i] = hypervisor_counts[i]; | 1345 | counts[i] = hypervisor_counts[i]; |
| 1345 | changed = 1; | 1346 | changed = 1; |
| 1346 | } | 1347 | } |
| @@ -1354,8 +1355,11 @@ static int update_cpu_associativity_changes_mask(void) | |||
| 1354 | return nr_cpus; | 1355 | return nr_cpus; |
| 1355 | } | 1356 | } |
| 1356 | 1357 | ||
| 1357 | /* 6 64-bit registers unpacked into 12 32-bit associativity values */ | 1358 | /* |
| 1358 | #define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32)) | 1359 | * 6 64-bit registers unpacked into 12 32-bit associativity values. To form |
| 1360 | * the complete property we have to add the length in the first cell. | ||
| 1361 | */ | ||
| 1362 | #define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32) + 1) | ||
| 1359 | 1363 | ||
| 1360 | /* | 1364 | /* |
| 1361 | * Convert the associativity domain numbers returned from the hypervisor | 1365 | * Convert the associativity domain numbers returned from the hypervisor |
| @@ -1363,15 +1367,14 @@ static int update_cpu_associativity_changes_mask(void) | |||
| 1363 | */ | 1367 | */ |
| 1364 | static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) | 1368 | static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) |
| 1365 | { | 1369 | { |
| 1366 | int i = 0; | 1370 | int i, nr_assoc_doms = 0; |
| 1367 | int nr_assoc_doms = 0; | ||
| 1368 | const u16 *field = (const u16*) packed; | 1371 | const u16 *field = (const u16*) packed; |
| 1369 | 1372 | ||
| 1370 | #define VPHN_FIELD_UNUSED (0xffff) | 1373 | #define VPHN_FIELD_UNUSED (0xffff) |
| 1371 | #define VPHN_FIELD_MSB (0x8000) | 1374 | #define VPHN_FIELD_MSB (0x8000) |
| 1372 | #define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) | 1375 | #define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) |
| 1373 | 1376 | ||
| 1374 | for (i = 0; i < VPHN_ASSOC_BUFSIZE; i++) { | 1377 | for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) { |
| 1375 | if (*field == VPHN_FIELD_UNUSED) { | 1378 | if (*field == VPHN_FIELD_UNUSED) { |
| 1376 | /* All significant fields processed, and remaining | 1379 | /* All significant fields processed, and remaining |
| 1377 | * fields contain the reserved value of all 1's. | 1380 | * fields contain the reserved value of all 1's. |
| @@ -1379,14 +1382,12 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) | |||
| 1379 | */ | 1382 | */ |
| 1380 | unpacked[i] = *((u32*)field); | 1383 | unpacked[i] = *((u32*)field); |
| 1381 | field += 2; | 1384 | field += 2; |
| 1382 | } | 1385 | } else if (*field & VPHN_FIELD_MSB) { |
| 1383 | else if (*field & VPHN_FIELD_MSB) { | ||
| 1384 | /* Data is in the lower 15 bits of this field */ | 1386 | /* Data is in the lower 15 bits of this field */ |
| 1385 | unpacked[i] = *field & VPHN_FIELD_MASK; | 1387 | unpacked[i] = *field & VPHN_FIELD_MASK; |
| 1386 | field++; | 1388 | field++; |
| 1387 | nr_assoc_doms++; | 1389 | nr_assoc_doms++; |
| 1388 | } | 1390 | } else { |
| 1389 | else { | ||
| 1390 | /* Data is in the lower 15 bits of this field | 1391 | /* Data is in the lower 15 bits of this field |
| 1391 | * concatenated with the next 16 bit field | 1392 | * concatenated with the next 16 bit field |
| 1392 | */ | 1393 | */ |
| @@ -1396,6 +1397,9 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) | |||
| 1396 | } | 1397 | } |
| 1397 | } | 1398 | } |
| 1398 | 1399 | ||
| 1400 | /* The first cell contains the length of the property */ | ||
| 1401 | unpacked[0] = nr_assoc_doms; | ||
| 1402 | |||
| 1399 | return nr_assoc_doms; | 1403 | return nr_assoc_doms; |
| 1400 | } | 1404 | } |
| 1401 | 1405 | ||
| @@ -1405,7 +1409,7 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) | |||
| 1405 | */ | 1409 | */ |
| 1406 | static long hcall_vphn(unsigned long cpu, unsigned int *associativity) | 1410 | static long hcall_vphn(unsigned long cpu, unsigned int *associativity) |
| 1407 | { | 1411 | { |
| 1408 | long rc = 0; | 1412 | long rc; |
| 1409 | long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; | 1413 | long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; |
| 1410 | u64 flags = 1; | 1414 | u64 flags = 1; |
| 1411 | int hwcpu = get_hard_smp_processor_id(cpu); | 1415 | int hwcpu = get_hard_smp_processor_id(cpu); |
| @@ -1419,7 +1423,7 @@ static long hcall_vphn(unsigned long cpu, unsigned int *associativity) | |||
| 1419 | static long vphn_get_associativity(unsigned long cpu, | 1423 | static long vphn_get_associativity(unsigned long cpu, |
| 1420 | unsigned int *associativity) | 1424 | unsigned int *associativity) |
| 1421 | { | 1425 | { |
| 1422 | long rc = 0; | 1426 | long rc; |
| 1423 | 1427 | ||
| 1424 | rc = hcall_vphn(cpu, associativity); | 1428 | rc = hcall_vphn(cpu, associativity); |
| 1425 | 1429 | ||
| @@ -1445,9 +1449,9 @@ static long vphn_get_associativity(unsigned long cpu, | |||
| 1445 | */ | 1449 | */ |
| 1446 | int arch_update_cpu_topology(void) | 1450 | int arch_update_cpu_topology(void) |
| 1447 | { | 1451 | { |
| 1448 | int cpu = 0, nid = 0, old_nid = 0; | 1452 | int cpu, nid, old_nid; |
| 1449 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; | 1453 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; |
| 1450 | struct sys_device *sysdev = NULL; | 1454 | struct sys_device *sysdev; |
| 1451 | 1455 | ||
| 1452 | for_each_cpu_mask(cpu, cpu_associativity_changes_mask) { | 1456 | for_each_cpu_mask(cpu, cpu_associativity_changes_mask) { |
| 1453 | vphn_get_associativity(cpu, associativity); | 1457 | vphn_get_associativity(cpu, associativity); |
| @@ -1512,7 +1516,8 @@ int start_topology_update(void) | |||
| 1512 | { | 1516 | { |
| 1513 | int rc = 0; | 1517 | int rc = 0; |
| 1514 | 1518 | ||
| 1515 | if (firmware_has_feature(FW_FEATURE_VPHN)) { | 1519 | if (firmware_has_feature(FW_FEATURE_VPHN) && |
| 1520 | get_lppaca()->shared_proc) { | ||
| 1516 | vphn_enabled = 1; | 1521 | vphn_enabled = 1; |
| 1517 | setup_cpu_associativity_change_counters(); | 1522 | setup_cpu_associativity_change_counters(); |
| 1518 | init_timer_deferrable(&topology_timer); | 1523 | init_timer_deferrable(&topology_timer); |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 5d3ea9f60dd..ca5d5898d32 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
| @@ -713,6 +713,13 @@ EXPORT_SYMBOL(arch_free_page); | |||
| 713 | /* NB: reg/unreg are called while guarded with the tracepoints_mutex */ | 713 | /* NB: reg/unreg are called while guarded with the tracepoints_mutex */ |
| 714 | extern long hcall_tracepoint_refcount; | 714 | extern long hcall_tracepoint_refcount; |
| 715 | 715 | ||
| 716 | /* | ||
| 717 | * Since the tracing code might execute hcalls we need to guard against | ||
| 718 | * recursion. One example of this are spinlocks calling H_YIELD on | ||
| 719 | * shared processor partitions. | ||
| 720 | */ | ||
| 721 | static DEFINE_PER_CPU(unsigned int, hcall_trace_depth); | ||
| 722 | |||
| 716 | void hcall_tracepoint_regfunc(void) | 723 | void hcall_tracepoint_regfunc(void) |
| 717 | { | 724 | { |
| 718 | hcall_tracepoint_refcount++; | 725 | hcall_tracepoint_refcount++; |
| @@ -725,12 +732,42 @@ void hcall_tracepoint_unregfunc(void) | |||
| 725 | 732 | ||
| 726 | void __trace_hcall_entry(unsigned long opcode, unsigned long *args) | 733 | void __trace_hcall_entry(unsigned long opcode, unsigned long *args) |
| 727 | { | 734 | { |
| 735 | unsigned long flags; | ||
| 736 | unsigned int *depth; | ||
| 737 | |||
| 738 | local_irq_save(flags); | ||
| 739 | |||
| 740 | depth = &__get_cpu_var(hcall_trace_depth); | ||
| 741 | |||
| 742 | if (*depth) | ||
| 743 | goto out; | ||
| 744 | |||
| 745 | (*depth)++; | ||
| 728 | trace_hcall_entry(opcode, args); | 746 | trace_hcall_entry(opcode, args); |
| 747 | (*depth)--; | ||
| 748 | |||
| 749 | out: | ||
| 750 | local_irq_restore(flags); | ||
| 729 | } | 751 | } |
| 730 | 752 | ||
| 731 | void __trace_hcall_exit(long opcode, unsigned long retval, | 753 | void __trace_hcall_exit(long opcode, unsigned long retval, |
| 732 | unsigned long *retbuf) | 754 | unsigned long *retbuf) |
| 733 | { | 755 | { |
| 756 | unsigned long flags; | ||
| 757 | unsigned int *depth; | ||
| 758 | |||
| 759 | local_irq_save(flags); | ||
| 760 | |||
| 761 | depth = &__get_cpu_var(hcall_trace_depth); | ||
| 762 | |||
| 763 | if (*depth) | ||
| 764 | goto out; | ||
| 765 | |||
| 766 | (*depth)++; | ||
| 734 | trace_hcall_exit(opcode, retval, retbuf); | 767 | trace_hcall_exit(opcode, retval, retbuf); |
| 768 | (*depth)--; | ||
| 769 | |||
| 770 | out: | ||
| 771 | local_irq_restore(flags); | ||
| 735 | } | 772 | } |
| 736 | #endif | 773 | #endif |
diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c index f42dbabc0d3..48884f89ab9 100644 --- a/arch/s390/crypto/sha_common.c +++ b/arch/s390/crypto/sha_common.c | |||
| @@ -38,6 +38,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) | |||
| 38 | BUG_ON(ret != bsize); | 38 | BUG_ON(ret != bsize); |
| 39 | data += bsize - index; | 39 | data += bsize - index; |
| 40 | len -= bsize - index; | 40 | len -= bsize - index; |
| 41 | index = 0; | ||
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | /* process as many blocks as possible */ | 44 | /* process as many blocks as possible */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index bf3de04170a..2c79b641627 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -148,11 +148,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | |||
| 148 | */ | 148 | */ |
| 149 | extern unsigned long thread_saved_pc(struct task_struct *t); | 149 | extern unsigned long thread_saved_pc(struct task_struct *t); |
| 150 | 150 | ||
| 151 | /* | ||
| 152 | * Print register of task into buffer. Used in fs/proc/array.c. | ||
| 153 | */ | ||
| 154 | extern void task_show_regs(struct seq_file *m, struct task_struct *task); | ||
| 155 | |||
| 156 | extern void show_code(struct pt_regs *regs); | 151 | extern void show_code(struct pt_regs *regs); |
| 157 | 152 | ||
| 158 | unsigned long get_wchan(struct task_struct *p); | 153 | unsigned long get_wchan(struct task_struct *p); |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 5eb78dd584c..b5a4a739b47 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
| @@ -237,43 +237,6 @@ void show_regs(struct pt_regs *regs) | |||
| 237 | show_last_breaking_event(regs); | 237 | show_last_breaking_event(regs); |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | /* This is called from fs/proc/array.c */ | ||
| 241 | void task_show_regs(struct seq_file *m, struct task_struct *task) | ||
| 242 | { | ||
| 243 | struct pt_regs *regs; | ||
| 244 | |||
| 245 | regs = task_pt_regs(task); | ||
| 246 | seq_printf(m, "task: %p, ksp: %p\n", | ||
| 247 | task, (void *)task->thread.ksp); | ||
| 248 | seq_printf(m, "User PSW : %p %p\n", | ||
| 249 | (void *) regs->psw.mask, (void *)regs->psw.addr); | ||
| 250 | |||
| 251 | seq_printf(m, "User GPRS: " FOURLONG, | ||
| 252 | regs->gprs[0], regs->gprs[1], | ||
| 253 | regs->gprs[2], regs->gprs[3]); | ||
| 254 | seq_printf(m, " " FOURLONG, | ||
| 255 | regs->gprs[4], regs->gprs[5], | ||
| 256 | regs->gprs[6], regs->gprs[7]); | ||
| 257 | seq_printf(m, " " FOURLONG, | ||
| 258 | regs->gprs[8], regs->gprs[9], | ||
| 259 | regs->gprs[10], regs->gprs[11]); | ||
| 260 | seq_printf(m, " " FOURLONG, | ||
| 261 | regs->gprs[12], regs->gprs[13], | ||
| 262 | regs->gprs[14], regs->gprs[15]); | ||
| 263 | seq_printf(m, "User ACRS: %08x %08x %08x %08x\n", | ||
| 264 | task->thread.acrs[0], task->thread.acrs[1], | ||
| 265 | task->thread.acrs[2], task->thread.acrs[3]); | ||
| 266 | seq_printf(m, " %08x %08x %08x %08x\n", | ||
| 267 | task->thread.acrs[4], task->thread.acrs[5], | ||
| 268 | task->thread.acrs[6], task->thread.acrs[7]); | ||
| 269 | seq_printf(m, " %08x %08x %08x %08x\n", | ||
| 270 | task->thread.acrs[8], task->thread.acrs[9], | ||
| 271 | task->thread.acrs[10], task->thread.acrs[11]); | ||
| 272 | seq_printf(m, " %08x %08x %08x %08x\n", | ||
| 273 | task->thread.acrs[12], task->thread.acrs[13], | ||
| 274 | task->thread.acrs[14], task->thread.acrs[15]); | ||
| 275 | } | ||
| 276 | |||
| 277 | static DEFINE_SPINLOCK(die_lock); | 240 | static DEFINE_SPINLOCK(die_lock); |
| 278 | 241 | ||
| 279 | void die(const char * str, struct pt_regs * regs, long err) | 242 | void die(const char * str, struct pt_regs * regs, long err) |
diff --git a/arch/sparc/include/asm/pcr.h b/arch/sparc/include/asm/pcr.h index a2f5c61f924..843e4faf6a5 100644 --- a/arch/sparc/include/asm/pcr.h +++ b/arch/sparc/include/asm/pcr.h | |||
| @@ -43,4 +43,6 @@ static inline u64 picl_value(unsigned int nmi_hz) | |||
| 43 | 43 | ||
| 44 | extern u64 pcr_enable; | 44 | extern u64 pcr_enable; |
| 45 | 45 | ||
| 46 | extern int pcr_arch_init(void); | ||
| 47 | |||
| 46 | #endif /* __PCR_H */ | 48 | #endif /* __PCR_H */ |
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 47977a77f6c..72509d0e34b 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c | |||
| @@ -255,10 +255,9 @@ static inline iopte_t *alloc_npages(struct device *dev, struct iommu *iommu, | |||
| 255 | static int iommu_alloc_ctx(struct iommu *iommu) | 255 | static int iommu_alloc_ctx(struct iommu *iommu) |
| 256 | { | 256 | { |
| 257 | int lowest = iommu->ctx_lowest_free; | 257 | int lowest = iommu->ctx_lowest_free; |
| 258 | int sz = IOMMU_NUM_CTXS - lowest; | 258 | int n = find_next_zero_bit(iommu->ctx_bitmap, IOMMU_NUM_CTXS, lowest); |
| 259 | int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); | ||
| 260 | 259 | ||
| 261 | if (unlikely(n == sz)) { | 260 | if (unlikely(n == IOMMU_NUM_CTXS)) { |
| 262 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); | 261 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); |
| 263 | if (unlikely(n == lowest)) { | 262 | if (unlikely(n == lowest)) { |
| 264 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); | 263 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); |
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index ae96cf52a95..7c2ced612b8 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c | |||
| @@ -167,5 +167,3 @@ out_unregister: | |||
| 167 | unregister_perf_hsvc(); | 167 | unregister_perf_hsvc(); |
| 168 | return err; | 168 | return err; |
| 169 | } | 169 | } |
| 170 | |||
| 171 | early_initcall(pcr_arch_init); | ||
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index b6a2b8f4704..555a76d1f4a 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #include <asm/mdesc.h> | 49 | #include <asm/mdesc.h> |
| 50 | #include <asm/ldc.h> | 50 | #include <asm/ldc.h> |
| 51 | #include <asm/hypervisor.h> | 51 | #include <asm/hypervisor.h> |
| 52 | #include <asm/pcr.h> | ||
| 52 | 53 | ||
| 53 | #include "cpumap.h" | 54 | #include "cpumap.h" |
| 54 | 55 | ||
| @@ -1358,6 +1359,7 @@ void __cpu_die(unsigned int cpu) | |||
| 1358 | 1359 | ||
| 1359 | void __init smp_cpus_done(unsigned int max_cpus) | 1360 | void __init smp_cpus_done(unsigned int max_cpus) |
| 1360 | { | 1361 | { |
| 1362 | pcr_arch_init(); | ||
| 1361 | } | 1363 | } |
| 1362 | 1364 | ||
| 1363 | void smp_send_reschedule(int cpu) | 1365 | void smp_send_reschedule(int cpu) |
diff --git a/arch/sparc/kernel/una_asm_32.S b/arch/sparc/kernel/una_asm_32.S index 8cc03458eb7..8f096e84a93 100644 --- a/arch/sparc/kernel/una_asm_32.S +++ b/arch/sparc/kernel/una_asm_32.S | |||
| @@ -24,9 +24,9 @@ retl_efault: | |||
| 24 | .globl __do_int_store | 24 | .globl __do_int_store |
| 25 | __do_int_store: | 25 | __do_int_store: |
| 26 | ld [%o2], %g1 | 26 | ld [%o2], %g1 |
| 27 | cmp %1, 2 | 27 | cmp %o1, 2 |
| 28 | be 2f | 28 | be 2f |
| 29 | cmp %1, 4 | 29 | cmp %o1, 4 |
| 30 | be 1f | 30 | be 1f |
| 31 | srl %g1, 24, %g2 | 31 | srl %g1, 24, %g2 |
| 32 | srl %g1, 16, %g7 | 32 | srl %g1, 16, %g7 |
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c index 764b3eb7b60..48d00e72ce1 100644 --- a/arch/sparc/lib/bitext.c +++ b/arch/sparc/lib/bitext.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
| 13 | #include <linux/bitops.h> | 13 | #include <linux/bitmap.h> |
| 14 | 14 | ||
| 15 | #include <asm/bitext.h> | 15 | #include <asm/bitext.h> |
| 16 | 16 | ||
| @@ -80,8 +80,7 @@ int bit_map_string_get(struct bit_map *t, int len, int align) | |||
| 80 | while (test_bit(offset + i, t->map) == 0) { | 80 | while (test_bit(offset + i, t->map) == 0) { |
| 81 | i++; | 81 | i++; |
| 82 | if (i == len) { | 82 | if (i == len) { |
| 83 | for (i = 0; i < len; i++) | 83 | bitmap_set(t->map, offset, len); |
| 84 | __set_bit(offset + i, t->map); | ||
| 85 | if (offset == t->first_free) | 84 | if (offset == t->first_free) |
| 86 | t->first_free = find_next_zero_bit | 85 | t->first_free = find_next_zero_bit |
| 87 | (t->map, t->size, | 86 | (t->map, t->size, |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 5e3969c36d7..3c896946f4c 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -233,6 +233,7 @@ extern void sync_Arb_IDs(void); | |||
| 233 | extern void init_bsp_APIC(void); | 233 | extern void init_bsp_APIC(void); |
| 234 | extern void setup_local_APIC(void); | 234 | extern void setup_local_APIC(void); |
| 235 | extern void end_local_APIC_setup(void); | 235 | extern void end_local_APIC_setup(void); |
| 236 | extern void bsp_end_local_APIC_setup(void); | ||
| 236 | extern void init_apic_mappings(void); | 237 | extern void init_apic_mappings(void); |
| 237 | void register_lapic_address(unsigned long address); | 238 | void register_lapic_address(unsigned long address); |
| 238 | extern void setup_boot_APIC_clock(void); | 239 | extern void setup_boot_APIC_clock(void); |
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 6e6e7558e70..4564c8e28a3 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h | |||
| @@ -32,6 +32,6 @@ extern void arch_unregister_cpu(int); | |||
| 32 | 32 | ||
| 33 | DECLARE_PER_CPU(int, cpu_state); | 33 | DECLARE_PER_CPU(int, cpu_state); |
| 34 | 34 | ||
| 35 | int __cpuinit mwait_usable(const struct cpuinfo_x86 *); | 35 | int mwait_usable(const struct cpuinfo_x86 *); |
| 36 | 36 | ||
| 37 | #endif /* _ASM_X86_CPU_H */ | 37 | #endif /* _ASM_X86_CPU_H */ |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 4a2d4e0c18d..8b5393ec108 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
| @@ -36,8 +36,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
| 36 | unsigned cpu = smp_processor_id(); | 36 | unsigned cpu = smp_processor_id(); |
| 37 | 37 | ||
| 38 | if (likely(prev != next)) { | 38 | if (likely(prev != next)) { |
| 39 | /* stop flush ipis for the previous mm */ | ||
| 40 | cpumask_clear_cpu(cpu, mm_cpumask(prev)); | ||
| 41 | #ifdef CONFIG_SMP | 39 | #ifdef CONFIG_SMP |
| 42 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); | 40 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
| 43 | percpu_write(cpu_tlbstate.active_mm, next); | 41 | percpu_write(cpu_tlbstate.active_mm, next); |
| @@ -47,6 +45,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
| 47 | /* Re-load page tables */ | 45 | /* Re-load page tables */ |
| 48 | load_cr3(next->pgd); | 46 | load_cr3(next->pgd); |
| 49 | 47 | ||
| 48 | /* stop flush ipis for the previous mm */ | ||
| 49 | cpumask_clear_cpu(cpu, mm_cpumask(prev)); | ||
| 50 | |||
| 50 | /* | 51 | /* |
| 51 | * load the LDT, if the LDT is different: | 52 | * load the LDT, if the LDT is different: |
| 52 | */ | 53 | */ |
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 4c2f63c7fc1..1f469513677 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
| @@ -40,10 +40,7 @@ DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid); | |||
| 40 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 40 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); |
| 41 | 41 | ||
| 42 | /* Static state in head.S used to set up a CPU */ | 42 | /* Static state in head.S used to set up a CPU */ |
| 43 | extern struct { | 43 | extern unsigned long stack_start; /* Initial stack pointer address */ |
| 44 | void *sp; | ||
| 45 | unsigned short ss; | ||
| 46 | } stack_start; | ||
| 47 | 44 | ||
| 48 | struct smp_ops { | 45 | struct smp_ops { |
| 49 | void (*smp_prepare_boot_cpu)(void); | 46 | void (*smp_prepare_boot_cpu)(void); |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 69fd72aa559..68d1537b8c8 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
| @@ -12,10 +12,8 @@ | |||
| 12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
| 13 | #include <asm/segment.h> | 13 | #include <asm/segment.h> |
| 14 | #include <asm/desc.h> | 14 | #include <asm/desc.h> |
| 15 | |||
| 16 | #ifdef CONFIG_X86_32 | ||
| 17 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
| 18 | #endif | 16 | #include <asm/cacheflush.h> |
| 19 | 17 | ||
| 20 | #include "realmode/wakeup.h" | 18 | #include "realmode/wakeup.h" |
| 21 | #include "sleep.h" | 19 | #include "sleep.h" |
| @@ -100,7 +98,7 @@ int acpi_save_state_mem(void) | |||
| 100 | #else /* CONFIG_64BIT */ | 98 | #else /* CONFIG_64BIT */ |
| 101 | header->trampoline_segment = setup_trampoline() >> 4; | 99 | header->trampoline_segment = setup_trampoline() >> 4; |
| 102 | #ifdef CONFIG_SMP | 100 | #ifdef CONFIG_SMP |
| 103 | stack_start.sp = temp_stack + sizeof(temp_stack); | 101 | stack_start = (unsigned long)temp_stack + sizeof(temp_stack); |
| 104 | early_gdt_descr.address = | 102 | early_gdt_descr.address = |
| 105 | (unsigned long)get_cpu_gdt_table(smp_processor_id()); | 103 | (unsigned long)get_cpu_gdt_table(smp_processor_id()); |
| 106 | initial_gs = per_cpu_offset(smp_processor_id()); | 104 | initial_gs = per_cpu_offset(smp_processor_id()); |
| @@ -149,6 +147,15 @@ void __init acpi_reserve_wakeup_memory(void) | |||
| 149 | memblock_x86_reserve_range(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); | 147 | memblock_x86_reserve_range(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); |
| 150 | } | 148 | } |
| 151 | 149 | ||
| 150 | int __init acpi_configure_wakeup_memory(void) | ||
| 151 | { | ||
| 152 | if (acpi_realmode) | ||
| 153 | set_memory_x(acpi_realmode, WAKEUP_SIZE >> PAGE_SHIFT); | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | arch_initcall(acpi_configure_wakeup_memory); | ||
| 158 | |||
| 152 | 159 | ||
| 153 | static int __init acpi_sleep_setup(char *str) | 160 | static int __init acpi_sleep_setup(char *str) |
| 154 | { | 161 | { |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 123608531c8..7038b95d363 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
| @@ -671,7 +671,7 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n) | |||
| 671 | 671 | ||
| 672 | atomic_set(&stop_machine_first, 1); | 672 | atomic_set(&stop_machine_first, 1); |
| 673 | wrote_text = 0; | 673 | wrote_text = 0; |
| 674 | stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); | 674 | __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); |
| 675 | } | 675 | } |
| 676 | 676 | ||
| 677 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) | 677 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 06c196d7e59..76b96d74978 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -1381,12 +1381,17 @@ void __cpuinit end_local_APIC_setup(void) | |||
| 1381 | #endif | 1381 | #endif |
| 1382 | 1382 | ||
| 1383 | apic_pm_activate(); | 1383 | apic_pm_activate(); |
| 1384 | } | ||
| 1385 | |||
| 1386 | void __init bsp_end_local_APIC_setup(void) | ||
| 1387 | { | ||
| 1388 | end_local_APIC_setup(); | ||
| 1384 | 1389 | ||
| 1385 | /* | 1390 | /* |
| 1386 | * Now that local APIC setup is completed for BP, configure the fault | 1391 | * Now that local APIC setup is completed for BP, configure the fault |
| 1387 | * handling for interrupt remapping. | 1392 | * handling for interrupt remapping. |
| 1388 | */ | 1393 | */ |
| 1389 | if (!smp_processor_id() && intr_remapping_enabled) | 1394 | if (intr_remapping_enabled) |
| 1390 | enable_drhd_fault_handling(); | 1395 | enable_drhd_fault_handling(); |
| 1391 | 1396 | ||
| 1392 | } | 1397 | } |
| @@ -1756,7 +1761,7 @@ int __init APIC_init_uniprocessor(void) | |||
| 1756 | enable_IO_APIC(); | 1761 | enable_IO_APIC(); |
| 1757 | #endif | 1762 | #endif |
| 1758 | 1763 | ||
| 1759 | end_local_APIC_setup(); | 1764 | bsp_end_local_APIC_setup(); |
| 1760 | 1765 | ||
| 1761 | #ifdef CONFIG_X86_IO_APIC | 1766 | #ifdef CONFIG_X86_IO_APIC |
| 1762 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) | 1767 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 697dc34b7b8..ca9e2a3545a 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -4002,6 +4002,9 @@ int mp_find_ioapic(u32 gsi) | |||
| 4002 | { | 4002 | { |
| 4003 | int i = 0; | 4003 | int i = 0; |
| 4004 | 4004 | ||
| 4005 | if (nr_ioapics == 0) | ||
| 4006 | return -1; | ||
| 4007 | |||
| 4005 | /* Find the IOAPIC that manages this GSI. */ | 4008 | /* Find the IOAPIC that manages this GSI. */ |
| 4006 | for (i = 0; i < nr_ioapics; i++) { | 4009 | for (i = 0; i < nr_ioapics; i++) { |
| 4007 | if ((gsi >= mp_gsi_routing[i].gsi_base) | 4010 | if ((gsi >= mp_gsi_routing[i].gsi_base) |
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 01c0f3ee6cc..bebabec5b44 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
| @@ -793,13 +793,21 @@ void set_mtrr_aps_delayed_init(void) | |||
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | /* | 795 | /* |
| 796 | * MTRR initialization for all AP's | 796 | * Delayed MTRR initialization for all AP's |
| 797 | */ | 797 | */ |
| 798 | void mtrr_aps_init(void) | 798 | void mtrr_aps_init(void) |
| 799 | { | 799 | { |
| 800 | if (!use_intel()) | 800 | if (!use_intel()) |
| 801 | return; | 801 | return; |
| 802 | 802 | ||
| 803 | /* | ||
| 804 | * Check if someone has requested the delay of AP MTRR initialization, | ||
| 805 | * by doing set_mtrr_aps_delayed_init(), prior to this point. If not, | ||
| 806 | * then we are done. | ||
| 807 | */ | ||
| 808 | if (!mtrr_aps_delayed_init) | ||
| 809 | return; | ||
| 810 | |||
| 803 | set_mtrr(~0U, 0, 0, 0); | 811 | set_mtrr(~0U, 0, 0, 0); |
| 804 | mtrr_aps_delayed_init = false; | 812 | mtrr_aps_delayed_init = false; |
| 805 | } | 813 | } |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index fc293dc8dc3..767d6c43de3 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -85,6 +85,8 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE) | |||
| 85 | */ | 85 | */ |
| 86 | __HEAD | 86 | __HEAD |
| 87 | ENTRY(startup_32) | 87 | ENTRY(startup_32) |
| 88 | movl pa(stack_start),%ecx | ||
| 89 | |||
| 88 | /* test KEEP_SEGMENTS flag to see if the bootloader is asking | 90 | /* test KEEP_SEGMENTS flag to see if the bootloader is asking |
| 89 | us to not reload segments */ | 91 | us to not reload segments */ |
| 90 | testb $(1<<6), BP_loadflags(%esi) | 92 | testb $(1<<6), BP_loadflags(%esi) |
| @@ -99,7 +101,9 @@ ENTRY(startup_32) | |||
| 99 | movl %eax,%es | 101 | movl %eax,%es |
| 100 | movl %eax,%fs | 102 | movl %eax,%fs |
| 101 | movl %eax,%gs | 103 | movl %eax,%gs |
| 104 | movl %eax,%ss | ||
| 102 | 2: | 105 | 2: |
| 106 | leal -__PAGE_OFFSET(%ecx),%esp | ||
| 103 | 107 | ||
| 104 | /* | 108 | /* |
| 105 | * Clear BSS first so that there are no surprises... | 109 | * Clear BSS first so that there are no surprises... |
| @@ -145,8 +149,6 @@ ENTRY(startup_32) | |||
| 145 | * _brk_end is set up to point to the first "safe" location. | 149 | * _brk_end is set up to point to the first "safe" location. |
| 146 | * Mappings are created both at virtual address 0 (identity mapping) | 150 | * Mappings are created both at virtual address 0 (identity mapping) |
| 147 | * and PAGE_OFFSET for up to _end. | 151 | * and PAGE_OFFSET for up to _end. |
| 148 | * | ||
| 149 | * Note that the stack is not yet set up! | ||
| 150 | */ | 152 | */ |
| 151 | #ifdef CONFIG_X86_PAE | 153 | #ifdef CONFIG_X86_PAE |
| 152 | 154 | ||
| @@ -282,6 +284,9 @@ ENTRY(startup_32_smp) | |||
| 282 | movl %eax,%es | 284 | movl %eax,%es |
| 283 | movl %eax,%fs | 285 | movl %eax,%fs |
| 284 | movl %eax,%gs | 286 | movl %eax,%gs |
| 287 | movl pa(stack_start),%ecx | ||
| 288 | movl %eax,%ss | ||
| 289 | leal -__PAGE_OFFSET(%ecx),%esp | ||
| 285 | #endif /* CONFIG_SMP */ | 290 | #endif /* CONFIG_SMP */ |
| 286 | default_entry: | 291 | default_entry: |
| 287 | 292 | ||
| @@ -347,8 +352,8 @@ default_entry: | |||
| 347 | movl %eax,%cr0 /* ..and set paging (PG) bit */ | 352 | movl %eax,%cr0 /* ..and set paging (PG) bit */ |
| 348 | ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */ | 353 | ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */ |
| 349 | 1: | 354 | 1: |
| 350 | /* Set up the stack pointer */ | 355 | /* Shift the stack pointer to a virtual address */ |
| 351 | lss stack_start,%esp | 356 | addl $__PAGE_OFFSET, %esp |
| 352 | 357 | ||
| 353 | /* | 358 | /* |
| 354 | * Initialize eflags. Some BIOS's leave bits like NT set. This would | 359 | * Initialize eflags. Some BIOS's leave bits like NT set. This would |
| @@ -360,9 +365,7 @@ default_entry: | |||
| 360 | 365 | ||
| 361 | #ifdef CONFIG_SMP | 366 | #ifdef CONFIG_SMP |
| 362 | cmpb $0, ready | 367 | cmpb $0, ready |
| 363 | jz 1f /* Initial CPU cleans BSS */ | 368 | jnz checkCPUtype |
| 364 | jmp checkCPUtype | ||
| 365 | 1: | ||
| 366 | #endif /* CONFIG_SMP */ | 369 | #endif /* CONFIG_SMP */ |
| 367 | 370 | ||
| 368 | /* | 371 | /* |
| @@ -470,14 +473,7 @@ is386: movl $2,%ecx # set MP | |||
| 470 | 473 | ||
| 471 | cld # gcc2 wants the direction flag cleared at all times | 474 | cld # gcc2 wants the direction flag cleared at all times |
| 472 | pushl $0 # fake return address for unwinder | 475 | pushl $0 # fake return address for unwinder |
| 473 | #ifdef CONFIG_SMP | ||
| 474 | movb ready, %cl | ||
| 475 | movb $1, ready | 476 | movb $1, ready |
| 476 | cmpb $0,%cl # the first CPU calls start_kernel | ||
| 477 | je 1f | ||
| 478 | movl (stack_start), %esp | ||
| 479 | 1: | ||
| 480 | #endif /* CONFIG_SMP */ | ||
| 481 | jmp *(initial_code) | 477 | jmp *(initial_code) |
| 482 | 478 | ||
| 483 | /* | 479 | /* |
| @@ -670,15 +666,15 @@ ENTRY(initial_page_table) | |||
| 670 | #endif | 666 | #endif |
| 671 | 667 | ||
| 672 | .data | 668 | .data |
| 669 | .balign 4 | ||
| 673 | ENTRY(stack_start) | 670 | ENTRY(stack_start) |
| 674 | .long init_thread_union+THREAD_SIZE | 671 | .long init_thread_union+THREAD_SIZE |
| 675 | .long __BOOT_DS | ||
| 676 | |||
| 677 | ready: .byte 0 | ||
| 678 | 672 | ||
| 679 | early_recursion_flag: | 673 | early_recursion_flag: |
| 680 | .long 0 | 674 | .long 0 |
| 681 | 675 | ||
| 676 | ready: .byte 0 | ||
| 677 | |||
| 682 | int_msg: | 678 | int_msg: |
| 683 | .asciz "Unknown interrupt or fault at: %p %p %p\n" | 679 | .asciz "Unknown interrupt or fault at: %p %p %p\n" |
| 684 | 680 | ||
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 52945da52a9..387b6a0c9e8 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -367,7 +367,8 @@ void fixup_irqs(void) | |||
| 367 | if (irr & (1 << (vector % 32))) { | 367 | if (irr & (1 << (vector % 32))) { |
| 368 | irq = __this_cpu_read(vector_irq[vector]); | 368 | irq = __this_cpu_read(vector_irq[vector]); |
| 369 | 369 | ||
| 370 | data = irq_get_irq_data(irq); | 370 | desc = irq_to_desc(irq); |
| 371 | data = &desc->irq_data; | ||
| 371 | raw_spin_lock(&desc->lock); | 372 | raw_spin_lock(&desc->lock); |
| 372 | if (data->chip->irq_retrigger) | 373 | if (data->chip->irq_retrigger) |
| 373 | data->chip->irq_retrigger(data); | 374 | data->chip->irq_retrigger(data); |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index e764fc05d70..ff455419898 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -92,21 +92,31 @@ void show_regs(struct pt_regs *regs) | |||
| 92 | 92 | ||
| 93 | void show_regs_common(void) | 93 | void show_regs_common(void) |
| 94 | { | 94 | { |
| 95 | const char *board, *product; | 95 | const char *vendor, *product, *board; |
| 96 | 96 | ||
| 97 | board = dmi_get_system_info(DMI_BOARD_NAME); | 97 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); |
| 98 | if (!board) | 98 | if (!vendor) |
| 99 | board = ""; | 99 | vendor = ""; |
| 100 | product = dmi_get_system_info(DMI_PRODUCT_NAME); | 100 | product = dmi_get_system_info(DMI_PRODUCT_NAME); |
| 101 | if (!product) | 101 | if (!product) |
| 102 | product = ""; | 102 | product = ""; |
| 103 | 103 | ||
| 104 | /* Board Name is optional */ | ||
| 105 | board = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 106 | |||
| 104 | printk(KERN_CONT "\n"); | 107 | printk(KERN_CONT "\n"); |
| 105 | printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", | 108 | printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", |
| 106 | current->pid, current->comm, print_tainted(), | 109 | current->pid, current->comm, print_tainted(), |
| 107 | init_utsname()->release, | 110 | init_utsname()->release, |
| 108 | (int)strcspn(init_utsname()->version, " "), | 111 | (int)strcspn(init_utsname()->version, " "), |
| 109 | init_utsname()->version, board, product); | 112 | init_utsname()->version); |
| 113 | printk(KERN_CONT " "); | ||
| 114 | printk(KERN_CONT "%s %s", vendor, product); | ||
| 115 | if (board) { | ||
| 116 | printk(KERN_CONT "/"); | ||
| 117 | printk(KERN_CONT "%s", board); | ||
| 118 | } | ||
| 119 | printk(KERN_CONT "\n"); | ||
| 110 | } | 120 | } |
| 111 | 121 | ||
| 112 | void flush_thread(void) | 122 | void flush_thread(void) |
| @@ -506,7 +516,7 @@ static void poll_idle(void) | |||
| 506 | #define MWAIT_ECX_EXTENDED_INFO 0x01 | 516 | #define MWAIT_ECX_EXTENDED_INFO 0x01 |
| 507 | #define MWAIT_EDX_C1 0xf0 | 517 | #define MWAIT_EDX_C1 0xf0 |
| 508 | 518 | ||
| 509 | int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) | 519 | int mwait_usable(const struct cpuinfo_x86 *c) |
| 510 | { | 520 | { |
| 511 | u32 eax, ebx, ecx, edx; | 521 | u32 eax, ebx, ecx, edx; |
| 512 | 522 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 0cbe8c0b35e..08776a95348 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -638,7 +638,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
| 638 | * target processor state. | 638 | * target processor state. |
| 639 | */ | 639 | */ |
| 640 | startup_ipi_hook(phys_apicid, (unsigned long) start_secondary, | 640 | startup_ipi_hook(phys_apicid, (unsigned long) start_secondary, |
| 641 | (unsigned long)stack_start.sp); | 641 | stack_start); |
| 642 | 642 | ||
| 643 | /* | 643 | /* |
| 644 | * Run STARTUP IPI loop. | 644 | * Run STARTUP IPI loop. |
| @@ -785,7 +785,7 @@ do_rest: | |||
| 785 | #endif | 785 | #endif |
| 786 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 786 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
| 787 | initial_code = (unsigned long)start_secondary; | 787 | initial_code = (unsigned long)start_secondary; |
| 788 | stack_start.sp = (void *) c_idle.idle->thread.sp; | 788 | stack_start = c_idle.idle->thread.sp; |
| 789 | 789 | ||
| 790 | /* start_ip had better be page-aligned! */ | 790 | /* start_ip had better be page-aligned! */ |
| 791 | start_ip = setup_trampoline(); | 791 | start_ip = setup_trampoline(); |
| @@ -1060,7 +1060,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
| 1060 | 1060 | ||
| 1061 | connect_bsp_APIC(); | 1061 | connect_bsp_APIC(); |
| 1062 | setup_local_APIC(); | 1062 | setup_local_APIC(); |
| 1063 | end_local_APIC_setup(); | 1063 | bsp_end_local_APIC_setup(); |
| 1064 | return -1; | 1064 | return -1; |
| 1065 | } | 1065 | } |
| 1066 | 1066 | ||
| @@ -1137,7 +1137,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
| 1137 | if (!skip_ioapic_setup && nr_ioapics) | 1137 | if (!skip_ioapic_setup && nr_ioapics) |
| 1138 | enable_IO_APIC(); | 1138 | enable_IO_APIC(); |
| 1139 | 1139 | ||
| 1140 | end_local_APIC_setup(); | 1140 | bsp_end_local_APIC_setup(); |
| 1141 | 1141 | ||
| 1142 | map_cpu_to_logical_apicid(); | 1142 | map_cpu_to_logical_apicid(); |
| 1143 | 1143 | ||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 25bd1bc5aad..54ce246a383 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -1150,8 +1150,8 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) | |||
| 1150 | kvm_load_ldt(svm->host.ldt); | 1150 | kvm_load_ldt(svm->host.ldt); |
| 1151 | #ifdef CONFIG_X86_64 | 1151 | #ifdef CONFIG_X86_64 |
| 1152 | loadsegment(fs, svm->host.fs); | 1152 | loadsegment(fs, svm->host.fs); |
| 1153 | load_gs_index(svm->host.gs); | ||
| 1154 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); | 1153 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); |
| 1154 | load_gs_index(svm->host.gs); | ||
| 1155 | #else | 1155 | #else |
| 1156 | loadsegment(gs, svm->host.gs); | 1156 | loadsegment(gs, svm->host.gs); |
| 1157 | #endif | 1157 | #endif |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 8b830ca14ac..d343b3c81f3 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -256,7 +256,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, | |||
| 256 | unsigned long pfn) | 256 | unsigned long pfn) |
| 257 | { | 257 | { |
| 258 | pgprot_t forbidden = __pgprot(0); | 258 | pgprot_t forbidden = __pgprot(0); |
| 259 | pgprot_t required = __pgprot(0); | ||
| 260 | 259 | ||
| 261 | /* | 260 | /* |
| 262 | * The BIOS area between 640k and 1Mb needs to be executable for | 261 | * The BIOS area between 640k and 1Mb needs to be executable for |
| @@ -282,12 +281,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, | |||
| 282 | if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT, | 281 | if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT, |
| 283 | __pa((unsigned long)__end_rodata) >> PAGE_SHIFT)) | 282 | __pa((unsigned long)__end_rodata) >> PAGE_SHIFT)) |
| 284 | pgprot_val(forbidden) |= _PAGE_RW; | 283 | pgprot_val(forbidden) |= _PAGE_RW; |
| 285 | /* | ||
| 286 | * .data and .bss should always be writable. | ||
| 287 | */ | ||
| 288 | if (within(address, (unsigned long)_sdata, (unsigned long)_edata) || | ||
| 289 | within(address, (unsigned long)__bss_start, (unsigned long)__bss_stop)) | ||
| 290 | pgprot_val(required) |= _PAGE_RW; | ||
| 291 | 284 | ||
| 292 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) | 285 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) |
| 293 | /* | 286 | /* |
| @@ -327,7 +320,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, | |||
| 327 | #endif | 320 | #endif |
| 328 | 321 | ||
| 329 | prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); | 322 | prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); |
| 330 | prot = __pgprot(pgprot_val(prot) | pgprot_val(required)); | ||
| 331 | 323 | ||
| 332 | return prot; | 324 | return prot; |
| 333 | } | 325 | } |
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 381b09bb562..a89043a3caa 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
| @@ -168,7 +168,15 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, | |||
| 168 | * tree of blkg (instead of traversing through hash list all | 168 | * tree of blkg (instead of traversing through hash list all |
| 169 | * the time. | 169 | * the time. |
| 170 | */ | 170 | */ |
| 171 | tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); | 171 | |
| 172 | /* | ||
| 173 | * This is the common case when there are no blkio cgroups. | ||
| 174 | * Avoid lookup in this case | ||
| 175 | */ | ||
| 176 | if (blkcg == &blkio_root_cgroup) | ||
| 177 | tg = &td->root_tg; | ||
| 178 | else | ||
| 179 | tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); | ||
| 172 | 180 | ||
| 173 | /* Fill in device details for root group */ | 181 | /* Fill in device details for root group */ |
| 174 | if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { | 182 | if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 501ffdf0399..7be4c795962 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -599,7 +599,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg) | |||
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | static inline unsigned | 601 | static inline unsigned |
| 602 | cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 602 | cfq_scaled_cfqq_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
| 603 | { | 603 | { |
| 604 | unsigned slice = cfq_prio_to_slice(cfqd, cfqq); | 604 | unsigned slice = cfq_prio_to_slice(cfqd, cfqq); |
| 605 | if (cfqd->cfq_latency) { | 605 | if (cfqd->cfq_latency) { |
| @@ -631,7 +631,7 @@ cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
| 631 | static inline void | 631 | static inline void |
| 632 | cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 632 | cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
| 633 | { | 633 | { |
| 634 | unsigned slice = cfq_scaled_group_slice(cfqd, cfqq); | 634 | unsigned slice = cfq_scaled_cfqq_slice(cfqd, cfqq); |
| 635 | 635 | ||
| 636 | cfqq->slice_start = jiffies; | 636 | cfqq->slice_start = jiffies; |
| 637 | cfqq->slice_end = jiffies + slice; | 637 | cfqq->slice_end = jiffies + slice; |
| @@ -1671,7 +1671,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 1671 | */ | 1671 | */ |
| 1672 | if (timed_out) { | 1672 | if (timed_out) { |
| 1673 | if (cfq_cfqq_slice_new(cfqq)) | 1673 | if (cfq_cfqq_slice_new(cfqq)) |
| 1674 | cfqq->slice_resid = cfq_scaled_group_slice(cfqd, cfqq); | 1674 | cfqq->slice_resid = cfq_scaled_cfqq_slice(cfqd, cfqq); |
| 1675 | else | 1675 | else |
| 1676 | cfqq->slice_resid = cfqq->slice_end - jiffies; | 1676 | cfqq->slice_resid = cfqq->slice_end - jiffies; |
| 1677 | cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); | 1677 | cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); |
| @@ -3432,6 +3432,10 @@ static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
| 3432 | { | 3432 | { |
| 3433 | struct cfq_io_context *cic = cfqd->active_cic; | 3433 | struct cfq_io_context *cic = cfqd->active_cic; |
| 3434 | 3434 | ||
| 3435 | /* If the queue already has requests, don't wait */ | ||
| 3436 | if (!RB_EMPTY_ROOT(&cfqq->sort_list)) | ||
| 3437 | return false; | ||
| 3438 | |||
| 3435 | /* If there are other queues in the group, don't wait */ | 3439 | /* If there are other queues in the group, don't wait */ |
| 3436 | if (cfqq->cfqg->nr_cfqq > 1) | 3440 | if (cfqq->cfqg->nr_cfqq > 1) |
| 3437 | return false; | 3441 | return false; |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index e9562a7cb2f..3b20a3401b6 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
| @@ -212,37 +212,40 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
| 212 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 212 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | /* Validate wake_device is of type Device */ | ||
| 216 | |||
| 217 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); | ||
| 218 | if (device_node->type != ACPI_TYPE_DEVICE) { | ||
| 219 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 220 | } | ||
| 221 | |||
| 222 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 215 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
| 223 | 216 | ||
| 224 | /* Ensure that we have a valid GPE number */ | 217 | /* Ensure that we have a valid GPE number */ |
| 225 | 218 | ||
| 226 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 219 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
| 227 | if (gpe_event_info) { | 220 | if (!gpe_event_info) { |
| 228 | /* | 221 | goto unlock_and_exit; |
| 229 | * If there is no method or handler for this GPE, then the | 222 | } |
| 230 | * wake_device will be notified whenever this GPE fires (aka | 223 | |
| 231 | * "implicit notify") Note: The GPE is assumed to be | 224 | /* |
| 232 | * level-triggered (for windows compatibility). | 225 | * If there is no method or handler for this GPE, then the |
| 233 | */ | 226 | * wake_device will be notified whenever this GPE fires (aka |
| 234 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 227 | * "implicit notify") Note: The GPE is assumed to be |
| 235 | ACPI_GPE_DISPATCH_NONE) { | 228 | * level-triggered (for windows compatibility). |
| 236 | gpe_event_info->flags = | 229 | */ |
| 237 | (ACPI_GPE_DISPATCH_NOTIFY | | 230 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
| 238 | ACPI_GPE_LEVEL_TRIGGERED); | 231 | ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { |
| 239 | gpe_event_info->dispatch.device_node = device_node; | ||
| 240 | } | ||
| 241 | 232 | ||
| 242 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | 233 | /* Validate wake_device is of type Device */ |
| 243 | status = AE_OK; | 234 | |
| 235 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, | ||
| 236 | wake_device); | ||
| 237 | if (device_node->type != ACPI_TYPE_DEVICE) { | ||
| 238 | goto unlock_and_exit; | ||
| 239 | } | ||
| 240 | gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | | ||
| 241 | ACPI_GPE_LEVEL_TRIGGERED); | ||
| 242 | gpe_event_info->dispatch.device_node = device_node; | ||
| 244 | } | 243 | } |
| 245 | 244 | ||
| 245 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
| 246 | status = AE_OK; | ||
| 247 | |||
| 248 | unlock_and_exit: | ||
| 246 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 249 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 247 | return_ACPI_STATUS(status); | 250 | return_ACPI_STATUS(status); |
| 248 | } | 251 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b0931818cf9..c90c76aa7f8 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -636,17 +636,21 @@ EXPORT_SYMBOL(acpi_os_write_port); | |||
| 636 | acpi_status | 636 | acpi_status |
| 637 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | 637 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) |
| 638 | { | 638 | { |
| 639 | u32 dummy; | ||
| 640 | void __iomem *virt_addr; | 639 | void __iomem *virt_addr; |
| 641 | int size = width / 8, unmap = 0; | 640 | unsigned int size = width / 8; |
| 641 | bool unmap = false; | ||
| 642 | u32 dummy; | ||
| 642 | 643 | ||
| 643 | rcu_read_lock(); | 644 | rcu_read_lock(); |
| 644 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 645 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
| 645 | rcu_read_unlock(); | ||
| 646 | if (!virt_addr) { | 646 | if (!virt_addr) { |
| 647 | rcu_read_unlock(); | ||
| 647 | virt_addr = acpi_os_ioremap(phys_addr, size); | 648 | virt_addr = acpi_os_ioremap(phys_addr, size); |
| 648 | unmap = 1; | 649 | if (!virt_addr) |
| 650 | return AE_BAD_ADDRESS; | ||
| 651 | unmap = true; | ||
| 649 | } | 652 | } |
| 653 | |||
| 650 | if (!value) | 654 | if (!value) |
| 651 | value = &dummy; | 655 | value = &dummy; |
| 652 | 656 | ||
| @@ -666,6 +670,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | |||
| 666 | 670 | ||
| 667 | if (unmap) | 671 | if (unmap) |
| 668 | iounmap(virt_addr); | 672 | iounmap(virt_addr); |
| 673 | else | ||
| 674 | rcu_read_unlock(); | ||
| 669 | 675 | ||
| 670 | return AE_OK; | 676 | return AE_OK; |
| 671 | } | 677 | } |
| @@ -674,14 +680,17 @@ acpi_status | |||
| 674 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | 680 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) |
| 675 | { | 681 | { |
| 676 | void __iomem *virt_addr; | 682 | void __iomem *virt_addr; |
| 677 | int size = width / 8, unmap = 0; | 683 | unsigned int size = width / 8; |
| 684 | bool unmap = false; | ||
| 678 | 685 | ||
| 679 | rcu_read_lock(); | 686 | rcu_read_lock(); |
| 680 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 687 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
| 681 | rcu_read_unlock(); | ||
| 682 | if (!virt_addr) { | 688 | if (!virt_addr) { |
| 689 | rcu_read_unlock(); | ||
| 683 | virt_addr = acpi_os_ioremap(phys_addr, size); | 690 | virt_addr = acpi_os_ioremap(phys_addr, size); |
| 684 | unmap = 1; | 691 | if (!virt_addr) |
| 692 | return AE_BAD_ADDRESS; | ||
| 693 | unmap = true; | ||
| 685 | } | 694 | } |
| 686 | 695 | ||
| 687 | switch (width) { | 696 | switch (width) { |
| @@ -700,6 +709,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
| 700 | 709 | ||
| 701 | if (unmap) | 710 | if (unmap) |
| 702 | iounmap(virt_addr); | 711 | iounmap(virt_addr); |
| 712 | else | ||
| 713 | rcu_read_unlock(); | ||
| 703 | 714 | ||
| 704 | return AE_OK; | 715 | return AE_OK; |
| 705 | } | 716 | } |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 42d3d72dae8..5af3479714f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
| @@ -82,6 +82,11 @@ long acpi_is_video_device(struct acpi_device *device) | |||
| 82 | if (!device) | 82 | if (!device) |
| 83 | return 0; | 83 | return 0; |
| 84 | 84 | ||
| 85 | /* Is this device able to support video switching ? */ | ||
| 86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) || | ||
| 87 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
| 88 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; | ||
| 89 | |||
| 85 | /* Is this device able to retrieve a video ROM ? */ | 90 | /* Is this device able to retrieve a video ROM ? */ |
| 86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | 91 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) |
| 87 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; | 92 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index ed650145250..7bfbe40bc43 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
| @@ -86,8 +86,12 @@ int __init acpi_wakeup_device_init(void) | |||
| 86 | struct acpi_device *dev = container_of(node, | 86 | struct acpi_device *dev = container_of(node, |
| 87 | struct acpi_device, | 87 | struct acpi_device, |
| 88 | wakeup_list); | 88 | wakeup_list); |
| 89 | if (device_can_wakeup(&dev->dev)) | 89 | if (device_can_wakeup(&dev->dev)) { |
| 90 | /* Button GPEs are supposed to be always enabled. */ | ||
| 91 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
| 92 | dev->wakeup.gpe_number); | ||
| 90 | device_set_wakeup_enable(&dev->dev, true); | 93 | device_set_wakeup_enable(&dev->dev, true); |
| 94 | } | ||
| 91 | } | 95 | } |
| 92 | mutex_unlock(&acpi_device_lock); | 96 | mutex_unlock(&acpi_device_lock); |
| 93 | return 0; | 97 | return 0; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 73fb1c4f4cd..25ef1a4556e 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
| @@ -866,8 +866,9 @@ static int popen(struct atm_vcc *vcc) | |||
| 866 | } | 866 | } |
| 867 | 867 | ||
| 868 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); | 868 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); |
| 869 | if (!skb && net_ratelimit()) { | 869 | if (!skb) { |
| 870 | dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); | 870 | if (net_ratelimit()) |
| 871 | dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); | ||
| 871 | return -ENOMEM; | 872 | return -ENOMEM; |
| 872 | } | 873 | } |
| 873 | header = (void *)skb_put(skb, sizeof(*header)); | 874 | header = (void *)skb_put(skb, sizeof(*header)); |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index d7f463d6312..40528ba56d1 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
| @@ -39,4 +39,4 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o | |||
| 39 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ | 39 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ |
| 40 | obj-$(CONFIG_BLK_DEV_RBD) += rbd.o | 40 | obj-$(CONFIG_BLK_DEV_RBD) += rbd.o |
| 41 | 41 | ||
| 42 | swim_mod-objs := swim.o swim_asm.o | 42 | swim_mod-y := swim.o swim_asm.o |
diff --git a/drivers/block/aoe/Makefile b/drivers/block/aoe/Makefile index e76d997183c..06ea82cdf27 100644 --- a/drivers/block/aoe/Makefile +++ b/drivers/block/aoe/Makefile | |||
| @@ -3,4 +3,4 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_ATA_OVER_ETH) += aoe.o | 5 | obj-$(CONFIG_ATA_OVER_ETH) += aoe.o |
| 6 | aoe-objs := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o | 6 | aoe-y := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 516d5bbec2b..9279272b373 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -2833,7 +2833,7 @@ static int cciss_revalidate(struct gendisk *disk) | |||
| 2833 | sector_t total_size; | 2833 | sector_t total_size; |
| 2834 | InquiryData_struct *inq_buff = NULL; | 2834 | InquiryData_struct *inq_buff = NULL; |
| 2835 | 2835 | ||
| 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2836 | for (logvol = 0; logvol <= h->highest_lun; logvol++) { |
| 2837 | if (!h->drv[logvol]) | 2837 | if (!h->drv[logvol]) |
| 2838 | continue; | 2838 | continue; |
| 2839 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, | 2839 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 44e18c073c4..49e6a545eb6 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -1641,6 +1641,9 @@ out: | |||
| 1641 | 1641 | ||
| 1642 | static void loop_free(struct loop_device *lo) | 1642 | static void loop_free(struct loop_device *lo) |
| 1643 | { | 1643 | { |
| 1644 | if (!lo->lo_queue->queue_lock) | ||
| 1645 | lo->lo_queue->queue_lock = &lo->lo_queue->__queue_lock; | ||
| 1646 | |||
| 1644 | blk_cleanup_queue(lo->lo_queue); | 1647 | blk_cleanup_queue(lo->lo_queue); |
| 1645 | put_disk(lo->lo_disk); | 1648 | put_disk(lo->lo_disk); |
| 1646 | list_del(&lo->lo_list); | 1649 | list_del(&lo->lo_list); |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index a32fb41246f..e6fc716aca4 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
| @@ -53,7 +53,6 @@ | |||
| 53 | #define DBG_BLKDEV 0x0100 | 53 | #define DBG_BLKDEV 0x0100 |
| 54 | #define DBG_RX 0x0200 | 54 | #define DBG_RX 0x0200 |
| 55 | #define DBG_TX 0x0400 | 55 | #define DBG_TX 0x0400 |
| 56 | static DEFINE_MUTEX(nbd_mutex); | ||
| 57 | static unsigned int debugflags; | 56 | static unsigned int debugflags; |
| 58 | #endif /* NDEBUG */ | 57 | #endif /* NDEBUG */ |
| 59 | 58 | ||
| @@ -718,11 +717,9 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 718 | dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", | 717 | dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", |
| 719 | lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); | 718 | lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); |
| 720 | 719 | ||
| 721 | mutex_lock(&nbd_mutex); | ||
| 722 | mutex_lock(&lo->tx_lock); | 720 | mutex_lock(&lo->tx_lock); |
| 723 | error = __nbd_ioctl(bdev, lo, cmd, arg); | 721 | error = __nbd_ioctl(bdev, lo, cmd, arg); |
| 724 | mutex_unlock(&lo->tx_lock); | 722 | mutex_unlock(&lo->tx_lock); |
| 725 | mutex_unlock(&nbd_mutex); | ||
| 726 | 723 | ||
| 727 | return error; | 724 | return error; |
| 728 | } | 725 | } |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a126e614601..333c21289d9 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
| @@ -39,6 +39,8 @@ static struct usb_device_id ath3k_table[] = { | |||
| 39 | /* Atheros AR3011 with sflash firmware*/ | 39 | /* Atheros AR3011 with sflash firmware*/ |
| 40 | { USB_DEVICE(0x0CF3, 0x3002) }, | 40 | { USB_DEVICE(0x0CF3, 0x3002) }, |
| 41 | 41 | ||
| 42 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
| 43 | { USB_DEVICE(0x03F0, 0x311D) }, | ||
| 42 | { } /* Terminating entry */ | 44 | { } /* Terminating entry */ |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1da773f899a..4cefa91e6c3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -102,6 +102,9 @@ static struct usb_device_id blacklist_table[] = { | |||
| 102 | /* Atheros 3011 with sflash firmware */ | 102 | /* Atheros 3011 with sflash firmware */ |
| 103 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | 103 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, |
| 104 | 104 | ||
| 105 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
| 106 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | ||
| 107 | |||
| 105 | /* Broadcom BCM2035 */ | 108 | /* Broadcom BCM2035 */ |
| 106 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 109 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
| 107 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 110 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 14033a36bcd..e2c48a7eccf 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
| @@ -409,7 +409,8 @@ int register_cdrom(struct cdrom_device_info *cdi) | |||
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | ENSURE(drive_status, CDC_DRIVE_STATUS ); | 411 | ENSURE(drive_status, CDC_DRIVE_STATUS ); |
| 412 | ENSURE(media_changed, CDC_MEDIA_CHANGED); | 412 | if (cdo->check_events == NULL && cdo->media_changed == NULL) |
| 413 | *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC); | ||
| 413 | ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); | 414 | ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); |
| 414 | ENSURE(lock_door, CDC_LOCK); | 415 | ENSURE(lock_door, CDC_LOCK); |
| 415 | ENSURE(select_speed, CDC_SELECT_SPEED); | 416 | ENSURE(select_speed, CDC_SELECT_SPEED); |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 5bc765d4c3c..8238f89f73c 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
| @@ -30,6 +30,7 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | |||
| 30 | obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o | 30 | obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o |
| 31 | obj-$(CONFIG_SX) += sx.o generic_serial.o | 31 | obj-$(CONFIG_SX) += sx.o generic_serial.o |
| 32 | obj-$(CONFIG_RIO) += rio/ generic_serial.o | 32 | obj-$(CONFIG_RIO) += rio/ generic_serial.o |
| 33 | obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o | ||
| 33 | obj-$(CONFIG_RAW_DRIVER) += raw.o | 34 | obj-$(CONFIG_RAW_DRIVER) += raw.o |
| 34 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o | 35 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o |
| 35 | obj-$(CONFIG_MSPEC) += mspec.o | 36 | obj-$(CONFIG_MSPEC) += mspec.o |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index fcd867d923b..d8b1b576556 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
| @@ -50,7 +50,7 @@ config AGP_ATI | |||
| 50 | 50 | ||
| 51 | config AGP_AMD | 51 | config AGP_AMD |
| 52 | tristate "AMD Irongate, 761, and 762 chipset support" | 52 | tristate "AMD Irongate, 761, and 762 chipset support" |
| 53 | depends on AGP && (X86_32 || ALPHA) | 53 | depends on AGP && X86_32 |
| 54 | help | 54 | help |
| 55 | This option gives you AGP support for the GLX component of | 55 | This option gives you AGP support for the GLX component of |
| 56 | X on AMD Irongate, 761, and 762 chipsets. | 56 | X on AMD Irongate, 761, and 762 chipsets. |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index b1b4362bc64..45681c0ff3b 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
| @@ -41,22 +41,8 @@ static int amd_create_page_map(struct amd_page_map *page_map) | |||
| 41 | if (page_map->real == NULL) | 41 | if (page_map->real == NULL) |
| 42 | return -ENOMEM; | 42 | return -ENOMEM; |
| 43 | 43 | ||
| 44 | #ifndef CONFIG_X86 | ||
| 45 | SetPageReserved(virt_to_page(page_map->real)); | ||
| 46 | global_cache_flush(); | ||
| 47 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | ||
| 48 | PAGE_SIZE); | ||
| 49 | if (page_map->remapped == NULL) { | ||
| 50 | ClearPageReserved(virt_to_page(page_map->real)); | ||
| 51 | free_page((unsigned long) page_map->real); | ||
| 52 | page_map->real = NULL; | ||
| 53 | return -ENOMEM; | ||
| 54 | } | ||
| 55 | global_cache_flush(); | ||
| 56 | #else | ||
| 57 | set_memory_uc((unsigned long)page_map->real, 1); | 44 | set_memory_uc((unsigned long)page_map->real, 1); |
| 58 | page_map->remapped = page_map->real; | 45 | page_map->remapped = page_map->real; |
| 59 | #endif | ||
| 60 | 46 | ||
| 61 | for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { | 47 | for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { |
| 62 | writel(agp_bridge->scratch_page, page_map->remapped+i); | 48 | writel(agp_bridge->scratch_page, page_map->remapped+i); |
| @@ -68,12 +54,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) | |||
| 68 | 54 | ||
| 69 | static void amd_free_page_map(struct amd_page_map *page_map) | 55 | static void amd_free_page_map(struct amd_page_map *page_map) |
| 70 | { | 56 | { |
| 71 | #ifndef CONFIG_X86 | ||
| 72 | iounmap(page_map->remapped); | ||
| 73 | ClearPageReserved(virt_to_page(page_map->real)); | ||
| 74 | #else | ||
| 75 | set_memory_wb((unsigned long)page_map->real, 1); | 57 | set_memory_wb((unsigned long)page_map->real, 1); |
| 76 | #endif | ||
| 77 | free_page((unsigned long) page_map->real); | 58 | free_page((unsigned long) page_map->real); |
| 78 | } | 59 | } |
| 79 | 60 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 857df10c042..b0a0dccc98c 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -774,20 +774,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
| 774 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | 774 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
| 775 | 775 | ||
| 776 | /* | 776 | /* |
| 777 | * If the device has not been properly setup, the following will catch | ||
| 778 | * the problem and should stop the system from crashing. | ||
| 779 | * 20030610 - hamish@zot.org | ||
| 780 | */ | ||
| 781 | if (pci_enable_device(pdev)) { | ||
| 782 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
| 783 | agp_put_bridge(bridge); | ||
| 784 | return -ENODEV; | ||
| 785 | } | ||
| 786 | |||
| 787 | /* | ||
| 788 | * The following fixes the case where the BIOS has "forgotten" to | 777 | * The following fixes the case where the BIOS has "forgotten" to |
| 789 | * provide an address range for the GART. | 778 | * provide an address range for the GART. |
| 790 | * 20030610 - hamish@zot.org | 779 | * 20030610 - hamish@zot.org |
| 780 | * This happens before pci_enable_device() intentionally; | ||
| 781 | * calling pci_enable_device() before assigning the resource | ||
| 782 | * will result in the GART being disabled on machines with such | ||
| 783 | * BIOSs (the GART ends up with a BAR starting at 0, which | ||
| 784 | * conflicts a lot of other devices). | ||
| 791 | */ | 785 | */ |
| 792 | r = &pdev->resource[0]; | 786 | r = &pdev->resource[0]; |
| 793 | if (!r->start && r->end) { | 787 | if (!r->start && r->end) { |
| @@ -798,6 +792,17 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
| 798 | } | 792 | } |
| 799 | } | 793 | } |
| 800 | 794 | ||
| 795 | /* | ||
| 796 | * If the device has not been properly setup, the following will catch | ||
| 797 | * the problem and should stop the system from crashing. | ||
| 798 | * 20030610 - hamish@zot.org | ||
| 799 | */ | ||
| 800 | if (pci_enable_device(pdev)) { | ||
| 801 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
| 802 | agp_put_bridge(bridge); | ||
| 803 | return -ENODEV; | ||
| 804 | } | ||
| 805 | |||
| 801 | /* Fill in the mode register */ | 806 | /* Fill in the mode register */ |
| 802 | if (cap_ptr) { | 807 | if (cap_ptr) { |
| 803 | pci_read_config_dword(pdev, | 808 | pci_read_config_dword(pdev, |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b6ae6e9a9c5..7855f9f45b8 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -320,6 +320,7 @@ static int unload_when_empty = 1; | |||
| 320 | static int add_smi(struct smi_info *smi); | 320 | static int add_smi(struct smi_info *smi); |
| 321 | static int try_smi_init(struct smi_info *smi); | 321 | static int try_smi_init(struct smi_info *smi); |
| 322 | static void cleanup_one_si(struct smi_info *to_clean); | 322 | static void cleanup_one_si(struct smi_info *to_clean); |
| 323 | static void cleanup_ipmi_si(void); | ||
| 323 | 324 | ||
| 324 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); | 325 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
| 325 | static int register_xaction_notifier(struct notifier_block *nb) | 326 | static int register_xaction_notifier(struct notifier_block *nb) |
| @@ -3450,16 +3451,7 @@ static int __devinit init_ipmi_si(void) | |||
| 3450 | mutex_lock(&smi_infos_lock); | 3451 | mutex_lock(&smi_infos_lock); |
| 3451 | if (unload_when_empty && list_empty(&smi_infos)) { | 3452 | if (unload_when_empty && list_empty(&smi_infos)) { |
| 3452 | mutex_unlock(&smi_infos_lock); | 3453 | mutex_unlock(&smi_infos_lock); |
| 3453 | #ifdef CONFIG_PCI | 3454 | cleanup_ipmi_si(); |
| 3454 | if (pci_registered) | ||
| 3455 | pci_unregister_driver(&ipmi_pci_driver); | ||
| 3456 | #endif | ||
| 3457 | |||
| 3458 | #ifdef CONFIG_PPC_OF | ||
| 3459 | if (of_registered) | ||
| 3460 | of_unregister_platform_driver(&ipmi_of_platform_driver); | ||
| 3461 | #endif | ||
| 3462 | driver_unregister(&ipmi_driver.driver); | ||
| 3463 | printk(KERN_WARNING PFX | 3455 | printk(KERN_WARNING PFX |
| 3464 | "Unable to find any System Interface(s)\n"); | 3456 | "Unable to find any System Interface(s)\n"); |
| 3465 | return -ENODEV; | 3457 | return -ENODEV; |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 36e0fa161c2..faf5a2c6592 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -577,9 +577,11 @@ duration: | |||
| 577 | if (rc) | 577 | if (rc) |
| 578 | return; | 578 | return; |
| 579 | 579 | ||
| 580 | if (be32_to_cpu(tpm_cmd.header.out.return_code) | 580 | if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || |
| 581 | != 3 * sizeof(u32)) | 581 | be32_to_cpu(tpm_cmd.header.out.length) |
| 582 | != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32)) | ||
| 582 | return; | 583 | return; |
| 584 | |||
| 583 | duration_cap = &tpm_cmd.params.getcap_out.cap.duration; | 585 | duration_cap = &tpm_cmd.params.getcap_out.cap.duration; |
| 584 | chip->vendor.duration[TPM_SHORT] = | 586 | chip->vendor.duration[TPM_SHORT] = |
| 585 | usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short)); | 587 | usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short)); |
| @@ -939,6 +941,18 @@ ssize_t tpm_show_caps_1_2(struct device * dev, | |||
| 939 | } | 941 | } |
| 940 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); | 942 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); |
| 941 | 943 | ||
| 944 | ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr, | ||
| 945 | char *buf) | ||
| 946 | { | ||
| 947 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
| 948 | |||
| 949 | return sprintf(buf, "%d %d %d\n", | ||
| 950 | jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), | ||
| 951 | jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), | ||
| 952 | jiffies_to_usecs(chip->vendor.duration[TPM_LONG])); | ||
| 953 | } | ||
| 954 | EXPORT_SYMBOL_GPL(tpm_show_timeouts); | ||
| 955 | |||
| 942 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | 956 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, |
| 943 | const char *buf, size_t count) | 957 | const char *buf, size_t count) |
| 944 | { | 958 | { |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 72ddb031b69..d84ff772c26 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
| @@ -56,6 +56,8 @@ extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, | |||
| 56 | char *); | 56 | char *); |
| 57 | extern ssize_t tpm_show_temp_deactivated(struct device *, | 57 | extern ssize_t tpm_show_temp_deactivated(struct device *, |
| 58 | struct device_attribute *attr, char *); | 58 | struct device_attribute *attr, char *); |
| 59 | extern ssize_t tpm_show_timeouts(struct device *, | ||
| 60 | struct device_attribute *attr, char *); | ||
| 59 | 61 | ||
| 60 | struct tpm_chip; | 62 | struct tpm_chip; |
| 61 | 63 | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index dd21df55689..0d1d38e5f26 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
| @@ -376,6 +376,7 @@ static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | |||
| 376 | NULL); | 376 | NULL); |
| 377 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 377 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); |
| 378 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 378 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
| 379 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
| 379 | 380 | ||
| 380 | static struct attribute *tis_attrs[] = { | 381 | static struct attribute *tis_attrs[] = { |
| 381 | &dev_attr_pubek.attr, | 382 | &dev_attr_pubek.attr, |
| @@ -385,7 +386,8 @@ static struct attribute *tis_attrs[] = { | |||
| 385 | &dev_attr_owned.attr, | 386 | &dev_attr_owned.attr, |
| 386 | &dev_attr_temp_deactivated.attr, | 387 | &dev_attr_temp_deactivated.attr, |
| 387 | &dev_attr_caps.attr, | 388 | &dev_attr_caps.attr, |
| 388 | &dev_attr_cancel.attr, NULL, | 389 | &dev_attr_cancel.attr, |
| 390 | &dev_attr_timeouts.attr, NULL, | ||
| 389 | }; | 391 | }; |
| 390 | 392 | ||
| 391 | static struct attribute_group tis_attr_grp = { | 393 | static struct attribute_group tis_attr_grp = { |
diff --git a/drivers/tty/hvc/virtio_console.c b/drivers/char/virtio_console.c index 896a2ced1d2..49039318633 100644 --- a/drivers/tty/hvc/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation | 2 | * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation |
| 3 | * Copyright (C) 2009, 2010 Red Hat, Inc. | 3 | * Copyright (C) 2009, 2010, 2011 Red Hat, Inc. |
| 4 | * Copyright (C) 2009, 2010, 2011 Amit Shah <amit.shah@redhat.com> | ||
| 4 | * | 5 | * |
| 5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -31,7 +32,7 @@ | |||
| 31 | #include <linux/virtio_console.h> | 32 | #include <linux/virtio_console.h> |
| 32 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
| 33 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 34 | #include "hvc_console.h" | 35 | #include "../tty/hvc/hvc_console.h" |
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| 37 | * This is a global struct for storing common data for all the devices | 38 | * This is a global struct for storing common data for all the devices |
| @@ -1462,6 +1463,17 @@ static void control_work_handler(struct work_struct *work) | |||
| 1462 | spin_unlock(&portdev->cvq_lock); | 1463 | spin_unlock(&portdev->cvq_lock); |
| 1463 | } | 1464 | } |
| 1464 | 1465 | ||
| 1466 | static void out_intr(struct virtqueue *vq) | ||
| 1467 | { | ||
| 1468 | struct port *port; | ||
| 1469 | |||
| 1470 | port = find_port_by_vq(vq->vdev->priv, vq); | ||
| 1471 | if (!port) | ||
| 1472 | return; | ||
| 1473 | |||
| 1474 | wake_up_interruptible(&port->waitqueue); | ||
| 1475 | } | ||
| 1476 | |||
| 1465 | static void in_intr(struct virtqueue *vq) | 1477 | static void in_intr(struct virtqueue *vq) |
| 1466 | { | 1478 | { |
| 1467 | struct port *port; | 1479 | struct port *port; |
| @@ -1566,7 +1578,7 @@ static int init_vqs(struct ports_device *portdev) | |||
| 1566 | */ | 1578 | */ |
| 1567 | j = 0; | 1579 | j = 0; |
| 1568 | io_callbacks[j] = in_intr; | 1580 | io_callbacks[j] = in_intr; |
| 1569 | io_callbacks[j + 1] = NULL; | 1581 | io_callbacks[j + 1] = out_intr; |
| 1570 | io_names[j] = "input"; | 1582 | io_names[j] = "input"; |
| 1571 | io_names[j + 1] = "output"; | 1583 | io_names[j + 1] = "output"; |
| 1572 | j += 2; | 1584 | j += 2; |
| @@ -1580,7 +1592,7 @@ static int init_vqs(struct ports_device *portdev) | |||
| 1580 | for (i = 1; i < nr_ports; i++) { | 1592 | for (i = 1; i < nr_ports; i++) { |
| 1581 | j += 2; | 1593 | j += 2; |
| 1582 | io_callbacks[j] = in_intr; | 1594 | io_callbacks[j] = in_intr; |
| 1583 | io_callbacks[j + 1] = NULL; | 1595 | io_callbacks[j + 1] = out_intr; |
| 1584 | io_names[j] = "input"; | 1596 | io_names[j] = "input"; |
| 1585 | io_names[j + 1] = "output"; | 1597 | io_names[j + 1] = "output"; |
| 1586 | } | 1598 | } |
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 297f48b0cba..07bca4970e5 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
| @@ -79,6 +79,7 @@ | |||
| 79 | #include <linux/module.h> | 79 | #include <linux/module.h> |
| 80 | #include <linux/interrupt.h> | 80 | #include <linux/interrupt.h> |
| 81 | #include <linux/slab.h> | 81 | #include <linux/slab.h> |
| 82 | #include <linux/delay.h> | ||
| 82 | #include <linux/dmapool.h> | 83 | #include <linux/dmapool.h> |
| 83 | #include <linux/dmaengine.h> | 84 | #include <linux/dmaengine.h> |
| 84 | #include <linux/amba/bus.h> | 85 | #include <linux/amba/bus.h> |
| @@ -235,16 +236,19 @@ static void pl08x_start_txd(struct pl08x_dma_chan *plchan, | |||
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | /* | 238 | /* |
| 238 | * Overall DMAC remains enabled always. | 239 | * Pause the channel by setting the HALT bit. |
| 239 | * | 240 | * |
| 240 | * Disabling individual channels could lose data. | 241 | * For M->P transfers, pause the DMAC first and then stop the peripheral - |
| 242 | * the FIFO can only drain if the peripheral is still requesting data. | ||
| 243 | * (note: this can still timeout if the DMAC FIFO never drains of data.) | ||
| 241 | * | 244 | * |
| 242 | * Disable the peripheral DMA after disabling the DMAC in order to allow | 245 | * For P->M transfers, disable the peripheral first to stop it filling |
| 243 | * the DMAC FIFO to drain, and hence allow the channel to show inactive | 246 | * the DMAC FIFO, and then pause the DMAC. |
| 244 | */ | 247 | */ |
| 245 | static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) | 248 | static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) |
| 246 | { | 249 | { |
| 247 | u32 val; | 250 | u32 val; |
| 251 | int timeout; | ||
| 248 | 252 | ||
| 249 | /* Set the HALT bit and wait for the FIFO to drain */ | 253 | /* Set the HALT bit and wait for the FIFO to drain */ |
| 250 | val = readl(ch->base + PL080_CH_CONFIG); | 254 | val = readl(ch->base + PL080_CH_CONFIG); |
| @@ -252,8 +256,13 @@ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) | |||
| 252 | writel(val, ch->base + PL080_CH_CONFIG); | 256 | writel(val, ch->base + PL080_CH_CONFIG); |
| 253 | 257 | ||
| 254 | /* Wait for channel inactive */ | 258 | /* Wait for channel inactive */ |
| 255 | while (pl08x_phy_channel_busy(ch)) | 259 | for (timeout = 1000; timeout; timeout--) { |
| 256 | cpu_relax(); | 260 | if (!pl08x_phy_channel_busy(ch)) |
| 261 | break; | ||
| 262 | udelay(1); | ||
| 263 | } | ||
| 264 | if (pl08x_phy_channel_busy(ch)) | ||
| 265 | pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id); | ||
| 257 | } | 266 | } |
| 258 | 267 | ||
| 259 | static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) | 268 | static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) |
| @@ -267,19 +276,24 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) | |||
| 267 | } | 276 | } |
| 268 | 277 | ||
| 269 | 278 | ||
| 270 | /* Stops the channel */ | 279 | /* |
| 271 | static void pl08x_stop_phy_chan(struct pl08x_phy_chan *ch) | 280 | * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and |
| 281 | * clears any pending interrupt status. This should not be used for | ||
| 282 | * an on-going transfer, but as a method of shutting down a channel | ||
| 283 | * (eg, when it's no longer used) or terminating a transfer. | ||
| 284 | */ | ||
| 285 | static void pl08x_terminate_phy_chan(struct pl08x_driver_data *pl08x, | ||
| 286 | struct pl08x_phy_chan *ch) | ||
| 272 | { | 287 | { |
| 273 | u32 val; | 288 | u32 val = readl(ch->base + PL080_CH_CONFIG); |
| 274 | 289 | ||
| 275 | pl08x_pause_phy_chan(ch); | 290 | val &= ~(PL080_CONFIG_ENABLE | PL080_CONFIG_ERR_IRQ_MASK | |
| 291 | PL080_CONFIG_TC_IRQ_MASK); | ||
| 276 | 292 | ||
| 277 | /* Disable channel */ | ||
| 278 | val = readl(ch->base + PL080_CH_CONFIG); | ||
| 279 | val &= ~PL080_CONFIG_ENABLE; | ||
| 280 | val &= ~PL080_CONFIG_ERR_IRQ_MASK; | ||
| 281 | val &= ~PL080_CONFIG_TC_IRQ_MASK; | ||
| 282 | writel(val, ch->base + PL080_CH_CONFIG); | 293 | writel(val, ch->base + PL080_CH_CONFIG); |
| 294 | |||
| 295 | writel(1 << ch->id, pl08x->base + PL080_ERR_CLEAR); | ||
| 296 | writel(1 << ch->id, pl08x->base + PL080_TC_CLEAR); | ||
| 283 | } | 297 | } |
| 284 | 298 | ||
| 285 | static inline u32 get_bytes_in_cctl(u32 cctl) | 299 | static inline u32 get_bytes_in_cctl(u32 cctl) |
| @@ -404,13 +418,12 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x, | |||
| 404 | { | 418 | { |
| 405 | unsigned long flags; | 419 | unsigned long flags; |
| 406 | 420 | ||
| 421 | spin_lock_irqsave(&ch->lock, flags); | ||
| 422 | |||
| 407 | /* Stop the channel and clear its interrupts */ | 423 | /* Stop the channel and clear its interrupts */ |
| 408 | pl08x_stop_phy_chan(ch); | 424 | pl08x_terminate_phy_chan(pl08x, ch); |
| 409 | writel((1 << ch->id), pl08x->base + PL080_ERR_CLEAR); | ||
| 410 | writel((1 << ch->id), pl08x->base + PL080_TC_CLEAR); | ||
| 411 | 425 | ||
| 412 | /* Mark it as free */ | 426 | /* Mark it as free */ |
| 413 | spin_lock_irqsave(&ch->lock, flags); | ||
| 414 | ch->serving = NULL; | 427 | ch->serving = NULL; |
| 415 | spin_unlock_irqrestore(&ch->lock, flags); | 428 | spin_unlock_irqrestore(&ch->lock, flags); |
| 416 | } | 429 | } |
| @@ -1449,7 +1462,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
| 1449 | plchan->state = PL08X_CHAN_IDLE; | 1462 | plchan->state = PL08X_CHAN_IDLE; |
| 1450 | 1463 | ||
| 1451 | if (plchan->phychan) { | 1464 | if (plchan->phychan) { |
| 1452 | pl08x_stop_phy_chan(plchan->phychan); | 1465 | pl08x_terminate_phy_chan(pl08x, plchan->phychan); |
| 1453 | 1466 | ||
| 1454 | /* | 1467 | /* |
| 1455 | * Mark physical channel as free and free any slave | 1468 | * Mark physical channel as free and free any slave |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index e53d438142b..e18eaabe92b 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
| @@ -49,6 +49,7 @@ struct imxdma_channel { | |||
| 49 | 49 | ||
| 50 | struct imxdma_engine { | 50 | struct imxdma_engine { |
| 51 | struct device *dev; | 51 | struct device *dev; |
| 52 | struct device_dma_parameters dma_parms; | ||
| 52 | struct dma_device dma_device; | 53 | struct dma_device dma_device; |
| 53 | struct imxdma_channel channel[MAX_DMA_CHANNELS]; | 54 | struct imxdma_channel channel[MAX_DMA_CHANNELS]; |
| 54 | }; | 55 | }; |
| @@ -242,6 +243,21 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( | |||
| 242 | else | 243 | else |
| 243 | dmamode = DMA_MODE_WRITE; | 244 | dmamode = DMA_MODE_WRITE; |
| 244 | 245 | ||
| 246 | switch (imxdmac->word_size) { | ||
| 247 | case DMA_SLAVE_BUSWIDTH_4_BYTES: | ||
| 248 | if (sgl->length & 3 || sgl->dma_address & 3) | ||
| 249 | return NULL; | ||
| 250 | break; | ||
| 251 | case DMA_SLAVE_BUSWIDTH_2_BYTES: | ||
| 252 | if (sgl->length & 1 || sgl->dma_address & 1) | ||
| 253 | return NULL; | ||
| 254 | break; | ||
| 255 | case DMA_SLAVE_BUSWIDTH_1_BYTE: | ||
| 256 | break; | ||
| 257 | default: | ||
| 258 | return NULL; | ||
| 259 | } | ||
| 260 | |||
| 245 | ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, | 261 | ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, |
| 246 | dma_length, imxdmac->per_address, dmamode); | 262 | dma_length, imxdmac->per_address, dmamode); |
| 247 | if (ret) | 263 | if (ret) |
| @@ -329,6 +345,9 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
| 329 | 345 | ||
| 330 | INIT_LIST_HEAD(&imxdma->dma_device.channels); | 346 | INIT_LIST_HEAD(&imxdma->dma_device.channels); |
| 331 | 347 | ||
| 348 | dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); | ||
| 349 | dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); | ||
| 350 | |||
| 332 | /* Initialize channel parameters */ | 351 | /* Initialize channel parameters */ |
| 333 | for (i = 0; i < MAX_DMA_CHANNELS; i++) { | 352 | for (i = 0; i < MAX_DMA_CHANNELS; i++) { |
| 334 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; | 353 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; |
| @@ -346,11 +365,7 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
| 346 | imxdmac->imxdma = imxdma; | 365 | imxdmac->imxdma = imxdma; |
| 347 | spin_lock_init(&imxdmac->lock); | 366 | spin_lock_init(&imxdmac->lock); |
| 348 | 367 | ||
| 349 | dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); | ||
| 350 | dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); | ||
| 351 | |||
| 352 | imxdmac->chan.device = &imxdma->dma_device; | 368 | imxdmac->chan.device = &imxdma->dma_device; |
| 353 | imxdmac->chan.chan_id = i; | ||
| 354 | imxdmac->channel = i; | 369 | imxdmac->channel = i; |
| 355 | 370 | ||
| 356 | /* Add the channel to the DMAC list */ | 371 | /* Add the channel to the DMAC list */ |
| @@ -370,6 +385,9 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
| 370 | 385 | ||
| 371 | platform_set_drvdata(pdev, imxdma); | 386 | platform_set_drvdata(pdev, imxdma); |
| 372 | 387 | ||
| 388 | imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; | ||
| 389 | dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); | ||
| 390 | |||
| 373 | ret = dma_async_device_register(&imxdma->dma_device); | 391 | ret = dma_async_device_register(&imxdma->dma_device); |
| 374 | if (ret) { | 392 | if (ret) { |
| 375 | dev_err(&pdev->dev, "unable to register\n"); | 393 | dev_err(&pdev->dev, "unable to register\n"); |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d5a5d4d9c19..b6d1455fa93 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
| @@ -230,7 +230,7 @@ struct sdma_engine; | |||
| 230 | * struct sdma_channel - housekeeping for a SDMA channel | 230 | * struct sdma_channel - housekeeping for a SDMA channel |
| 231 | * | 231 | * |
| 232 | * @sdma pointer to the SDMA engine for this channel | 232 | * @sdma pointer to the SDMA engine for this channel |
| 233 | * @channel the channel number, matches dmaengine chan_id | 233 | * @channel the channel number, matches dmaengine chan_id + 1 |
| 234 | * @direction transfer type. Needed for setting SDMA script | 234 | * @direction transfer type. Needed for setting SDMA script |
| 235 | * @peripheral_type Peripheral type. Needed for setting SDMA script | 235 | * @peripheral_type Peripheral type. Needed for setting SDMA script |
| 236 | * @event_id0 aka dma request line | 236 | * @event_id0 aka dma request line |
| @@ -301,6 +301,7 @@ struct sdma_firmware_header { | |||
| 301 | 301 | ||
| 302 | struct sdma_engine { | 302 | struct sdma_engine { |
| 303 | struct device *dev; | 303 | struct device *dev; |
| 304 | struct device_dma_parameters dma_parms; | ||
| 304 | struct sdma_channel channel[MAX_DMA_CHANNELS]; | 305 | struct sdma_channel channel[MAX_DMA_CHANNELS]; |
| 305 | struct sdma_channel_control *channel_control; | 306 | struct sdma_channel_control *channel_control; |
| 306 | void __iomem *regs; | 307 | void __iomem *regs; |
| @@ -449,7 +450,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) | |||
| 449 | if (bd->mode.status & BD_RROR) | 450 | if (bd->mode.status & BD_RROR) |
| 450 | sdmac->status = DMA_ERROR; | 451 | sdmac->status = DMA_ERROR; |
| 451 | else | 452 | else |
| 452 | sdmac->status = DMA_SUCCESS; | 453 | sdmac->status = DMA_IN_PROGRESS; |
| 453 | 454 | ||
| 454 | bd->mode.status |= BD_DONE; | 455 | bd->mode.status |= BD_DONE; |
| 455 | sdmac->buf_tail++; | 456 | sdmac->buf_tail++; |
| @@ -770,15 +771,15 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel) | |||
| 770 | __raw_writel(1 << channel, sdma->regs + SDMA_H_START); | 771 | __raw_writel(1 << channel, sdma->regs + SDMA_H_START); |
| 771 | } | 772 | } |
| 772 | 773 | ||
| 773 | static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdma) | 774 | static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac) |
| 774 | { | 775 | { |
| 775 | dma_cookie_t cookie = sdma->chan.cookie; | 776 | dma_cookie_t cookie = sdmac->chan.cookie; |
| 776 | 777 | ||
| 777 | if (++cookie < 0) | 778 | if (++cookie < 0) |
| 778 | cookie = 1; | 779 | cookie = 1; |
| 779 | 780 | ||
| 780 | sdma->chan.cookie = cookie; | 781 | sdmac->chan.cookie = cookie; |
| 781 | sdma->desc.cookie = cookie; | 782 | sdmac->desc.cookie = cookie; |
| 782 | 783 | ||
| 783 | return cookie; | 784 | return cookie; |
| 784 | } | 785 | } |
| @@ -798,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 798 | 799 | ||
| 799 | cookie = sdma_assign_cookie(sdmac); | 800 | cookie = sdma_assign_cookie(sdmac); |
| 800 | 801 | ||
| 801 | sdma_enable_channel(sdma, tx->chan->chan_id); | 802 | sdma_enable_channel(sdma, sdmac->channel); |
| 802 | 803 | ||
| 803 | spin_unlock_irq(&sdmac->lock); | 804 | spin_unlock_irq(&sdmac->lock); |
| 804 | 805 | ||
| @@ -811,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) | |||
| 811 | struct imx_dma_data *data = chan->private; | 812 | struct imx_dma_data *data = chan->private; |
| 812 | int prio, ret; | 813 | int prio, ret; |
| 813 | 814 | ||
| 814 | /* No need to execute this for internal channel 0 */ | ||
| 815 | if (chan->chan_id == 0) | ||
| 816 | return 0; | ||
| 817 | |||
| 818 | if (!data) | 815 | if (!data) |
| 819 | return -EINVAL; | 816 | return -EINVAL; |
| 820 | 817 | ||
| @@ -879,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
| 879 | struct sdma_channel *sdmac = to_sdma_chan(chan); | 876 | struct sdma_channel *sdmac = to_sdma_chan(chan); |
| 880 | struct sdma_engine *sdma = sdmac->sdma; | 877 | struct sdma_engine *sdma = sdmac->sdma; |
| 881 | int ret, i, count; | 878 | int ret, i, count; |
| 882 | int channel = chan->chan_id; | 879 | int channel = sdmac->channel; |
| 883 | struct scatterlist *sg; | 880 | struct scatterlist *sg; |
| 884 | 881 | ||
| 885 | if (sdmac->status == DMA_IN_PROGRESS) | 882 | if (sdmac->status == DMA_IN_PROGRESS) |
| @@ -924,22 +921,33 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
| 924 | ret = -EINVAL; | 921 | ret = -EINVAL; |
| 925 | goto err_out; | 922 | goto err_out; |
| 926 | } | 923 | } |
| 927 | if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES) | 924 | |
| 925 | switch (sdmac->word_size) { | ||
| 926 | case DMA_SLAVE_BUSWIDTH_4_BYTES: | ||
| 928 | bd->mode.command = 0; | 927 | bd->mode.command = 0; |
| 929 | else | 928 | if (count & 3 || sg->dma_address & 3) |
| 930 | bd->mode.command = sdmac->word_size; | 929 | return NULL; |
| 930 | break; | ||
| 931 | case DMA_SLAVE_BUSWIDTH_2_BYTES: | ||
| 932 | bd->mode.command = 2; | ||
| 933 | if (count & 1 || sg->dma_address & 1) | ||
| 934 | return NULL; | ||
| 935 | break; | ||
| 936 | case DMA_SLAVE_BUSWIDTH_1_BYTE: | ||
| 937 | bd->mode.command = 1; | ||
| 938 | break; | ||
| 939 | default: | ||
| 940 | return NULL; | ||
| 941 | } | ||
| 931 | 942 | ||
| 932 | param = BD_DONE | BD_EXTD | BD_CONT; | 943 | param = BD_DONE | BD_EXTD | BD_CONT; |
| 933 | 944 | ||
| 934 | if (sdmac->flags & IMX_DMA_SG_LOOP) { | 945 | if (i + 1 == sg_len) { |
| 935 | param |= BD_INTR; | 946 | param |= BD_INTR; |
| 936 | if (i + 1 == sg_len) | 947 | param |= BD_LAST; |
| 937 | param |= BD_WRAP; | 948 | param &= ~BD_CONT; |
| 938 | } | 949 | } |
| 939 | 950 | ||
| 940 | if (i + 1 == sg_len) | ||
| 941 | param |= BD_INTR; | ||
| 942 | |||
| 943 | dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", | 951 | dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", |
| 944 | i, count, sg->dma_address, | 952 | i, count, sg->dma_address, |
| 945 | param & BD_WRAP ? "wrap" : "", | 953 | param & BD_WRAP ? "wrap" : "", |
| @@ -953,6 +961,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
| 953 | 961 | ||
| 954 | return &sdmac->desc; | 962 | return &sdmac->desc; |
| 955 | err_out: | 963 | err_out: |
| 964 | sdmac->status = DMA_ERROR; | ||
| 956 | return NULL; | 965 | return NULL; |
| 957 | } | 966 | } |
| 958 | 967 | ||
| @@ -963,7 +972,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( | |||
| 963 | struct sdma_channel *sdmac = to_sdma_chan(chan); | 972 | struct sdma_channel *sdmac = to_sdma_chan(chan); |
| 964 | struct sdma_engine *sdma = sdmac->sdma; | 973 | struct sdma_engine *sdma = sdmac->sdma; |
| 965 | int num_periods = buf_len / period_len; | 974 | int num_periods = buf_len / period_len; |
| 966 | int channel = chan->chan_id; | 975 | int channel = sdmac->channel; |
| 967 | int ret, i = 0, buf = 0; | 976 | int ret, i = 0, buf = 0; |
| 968 | 977 | ||
| 969 | dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); | 978 | dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); |
| @@ -1066,14 +1075,12 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, | |||
| 1066 | { | 1075 | { |
| 1067 | struct sdma_channel *sdmac = to_sdma_chan(chan); | 1076 | struct sdma_channel *sdmac = to_sdma_chan(chan); |
| 1068 | dma_cookie_t last_used; | 1077 | dma_cookie_t last_used; |
| 1069 | enum dma_status ret; | ||
| 1070 | 1078 | ||
| 1071 | last_used = chan->cookie; | 1079 | last_used = chan->cookie; |
| 1072 | 1080 | ||
| 1073 | ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used); | ||
| 1074 | dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); | 1081 | dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); |
| 1075 | 1082 | ||
| 1076 | return ret; | 1083 | return sdmac->status; |
| 1077 | } | 1084 | } |
| 1078 | 1085 | ||
| 1079 | static void sdma_issue_pending(struct dma_chan *chan) | 1086 | static void sdma_issue_pending(struct dma_chan *chan) |
| @@ -1135,7 +1142,7 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma, | |||
| 1135 | /* download the RAM image for SDMA */ | 1142 | /* download the RAM image for SDMA */ |
| 1136 | sdma_load_script(sdma, ram_code, | 1143 | sdma_load_script(sdma, ram_code, |
| 1137 | header->ram_code_size, | 1144 | header->ram_code_size, |
| 1138 | sdma->script_addrs->ram_code_start_addr); | 1145 | addr->ram_code_start_addr); |
| 1139 | clk_disable(sdma->clk); | 1146 | clk_disable(sdma->clk); |
| 1140 | 1147 | ||
| 1141 | sdma_add_scripts(sdma, addr); | 1148 | sdma_add_scripts(sdma, addr); |
| @@ -1237,7 +1244,6 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
| 1237 | struct resource *iores; | 1244 | struct resource *iores; |
| 1238 | struct sdma_platform_data *pdata = pdev->dev.platform_data; | 1245 | struct sdma_platform_data *pdata = pdev->dev.platform_data; |
| 1239 | int i; | 1246 | int i; |
| 1240 | dma_cap_mask_t mask; | ||
| 1241 | struct sdma_engine *sdma; | 1247 | struct sdma_engine *sdma; |
| 1242 | 1248 | ||
| 1243 | sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); | 1249 | sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); |
| @@ -1280,6 +1286,9 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
| 1280 | 1286 | ||
| 1281 | sdma->version = pdata->sdma_version; | 1287 | sdma->version = pdata->sdma_version; |
| 1282 | 1288 | ||
| 1289 | dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); | ||
| 1290 | dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); | ||
| 1291 | |||
| 1283 | INIT_LIST_HEAD(&sdma->dma_device.channels); | 1292 | INIT_LIST_HEAD(&sdma->dma_device.channels); |
| 1284 | /* Initialize channel parameters */ | 1293 | /* Initialize channel parameters */ |
| 1285 | for (i = 0; i < MAX_DMA_CHANNELS; i++) { | 1294 | for (i = 0; i < MAX_DMA_CHANNELS; i++) { |
| @@ -1288,15 +1297,17 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
| 1288 | sdmac->sdma = sdma; | 1297 | sdmac->sdma = sdma; |
| 1289 | spin_lock_init(&sdmac->lock); | 1298 | spin_lock_init(&sdmac->lock); |
| 1290 | 1299 | ||
| 1291 | dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); | ||
| 1292 | dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); | ||
| 1293 | |||
| 1294 | sdmac->chan.device = &sdma->dma_device; | 1300 | sdmac->chan.device = &sdma->dma_device; |
| 1295 | sdmac->chan.chan_id = i; | ||
| 1296 | sdmac->channel = i; | 1301 | sdmac->channel = i; |
| 1297 | 1302 | ||
| 1298 | /* Add the channel to the DMAC list */ | 1303 | /* |
| 1299 | list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); | 1304 | * Add the channel to the DMAC list. Do not add channel 0 though |
| 1305 | * because we need it internally in the SDMA driver. This also means | ||
| 1306 | * that channel 0 in dmaengine counting matches sdma channel 1. | ||
| 1307 | */ | ||
| 1308 | if (i) | ||
| 1309 | list_add_tail(&sdmac->chan.device_node, | ||
| 1310 | &sdma->dma_device.channels); | ||
| 1300 | } | 1311 | } |
| 1301 | 1312 | ||
| 1302 | ret = sdma_init(sdma); | 1313 | ret = sdma_init(sdma); |
| @@ -1317,6 +1328,8 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
| 1317 | sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; | 1328 | sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; |
| 1318 | sdma->dma_device.device_control = sdma_control; | 1329 | sdma->dma_device.device_control = sdma_control; |
| 1319 | sdma->dma_device.device_issue_pending = sdma_issue_pending; | 1330 | sdma->dma_device.device_issue_pending = sdma_issue_pending; |
| 1331 | sdma->dma_device.dev->dma_parms = &sdma->dma_parms; | ||
| 1332 | dma_set_max_seg_size(sdma->dma_device.dev, 65535); | ||
| 1320 | 1333 | ||
| 1321 | ret = dma_async_device_register(&sdma->dma_device); | 1334 | ret = dma_async_device_register(&sdma->dma_device); |
| 1322 | if (ret) { | 1335 | if (ret) { |
| @@ -1324,13 +1337,6 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
| 1324 | goto err_init; | 1337 | goto err_init; |
| 1325 | } | 1338 | } |
| 1326 | 1339 | ||
| 1327 | /* request channel 0. This is an internal control channel | ||
| 1328 | * to the SDMA engine and not available to clients. | ||
| 1329 | */ | ||
| 1330 | dma_cap_zero(mask); | ||
| 1331 | dma_cap_set(DMA_SLAVE, mask); | ||
| 1332 | dma_request_channel(mask, NULL, NULL); | ||
| 1333 | |||
| 1334 | dev_info(sdma->dev, "initialized\n"); | 1340 | dev_info(sdma->dev, "initialized\n"); |
| 1335 | 1341 | ||
| 1336 | return 0; | 1342 | return 0; |
| @@ -1348,7 +1354,7 @@ err_clk: | |||
| 1348 | err_request_region: | 1354 | err_request_region: |
| 1349 | err_irq: | 1355 | err_irq: |
| 1350 | kfree(sdma); | 1356 | kfree(sdma); |
| 1351 | return 0; | 1357 | return ret; |
| 1352 | } | 1358 | } |
| 1353 | 1359 | ||
| 1354 | static int __exit sdma_remove(struct platform_device *pdev) | 1360 | static int __exit sdma_remove(struct platform_device *pdev) |
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9773d..c1a125e7d1d 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c | |||
| @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, | |||
| 1145 | reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); | 1145 | reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); |
| 1146 | idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); | 1146 | idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); |
| 1147 | 1147 | ||
| 1148 | /* | ||
| 1149 | * Problem (observed with channel DMAIC_7): after enabling the channel | ||
| 1150 | * and initialising buffers, there comes an interrupt with current still | ||
| 1151 | * pointing at buffer 0, whereas it should use buffer 0 first and only | ||
| 1152 | * generate an interrupt when it is done, then current should already | ||
| 1153 | * point to buffer 1. This spurious interrupt also comes on channel | ||
| 1154 | * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the | ||
| 1155 | * first interrupt, there comes the second with current correctly | ||
| 1156 | * pointing to buffer 1 this time. But sometimes this second interrupt | ||
| 1157 | * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling | ||
| 1158 | * the channel seems to prevent the channel from hanging, but it doesn't | ||
| 1159 | * prevent the spurious interrupt. This might also be unsafe. Think | ||
| 1160 | * about the IDMAC controller trying to switch to a buffer, when we | ||
| 1161 | * clear the ready bit, and re-enable it a moment later. | ||
| 1162 | */ | ||
| 1163 | reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); | ||
| 1164 | idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); | ||
| 1165 | idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); | ||
| 1166 | |||
| 1167 | reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); | ||
| 1168 | idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); | ||
| 1169 | idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); | ||
| 1170 | |||
| 1171 | spin_unlock_irqrestore(&ipu->lock, flags); | 1148 | spin_unlock_irqrestore(&ipu->lock, flags); |
| 1172 | 1149 | ||
| 1173 | return 0; | 1150 | return 0; |
| @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) | |||
| 1246 | 1223 | ||
| 1247 | /* Other interrupts do not interfere with this channel */ | 1224 | /* Other interrupts do not interfere with this channel */ |
| 1248 | spin_lock(&ichan->lock); | 1225 | spin_lock(&ichan->lock); |
| 1249 | if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && | ||
| 1250 | ((curbuf >> chan_id) & 1) == ichan->active_buffer && | ||
| 1251 | !list_is_last(ichan->queue.next, &ichan->queue))) { | ||
| 1252 | int i = 100; | ||
| 1253 | |||
| 1254 | /* This doesn't help. See comment in ipu_disable_channel() */ | ||
| 1255 | while (--i) { | ||
| 1256 | curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); | ||
| 1257 | if (((curbuf >> chan_id) & 1) != ichan->active_buffer) | ||
| 1258 | break; | ||
| 1259 | cpu_relax(); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | if (!i) { | ||
| 1263 | spin_unlock(&ichan->lock); | ||
| 1264 | dev_dbg(dev, | ||
| 1265 | "IRQ on active buffer on channel %x, active " | ||
| 1266 | "%d, ready %x, %x, current %x!\n", chan_id, | ||
| 1267 | ichan->active_buffer, ready0, ready1, curbuf); | ||
| 1268 | return IRQ_NONE; | ||
| 1269 | } else | ||
| 1270 | dev_dbg(dev, | ||
| 1271 | "Buffer deactivated on channel %x, active " | ||
| 1272 | "%d, ready %x, %x, current %x, rest %d!\n", chan_id, | ||
| 1273 | ichan->active_buffer, ready0, ready1, curbuf, i); | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || | 1226 | if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || |
| 1277 | (!ichan->active_buffer && (ready0 >> chan_id) & 1) | 1227 | (!ichan->active_buffer && (ready0 >> chan_id) & 1) |
| 1278 | )) { | 1228 | )) { |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 4a5ecc58025..23e03554f0d 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
| @@ -826,8 +826,6 @@ static void amd64_dump_dramcfg_low(u32 dclr, int chan) | |||
| 826 | /* Display and decode various NB registers for debug purposes. */ | 826 | /* Display and decode various NB registers for debug purposes. */ |
| 827 | static void amd64_dump_misc_regs(struct amd64_pvt *pvt) | 827 | static void amd64_dump_misc_regs(struct amd64_pvt *pvt) |
| 828 | { | 828 | { |
| 829 | int ganged; | ||
| 830 | |||
| 831 | debugf1("F3xE8 (NB Cap): 0x%08x\n", pvt->nbcap); | 829 | debugf1("F3xE8 (NB Cap): 0x%08x\n", pvt->nbcap); |
| 832 | 830 | ||
| 833 | debugf1(" NB two channel DRAM capable: %s\n", | 831 | debugf1(" NB two channel DRAM capable: %s\n", |
| @@ -851,28 +849,19 @@ static void amd64_dump_misc_regs(struct amd64_pvt *pvt) | |||
| 851 | debugf1(" DramHoleValid: %s\n", | 849 | debugf1(" DramHoleValid: %s\n", |
| 852 | (pvt->dhar & DHAR_VALID) ? "yes" : "no"); | 850 | (pvt->dhar & DHAR_VALID) ? "yes" : "no"); |
| 853 | 851 | ||
| 852 | amd64_debug_display_dimm_sizes(0, pvt); | ||
| 853 | |||
| 854 | /* everything below this point is Fam10h and above */ | 854 | /* everything below this point is Fam10h and above */ |
| 855 | if (boot_cpu_data.x86 == 0xf) { | 855 | if (boot_cpu_data.x86 == 0xf) |
| 856 | amd64_debug_display_dimm_sizes(0, pvt); | ||
| 857 | return; | 856 | return; |
| 858 | } | 857 | |
| 858 | amd64_debug_display_dimm_sizes(1, pvt); | ||
| 859 | 859 | ||
| 860 | amd64_info("using %s syndromes.\n", ((pvt->syn_type == 8) ? "x8" : "x4")); | 860 | amd64_info("using %s syndromes.\n", ((pvt->syn_type == 8) ? "x8" : "x4")); |
| 861 | 861 | ||
| 862 | /* Only if NOT ganged does dclr1 have valid info */ | 862 | /* Only if NOT ganged does dclr1 have valid info */ |
| 863 | if (!dct_ganging_enabled(pvt)) | 863 | if (!dct_ganging_enabled(pvt)) |
| 864 | amd64_dump_dramcfg_low(pvt->dclr1, 1); | 864 | amd64_dump_dramcfg_low(pvt->dclr1, 1); |
| 865 | |||
| 866 | /* | ||
| 867 | * Determine if ganged and then dump memory sizes for first controller, | ||
| 868 | * and if NOT ganged dump info for 2nd controller. | ||
| 869 | */ | ||
| 870 | ganged = dct_ganging_enabled(pvt); | ||
| 871 | |||
| 872 | amd64_debug_display_dimm_sizes(0, pvt); | ||
| 873 | |||
| 874 | if (!ganged) | ||
| 875 | amd64_debug_display_dimm_sizes(1, pvt); | ||
| 876 | } | 865 | } |
| 877 | 866 | ||
| 878 | /* Read in both of DBAM registers */ | 867 | /* Read in both of DBAM registers */ |
| @@ -1644,11 +1633,10 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) | |||
| 1644 | WARN_ON(ctrl != 0); | 1633 | WARN_ON(ctrl != 0); |
| 1645 | } | 1634 | } |
| 1646 | 1635 | ||
| 1647 | debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n", | 1636 | dbam = (ctrl && !dct_ganging_enabled(pvt)) ? pvt->dbam1 : pvt->dbam0; |
| 1648 | ctrl, ctrl ? pvt->dbam1 : pvt->dbam0); | 1637 | dcsb = (ctrl && !dct_ganging_enabled(pvt)) ? pvt->dcsb1 : pvt->dcsb0; |
| 1649 | 1638 | ||
| 1650 | dbam = ctrl ? pvt->dbam1 : pvt->dbam0; | 1639 | debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n", ctrl, dbam); |
| 1651 | dcsb = ctrl ? pvt->dcsb1 : pvt->dcsb0; | ||
| 1652 | 1640 | ||
| 1653 | edac_printk(KERN_DEBUG, EDAC_MC, "DCT%d chip selects:\n", ctrl); | 1641 | edac_printk(KERN_DEBUG, EDAC_MC, "DCT%d chip selects:\n", ctrl); |
| 1654 | 1642 | ||
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e28e4166817..bcb1126e3d0 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
| @@ -378,10 +378,17 @@ static void __init print_filtered(const char *info) | |||
| 378 | 378 | ||
| 379 | static void __init dmi_dump_ids(void) | 379 | static void __init dmi_dump_ids(void) |
| 380 | { | 380 | { |
| 381 | const char *board; /* Board Name is optional */ | ||
| 382 | |||
| 381 | printk(KERN_DEBUG "DMI: "); | 383 | printk(KERN_DEBUG "DMI: "); |
| 382 | print_filtered(dmi_get_system_info(DMI_BOARD_NAME)); | 384 | print_filtered(dmi_get_system_info(DMI_SYS_VENDOR)); |
| 383 | printk(KERN_CONT "/"); | 385 | printk(KERN_CONT " "); |
| 384 | print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); | 386 | print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); |
| 387 | board = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 388 | if (board) { | ||
| 389 | printk(KERN_CONT "/"); | ||
| 390 | print_filtered(board); | ||
| 391 | } | ||
| 385 | printk(KERN_CONT ", BIOS "); | 392 | printk(KERN_CONT ", BIOS "); |
| 386 | print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); | 393 | print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); |
| 387 | printk(KERN_CONT " "); | 394 | printk(KERN_CONT " "); |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index a261972f603..b473429eee7 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
| @@ -60,6 +60,7 @@ struct pca953x_chip { | |||
| 60 | unsigned gpio_start; | 60 | unsigned gpio_start; |
| 61 | uint16_t reg_output; | 61 | uint16_t reg_output; |
| 62 | uint16_t reg_direction; | 62 | uint16_t reg_direction; |
| 63 | struct mutex i2c_lock; | ||
| 63 | 64 | ||
| 64 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 65 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
| 65 | struct mutex irq_lock; | 66 | struct mutex irq_lock; |
| @@ -119,13 +120,17 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) | |||
| 119 | 120 | ||
| 120 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 121 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| 121 | 122 | ||
| 123 | mutex_lock(&chip->i2c_lock); | ||
| 122 | reg_val = chip->reg_direction | (1u << off); | 124 | reg_val = chip->reg_direction | (1u << off); |
| 123 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 125 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); |
| 124 | if (ret) | 126 | if (ret) |
| 125 | return ret; | 127 | goto exit; |
| 126 | 128 | ||
| 127 | chip->reg_direction = reg_val; | 129 | chip->reg_direction = reg_val; |
| 128 | return 0; | 130 | ret = 0; |
| 131 | exit: | ||
| 132 | mutex_unlock(&chip->i2c_lock); | ||
| 133 | return ret; | ||
| 129 | } | 134 | } |
| 130 | 135 | ||
| 131 | static int pca953x_gpio_direction_output(struct gpio_chip *gc, | 136 | static int pca953x_gpio_direction_output(struct gpio_chip *gc, |
| @@ -137,6 +142,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
| 137 | 142 | ||
| 138 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 143 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| 139 | 144 | ||
| 145 | mutex_lock(&chip->i2c_lock); | ||
| 140 | /* set output level */ | 146 | /* set output level */ |
| 141 | if (val) | 147 | if (val) |
| 142 | reg_val = chip->reg_output | (1u << off); | 148 | reg_val = chip->reg_output | (1u << off); |
| @@ -145,7 +151,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
| 145 | 151 | ||
| 146 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 152 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); |
| 147 | if (ret) | 153 | if (ret) |
| 148 | return ret; | 154 | goto exit; |
| 149 | 155 | ||
| 150 | chip->reg_output = reg_val; | 156 | chip->reg_output = reg_val; |
| 151 | 157 | ||
| @@ -153,10 +159,13 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
| 153 | reg_val = chip->reg_direction & ~(1u << off); | 159 | reg_val = chip->reg_direction & ~(1u << off); |
| 154 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 160 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); |
| 155 | if (ret) | 161 | if (ret) |
| 156 | return ret; | 162 | goto exit; |
| 157 | 163 | ||
| 158 | chip->reg_direction = reg_val; | 164 | chip->reg_direction = reg_val; |
| 159 | return 0; | 165 | ret = 0; |
| 166 | exit: | ||
| 167 | mutex_unlock(&chip->i2c_lock); | ||
| 168 | return ret; | ||
| 160 | } | 169 | } |
| 161 | 170 | ||
| 162 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | 171 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) |
| @@ -167,7 +176,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | |||
| 167 | 176 | ||
| 168 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 177 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| 169 | 178 | ||
| 179 | mutex_lock(&chip->i2c_lock); | ||
| 170 | ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); | 180 | ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); |
| 181 | mutex_unlock(&chip->i2c_lock); | ||
| 171 | if (ret < 0) { | 182 | if (ret < 0) { |
| 172 | /* NOTE: diagnostic already emitted; that's all we should | 183 | /* NOTE: diagnostic already emitted; that's all we should |
| 173 | * do unless gpio_*_value_cansleep() calls become different | 184 | * do unless gpio_*_value_cansleep() calls become different |
| @@ -187,6 +198,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | |||
| 187 | 198 | ||
| 188 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 199 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
| 189 | 200 | ||
| 201 | mutex_lock(&chip->i2c_lock); | ||
| 190 | if (val) | 202 | if (val) |
| 191 | reg_val = chip->reg_output | (1u << off); | 203 | reg_val = chip->reg_output | (1u << off); |
| 192 | else | 204 | else |
| @@ -194,9 +206,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | |||
| 194 | 206 | ||
| 195 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 207 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); |
| 196 | if (ret) | 208 | if (ret) |
| 197 | return; | 209 | goto exit; |
| 198 | 210 | ||
| 199 | chip->reg_output = reg_val; | 211 | chip->reg_output = reg_val; |
| 212 | exit: | ||
| 213 | mutex_unlock(&chip->i2c_lock); | ||
| 200 | } | 214 | } |
| 201 | 215 | ||
| 202 | static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) | 216 | static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) |
| @@ -517,6 +531,8 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
| 517 | 531 | ||
| 518 | chip->names = pdata->names; | 532 | chip->names = pdata->names; |
| 519 | 533 | ||
| 534 | mutex_init(&chip->i2c_lock); | ||
| 535 | |||
| 520 | /* initialize cached registers from their original values. | 536 | /* initialize cached registers from their original values. |
| 521 | * we can't share this chip with another i2c master. | 537 | * we can't share this chip with another i2c master. |
| 522 | */ | 538 | */ |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 2baa6708e44..654faa803dc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2674,3 +2674,23 @@ out: | |||
| 2674 | mutex_unlock(&dev->mode_config.mutex); | 2674 | mutex_unlock(&dev->mode_config.mutex); |
| 2675 | return ret; | 2675 | return ret; |
| 2676 | } | 2676 | } |
| 2677 | |||
| 2678 | void drm_mode_config_reset(struct drm_device *dev) | ||
| 2679 | { | ||
| 2680 | struct drm_crtc *crtc; | ||
| 2681 | struct drm_encoder *encoder; | ||
| 2682 | struct drm_connector *connector; | ||
| 2683 | |||
| 2684 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
| 2685 | if (crtc->funcs->reset) | ||
| 2686 | crtc->funcs->reset(crtc); | ||
| 2687 | |||
| 2688 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
| 2689 | if (encoder->funcs->reset) | ||
| 2690 | encoder->funcs->reset(encoder); | ||
| 2691 | |||
| 2692 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
| 2693 | if (connector->funcs->reset) | ||
| 2694 | connector->funcs->reset(connector); | ||
| 2695 | } | ||
| 2696 | EXPORT_SYMBOL(drm_mode_config_reset); | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 952b3d4fb2a..92369655dca 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -343,13 +343,12 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
| 343 | struct drm_encoder *encoder; | 343 | struct drm_encoder *encoder; |
| 344 | bool ret = true; | 344 | bool ret = true; |
| 345 | 345 | ||
| 346 | adjusted_mode = drm_mode_duplicate(dev, mode); | ||
| 347 | |||
| 348 | crtc->enabled = drm_helper_crtc_in_use(crtc); | 346 | crtc->enabled = drm_helper_crtc_in_use(crtc); |
| 349 | |||
| 350 | if (!crtc->enabled) | 347 | if (!crtc->enabled) |
| 351 | return true; | 348 | return true; |
| 352 | 349 | ||
| 350 | adjusted_mode = drm_mode_duplicate(dev, mode); | ||
| 351 | |||
| 353 | saved_hwmode = crtc->hwmode; | 352 | saved_hwmode = crtc->hwmode; |
| 354 | saved_mode = crtc->mode; | 353 | saved_mode = crtc->mode; |
| 355 | saved_x = crtc->x; | 354 | saved_x = crtc->x; |
| @@ -437,10 +436,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
| 437 | */ | 436 | */ |
| 438 | drm_calc_timestamping_constants(crtc); | 437 | drm_calc_timestamping_constants(crtc); |
| 439 | 438 | ||
| 440 | /* XXX free adjustedmode */ | ||
| 441 | drm_mode_destroy(dev, adjusted_mode); | ||
| 442 | /* FIXME: add subpixel order */ | 439 | /* FIXME: add subpixel order */ |
| 443 | done: | 440 | done: |
| 441 | drm_mode_destroy(dev, adjusted_mode); | ||
| 444 | if (!ret) { | 442 | if (!ret) { |
| 445 | crtc->hwmode = saved_hwmode; | 443 | crtc->hwmode = saved_hwmode; |
| 446 | crtc->mode = saved_mode; | 444 | crtc->mode = saved_mode; |
| @@ -497,14 +495,17 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 497 | 495 | ||
| 498 | crtc_funcs = set->crtc->helper_private; | 496 | crtc_funcs = set->crtc->helper_private; |
| 499 | 497 | ||
| 498 | if (!set->mode) | ||
| 499 | set->fb = NULL; | ||
| 500 | |||
| 500 | if (set->fb) { | 501 | if (set->fb) { |
| 501 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", | 502 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", |
| 502 | set->crtc->base.id, set->fb->base.id, | 503 | set->crtc->base.id, set->fb->base.id, |
| 503 | (int)set->num_connectors, set->x, set->y); | 504 | (int)set->num_connectors, set->x, set->y); |
| 504 | } else { | 505 | } else { |
| 505 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB] #connectors=%d (x y) (%i %i)\n", | 506 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); |
| 506 | set->crtc->base.id, (int)set->num_connectors, | 507 | set->mode = NULL; |
| 507 | set->x, set->y); | 508 | set->num_connectors = 0; |
| 508 | } | 509 | } |
| 509 | 510 | ||
| 510 | dev = set->crtc->dev; | 511 | dev = set->crtc->dev; |
| @@ -649,8 +650,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 649 | mode_changed = true; | 650 | mode_changed = true; |
| 650 | 651 | ||
| 651 | if (mode_changed) { | 652 | if (mode_changed) { |
| 652 | set->crtc->enabled = (set->mode != NULL); | 653 | set->crtc->enabled = drm_helper_crtc_in_use(set->crtc); |
| 653 | if (set->mode != NULL) { | 654 | if (set->crtc->enabled) { |
| 654 | DRM_DEBUG_KMS("attempting to set mode from" | 655 | DRM_DEBUG_KMS("attempting to set mode from" |
| 655 | " userspace\n"); | 656 | " userspace\n"); |
| 656 | drm_mode_debug_printmodeline(set->mode); | 657 | drm_mode_debug_printmodeline(set->mode); |
| @@ -665,6 +666,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 665 | ret = -EINVAL; | 666 | ret = -EINVAL; |
| 666 | goto fail; | 667 | goto fail; |
| 667 | } | 668 | } |
| 669 | DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); | ||
| 670 | for (i = 0; i < set->num_connectors; i++) { | ||
| 671 | DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, | ||
| 672 | drm_get_connector_name(set->connectors[i])); | ||
| 673 | set->connectors[i]->dpms = DRM_MODE_DPMS_ON; | ||
| 674 | } | ||
| 668 | } | 675 | } |
| 669 | drm_helper_disable_unused_functions(dev); | 676 | drm_helper_disable_unused_functions(dev); |
| 670 | } else if (fb_changed) { | 677 | } else if (fb_changed) { |
| @@ -681,12 +688,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 681 | goto fail; | 688 | goto fail; |
| 682 | } | 689 | } |
| 683 | } | 690 | } |
| 684 | DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); | ||
| 685 | for (i = 0; i < set->num_connectors; i++) { | ||
| 686 | DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, | ||
| 687 | drm_get_connector_name(set->connectors[i])); | ||
| 688 | set->connectors[i]->dpms = DRM_MODE_DPMS_ON; | ||
| 689 | } | ||
| 690 | 691 | ||
| 691 | kfree(save_connectors); | 692 | kfree(save_connectors); |
| 692 | kfree(save_encoders); | 693 | kfree(save_encoders); |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 3cdbaf379bb..be9a9c07d15 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
| @@ -283,17 +283,18 @@ int drm_vma_info(struct seq_file *m, void *data) | |||
| 283 | #endif | 283 | #endif |
| 284 | 284 | ||
| 285 | mutex_lock(&dev->struct_mutex); | 285 | mutex_lock(&dev->struct_mutex); |
| 286 | seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n", | 286 | seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", |
| 287 | atomic_read(&dev->vma_count), | 287 | atomic_read(&dev->vma_count), |
| 288 | high_memory, (u64)virt_to_phys(high_memory)); | 288 | high_memory, (void *)virt_to_phys(high_memory)); |
| 289 | 289 | ||
| 290 | list_for_each_entry(pt, &dev->vmalist, head) { | 290 | list_for_each_entry(pt, &dev->vmalist, head) { |
| 291 | vma = pt->vma; | 291 | vma = pt->vma; |
| 292 | if (!vma) | 292 | if (!vma) |
| 293 | continue; | 293 | continue; |
| 294 | seq_printf(m, | 294 | seq_printf(m, |
| 295 | "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", | 295 | "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", |
| 296 | pt->pid, vma->vm_start, vma->vm_end, | 296 | pt->pid, |
| 297 | (void *)vma->vm_start, (void *)vma->vm_end, | ||
| 297 | vma->vm_flags & VM_READ ? 'r' : '-', | 298 | vma->vm_flags & VM_READ ? 'r' : '-', |
| 298 | vma->vm_flags & VM_WRITE ? 'w' : '-', | 299 | vma->vm_flags & VM_WRITE ? 'w' : '-', |
| 299 | vma->vm_flags & VM_EXEC ? 'x' : '-', | 300 | vma->vm_flags & VM_EXEC ? 'x' : '-', |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0054e957203..3dadfa2a852 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -1250,7 +1250,7 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) | |||
| 1250 | * Drivers should call this routine in their vblank interrupt handlers to | 1250 | * Drivers should call this routine in their vblank interrupt handlers to |
| 1251 | * update the vblank counter and send any signals that may be pending. | 1251 | * update the vblank counter and send any signals that may be pending. |
| 1252 | */ | 1252 | */ |
| 1253 | void drm_handle_vblank(struct drm_device *dev, int crtc) | 1253 | bool drm_handle_vblank(struct drm_device *dev, int crtc) |
| 1254 | { | 1254 | { |
| 1255 | u32 vblcount; | 1255 | u32 vblcount; |
| 1256 | s64 diff_ns; | 1256 | s64 diff_ns; |
| @@ -1258,7 +1258,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
| 1258 | unsigned long irqflags; | 1258 | unsigned long irqflags; |
| 1259 | 1259 | ||
| 1260 | if (!dev->num_crtcs) | 1260 | if (!dev->num_crtcs) |
| 1261 | return; | 1261 | return false; |
| 1262 | 1262 | ||
| 1263 | /* Need timestamp lock to prevent concurrent execution with | 1263 | /* Need timestamp lock to prevent concurrent execution with |
| 1264 | * vblank enable/disable, as this would cause inconsistent | 1264 | * vblank enable/disable, as this would cause inconsistent |
| @@ -1269,7 +1269,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
| 1269 | /* Vblank irq handling disabled. Nothing to do. */ | 1269 | /* Vblank irq handling disabled. Nothing to do. */ |
| 1270 | if (!dev->vblank_enabled[crtc]) { | 1270 | if (!dev->vblank_enabled[crtc]) { |
| 1271 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); | 1271 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); |
| 1272 | return; | 1272 | return false; |
| 1273 | } | 1273 | } |
| 1274 | 1274 | ||
| 1275 | /* Fetch corresponding timestamp for this vblank interval from | 1275 | /* Fetch corresponding timestamp for this vblank interval from |
| @@ -1311,5 +1311,6 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
| 1311 | drm_handle_vblank_events(dev, crtc); | 1311 | drm_handle_vblank_events(dev, crtc); |
| 1312 | 1312 | ||
| 1313 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); | 1313 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); |
| 1314 | return true; | ||
| 1314 | } | 1315 | } |
| 1315 | EXPORT_SYMBOL(drm_handle_vblank); | 1316 | EXPORT_SYMBOL(drm_handle_vblank); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 66796bb82d3..0ad533f06af 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | |||
| 46 | unsigned int i915_powersave = 1; | 46 | unsigned int i915_powersave = 1; |
| 47 | module_param_named(powersave, i915_powersave, int, 0600); | 47 | module_param_named(powersave, i915_powersave, int, 0600); |
| 48 | 48 | ||
| 49 | unsigned int i915_enable_rc6 = 0; | ||
| 50 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | ||
| 51 | |||
| 49 | unsigned int i915_lvds_downclock = 0; | 52 | unsigned int i915_lvds_downclock = 0; |
| 50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | 53 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); |
| 51 | 54 | ||
| @@ -354,12 +357,13 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
| 354 | error = i915_gem_init_ringbuffer(dev); | 357 | error = i915_gem_init_ringbuffer(dev); |
| 355 | mutex_unlock(&dev->struct_mutex); | 358 | mutex_unlock(&dev->struct_mutex); |
| 356 | 359 | ||
| 360 | drm_mode_config_reset(dev); | ||
| 357 | drm_irq_install(dev); | 361 | drm_irq_install(dev); |
| 358 | 362 | ||
| 359 | /* Resume the modeset for every activated CRTC */ | 363 | /* Resume the modeset for every activated CRTC */ |
| 360 | drm_helper_resume_force_mode(dev); | 364 | drm_helper_resume_force_mode(dev); |
| 361 | 365 | ||
| 362 | if (dev_priv->renderctx && dev_priv->pwrctx) | 366 | if (IS_IRONLAKE_M(dev)) |
| 363 | ironlake_enable_rc6(dev); | 367 | ironlake_enable_rc6(dev); |
| 364 | } | 368 | } |
| 365 | 369 | ||
| @@ -542,6 +546,7 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
| 542 | 546 | ||
| 543 | mutex_unlock(&dev->struct_mutex); | 547 | mutex_unlock(&dev->struct_mutex); |
| 544 | drm_irq_uninstall(dev); | 548 | drm_irq_uninstall(dev); |
| 549 | drm_mode_config_reset(dev); | ||
| 545 | drm_irq_install(dev); | 550 | drm_irq_install(dev); |
| 546 | mutex_lock(&dev->struct_mutex); | 551 | mutex_lock(&dev->struct_mutex); |
| 547 | } | 552 | } |
| @@ -566,6 +571,14 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
| 566 | static int __devinit | 571 | static int __devinit |
| 567 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 572 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 568 | { | 573 | { |
| 574 | /* Only bind to function 0 of the device. Early generations | ||
| 575 | * used function 1 as a placeholder for multi-head. This causes | ||
| 576 | * us confusion instead, especially on the systems where both | ||
| 577 | * functions have the same PCI-ID! | ||
| 578 | */ | ||
| 579 | if (PCI_FUNC(pdev->devfn)) | ||
| 580 | return -ENODEV; | ||
| 581 | |||
| 569 | return drm_get_pci_dev(pdev, ent, &driver); | 582 | return drm_get_pci_dev(pdev, ent, &driver); |
| 570 | } | 583 | } |
| 571 | 584 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a0149c619cd..65dfe81d003 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -958,6 +958,7 @@ extern unsigned int i915_fbpercrtc; | |||
| 958 | extern unsigned int i915_powersave; | 958 | extern unsigned int i915_powersave; |
| 959 | extern unsigned int i915_lvds_downclock; | 959 | extern unsigned int i915_lvds_downclock; |
| 960 | extern unsigned int i915_panel_use_ssc; | 960 | extern unsigned int i915_panel_use_ssc; |
| 961 | extern unsigned int i915_enable_rc6; | ||
| 961 | 962 | ||
| 962 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 963 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
| 963 | extern int i915_resume(struct drm_device *dev); | 964 | extern int i915_resume(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 062f353497e..97f946dcc1a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1196,18 +1196,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
| 1196 | intel_finish_page_flip_plane(dev, 1); | 1196 | intel_finish_page_flip_plane(dev, 1); |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | if (pipea_stats & vblank_status) { | 1199 | if (pipea_stats & vblank_status && |
| 1200 | drm_handle_vblank(dev, 0)) { | ||
| 1200 | vblank++; | 1201 | vblank++; |
| 1201 | drm_handle_vblank(dev, 0); | ||
| 1202 | if (!dev_priv->flip_pending_is_done) { | 1202 | if (!dev_priv->flip_pending_is_done) { |
| 1203 | i915_pageflip_stall_check(dev, 0); | 1203 | i915_pageflip_stall_check(dev, 0); |
| 1204 | intel_finish_page_flip(dev, 0); | 1204 | intel_finish_page_flip(dev, 0); |
| 1205 | } | 1205 | } |
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | if (pipeb_stats & vblank_status) { | 1208 | if (pipeb_stats & vblank_status && |
| 1209 | drm_handle_vblank(dev, 1)) { | ||
| 1209 | vblank++; | 1210 | vblank++; |
| 1210 | drm_handle_vblank(dev, 1); | ||
| 1211 | if (!dev_priv->flip_pending_is_done) { | 1211 | if (!dev_priv->flip_pending_is_done) { |
| 1212 | i915_pageflip_stall_check(dev, 1); | 1212 | i915_pageflip_stall_check(dev, 1); |
| 1213 | intel_finish_page_flip(dev, 1); | 1213 | intel_finish_page_flip(dev, 1); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5cfc68940f1..15d94c63918 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -174,7 +174,9 @@ | |||
| 174 | * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! | 174 | * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! |
| 175 | */ | 175 | */ |
| 176 | #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) | 176 | #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) |
| 177 | #define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ | 177 | #define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ |
| 178 | #define MI_INVALIDATE_TLB (1<<18) | ||
| 179 | #define MI_INVALIDATE_BSD (1<<7) | ||
| 178 | #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) | 180 | #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) |
| 179 | #define MI_BATCH_NON_SECURE (1) | 181 | #define MI_BATCH_NON_SECURE (1) |
| 180 | #define MI_BATCH_NON_SECURE_I965 (1<<8) | 182 | #define MI_BATCH_NON_SECURE_I965 (1<<8) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 17035b87ee4..8a77ff4a723 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -535,6 +535,15 @@ static int intel_crt_set_property(struct drm_connector *connector, | |||
| 535 | return 0; | 535 | return 0; |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | static void intel_crt_reset(struct drm_connector *connector) | ||
| 539 | { | ||
| 540 | struct drm_device *dev = connector->dev; | ||
| 541 | struct intel_crt *crt = intel_attached_crt(connector); | ||
| 542 | |||
| 543 | if (HAS_PCH_SPLIT(dev)) | ||
| 544 | crt->force_hotplug_required = 1; | ||
| 545 | } | ||
| 546 | |||
| 538 | /* | 547 | /* |
| 539 | * Routines for controlling stuff on the analog port | 548 | * Routines for controlling stuff on the analog port |
| 540 | */ | 549 | */ |
| @@ -548,6 +557,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { | |||
| 548 | }; | 557 | }; |
| 549 | 558 | ||
| 550 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 559 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
| 560 | .reset = intel_crt_reset, | ||
| 551 | .dpms = drm_helper_connector_dpms, | 561 | .dpms = drm_helper_connector_dpms, |
| 552 | .detect = intel_crt_detect, | 562 | .detect = intel_crt_detect, |
| 553 | .fill_modes = drm_helper_probe_single_connector_modes, | 563 | .fill_modes = drm_helper_probe_single_connector_modes, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d7f237deaaf..3b006536b3d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -5551,6 +5551,16 @@ cleanup_work: | |||
| 5551 | return ret; | 5551 | return ret; |
| 5552 | } | 5552 | } |
| 5553 | 5553 | ||
| 5554 | static void intel_crtc_reset(struct drm_crtc *crtc) | ||
| 5555 | { | ||
| 5556 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 5557 | |||
| 5558 | /* Reset flags back to the 'unknown' status so that they | ||
| 5559 | * will be correctly set on the initial modeset. | ||
| 5560 | */ | ||
| 5561 | intel_crtc->dpms_mode = -1; | ||
| 5562 | } | ||
| 5563 | |||
| 5554 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | 5564 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
| 5555 | .dpms = intel_crtc_dpms, | 5565 | .dpms = intel_crtc_dpms, |
| 5556 | .mode_fixup = intel_crtc_mode_fixup, | 5566 | .mode_fixup = intel_crtc_mode_fixup, |
| @@ -5562,6 +5572,7 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = { | |||
| 5562 | }; | 5572 | }; |
| 5563 | 5573 | ||
| 5564 | static const struct drm_crtc_funcs intel_crtc_funcs = { | 5574 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
| 5575 | .reset = intel_crtc_reset, | ||
| 5565 | .cursor_set = intel_crtc_cursor_set, | 5576 | .cursor_set = intel_crtc_cursor_set, |
| 5566 | .cursor_move = intel_crtc_cursor_move, | 5577 | .cursor_move = intel_crtc_cursor_move, |
| 5567 | .gamma_set = intel_crtc_gamma_set, | 5578 | .gamma_set = intel_crtc_gamma_set, |
| @@ -5652,8 +5663,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 5652 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; | 5663 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; |
| 5653 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 5664 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
| 5654 | 5665 | ||
| 5655 | intel_crtc->cursor_addr = 0; | 5666 | intel_crtc_reset(&intel_crtc->base); |
| 5656 | intel_crtc->dpms_mode = -1; | ||
| 5657 | intel_crtc->active = true; /* force the pipe off on setup_init_config */ | 5667 | intel_crtc->active = true; /* force the pipe off on setup_init_config */ |
| 5658 | 5668 | ||
| 5659 | if (HAS_PCH_SPLIT(dev)) { | 5669 | if (HAS_PCH_SPLIT(dev)) { |
| @@ -6452,52 +6462,60 @@ void intel_enable_clock_gating(struct drm_device *dev) | |||
| 6452 | } | 6462 | } |
| 6453 | } | 6463 | } |
| 6454 | 6464 | ||
| 6455 | void intel_disable_clock_gating(struct drm_device *dev) | 6465 | static void ironlake_teardown_rc6(struct drm_device *dev) |
| 6456 | { | 6466 | { |
| 6457 | struct drm_i915_private *dev_priv = dev->dev_private; | 6467 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 6458 | 6468 | ||
| 6459 | if (dev_priv->renderctx) { | 6469 | if (dev_priv->renderctx) { |
| 6460 | struct drm_i915_gem_object *obj = dev_priv->renderctx; | 6470 | i915_gem_object_unpin(dev_priv->renderctx); |
| 6461 | 6471 | drm_gem_object_unreference(&dev_priv->renderctx->base); | |
| 6462 | I915_WRITE(CCID, 0); | ||
| 6463 | POSTING_READ(CCID); | ||
| 6464 | |||
| 6465 | i915_gem_object_unpin(obj); | ||
| 6466 | drm_gem_object_unreference(&obj->base); | ||
| 6467 | dev_priv->renderctx = NULL; | 6472 | dev_priv->renderctx = NULL; |
| 6468 | } | 6473 | } |
| 6469 | 6474 | ||
| 6470 | if (dev_priv->pwrctx) { | 6475 | if (dev_priv->pwrctx) { |
| 6471 | struct drm_i915_gem_object *obj = dev_priv->pwrctx; | 6476 | i915_gem_object_unpin(dev_priv->pwrctx); |
| 6477 | drm_gem_object_unreference(&dev_priv->pwrctx->base); | ||
| 6478 | dev_priv->pwrctx = NULL; | ||
| 6479 | } | ||
| 6480 | } | ||
| 6481 | |||
| 6482 | static void ironlake_disable_rc6(struct drm_device *dev) | ||
| 6483 | { | ||
| 6484 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 6485 | |||
| 6486 | if (I915_READ(PWRCTXA)) { | ||
| 6487 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ | ||
| 6488 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); | ||
| 6489 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), | ||
| 6490 | 50); | ||
| 6472 | 6491 | ||
| 6473 | I915_WRITE(PWRCTXA, 0); | 6492 | I915_WRITE(PWRCTXA, 0); |
| 6474 | POSTING_READ(PWRCTXA); | 6493 | POSTING_READ(PWRCTXA); |
| 6475 | 6494 | ||
| 6476 | i915_gem_object_unpin(obj); | 6495 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
| 6477 | drm_gem_object_unreference(&obj->base); | 6496 | POSTING_READ(RSTDBYCTL); |
| 6478 | dev_priv->pwrctx = NULL; | ||
| 6479 | } | 6497 | } |
| 6498 | |||
| 6499 | ironlake_disable_rc6(dev); | ||
| 6480 | } | 6500 | } |
| 6481 | 6501 | ||
| 6482 | static void ironlake_disable_rc6(struct drm_device *dev) | 6502 | static int ironlake_setup_rc6(struct drm_device *dev) |
| 6483 | { | 6503 | { |
| 6484 | struct drm_i915_private *dev_priv = dev->dev_private; | 6504 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 6485 | 6505 | ||
| 6486 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ | 6506 | if (dev_priv->renderctx == NULL) |
| 6487 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); | 6507 | dev_priv->renderctx = intel_alloc_context_page(dev); |
| 6488 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), | 6508 | if (!dev_priv->renderctx) |
| 6489 | 10); | 6509 | return -ENOMEM; |
| 6490 | POSTING_READ(CCID); | 6510 | |
| 6491 | I915_WRITE(PWRCTXA, 0); | 6511 | if (dev_priv->pwrctx == NULL) |
| 6492 | POSTING_READ(PWRCTXA); | 6512 | dev_priv->pwrctx = intel_alloc_context_page(dev); |
| 6493 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | 6513 | if (!dev_priv->pwrctx) { |
| 6494 | POSTING_READ(RSTDBYCTL); | 6514 | ironlake_teardown_rc6(dev); |
| 6495 | i915_gem_object_unpin(dev_priv->renderctx); | 6515 | return -ENOMEM; |
| 6496 | drm_gem_object_unreference(&dev_priv->renderctx->base); | 6516 | } |
| 6497 | dev_priv->renderctx = NULL; | 6517 | |
| 6498 | i915_gem_object_unpin(dev_priv->pwrctx); | 6518 | return 0; |
| 6499 | drm_gem_object_unreference(&dev_priv->pwrctx->base); | ||
| 6500 | dev_priv->pwrctx = NULL; | ||
| 6501 | } | 6519 | } |
| 6502 | 6520 | ||
| 6503 | void ironlake_enable_rc6(struct drm_device *dev) | 6521 | void ironlake_enable_rc6(struct drm_device *dev) |
| @@ -6505,15 +6523,26 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
| 6505 | struct drm_i915_private *dev_priv = dev->dev_private; | 6523 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 6506 | int ret; | 6524 | int ret; |
| 6507 | 6525 | ||
| 6526 | /* rc6 disabled by default due to repeated reports of hanging during | ||
| 6527 | * boot and resume. | ||
| 6528 | */ | ||
| 6529 | if (!i915_enable_rc6) | ||
| 6530 | return; | ||
| 6531 | |||
| 6532 | ret = ironlake_setup_rc6(dev); | ||
| 6533 | if (ret) | ||
| 6534 | return; | ||
| 6535 | |||
| 6508 | /* | 6536 | /* |
| 6509 | * GPU can automatically power down the render unit if given a page | 6537 | * GPU can automatically power down the render unit if given a page |
| 6510 | * to save state. | 6538 | * to save state. |
| 6511 | */ | 6539 | */ |
| 6512 | ret = BEGIN_LP_RING(6); | 6540 | ret = BEGIN_LP_RING(6); |
| 6513 | if (ret) { | 6541 | if (ret) { |
| 6514 | ironlake_disable_rc6(dev); | 6542 | ironlake_teardown_rc6(dev); |
| 6515 | return; | 6543 | return; |
| 6516 | } | 6544 | } |
| 6545 | |||
| 6517 | OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); | 6546 | OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); |
| 6518 | OUT_RING(MI_SET_CONTEXT); | 6547 | OUT_RING(MI_SET_CONTEXT); |
| 6519 | OUT_RING(dev_priv->renderctx->gtt_offset | | 6548 | OUT_RING(dev_priv->renderctx->gtt_offset | |
| @@ -6530,6 +6559,7 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
| 6530 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | 6559 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
| 6531 | } | 6560 | } |
| 6532 | 6561 | ||
| 6562 | |||
| 6533 | /* Set up chip specific display functions */ | 6563 | /* Set up chip specific display functions */ |
| 6534 | static void intel_init_display(struct drm_device *dev) | 6564 | static void intel_init_display(struct drm_device *dev) |
| 6535 | { | 6565 | { |
| @@ -6772,21 +6802,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 6772 | if (IS_GEN6(dev)) | 6802 | if (IS_GEN6(dev)) |
| 6773 | gen6_enable_rps(dev_priv); | 6803 | gen6_enable_rps(dev_priv); |
| 6774 | 6804 | ||
| 6775 | if (IS_IRONLAKE_M(dev)) { | 6805 | if (IS_IRONLAKE_M(dev)) |
| 6776 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
| 6777 | if (!dev_priv->renderctx) | ||
| 6778 | goto skip_rc6; | ||
| 6779 | dev_priv->pwrctx = intel_alloc_context_page(dev); | ||
| 6780 | if (!dev_priv->pwrctx) { | ||
| 6781 | i915_gem_object_unpin(dev_priv->renderctx); | ||
| 6782 | drm_gem_object_unreference(&dev_priv->renderctx->base); | ||
| 6783 | dev_priv->renderctx = NULL; | ||
| 6784 | goto skip_rc6; | ||
| 6785 | } | ||
| 6786 | ironlake_enable_rc6(dev); | 6806 | ironlake_enable_rc6(dev); |
| 6787 | } | ||
| 6788 | 6807 | ||
| 6789 | skip_rc6: | ||
| 6790 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 6808 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
| 6791 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 6809 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
| 6792 | (unsigned long)dev); | 6810 | (unsigned long)dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1f4242b682c..51cb4e36997 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1639,6 +1639,24 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
| 1639 | return 0; | 1639 | return 0; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | static bool | ||
| 1643 | intel_dp_detect_audio(struct drm_connector *connector) | ||
| 1644 | { | ||
| 1645 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
| 1646 | struct edid *edid; | ||
| 1647 | bool has_audio = false; | ||
| 1648 | |||
| 1649 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
| 1650 | if (edid) { | ||
| 1651 | has_audio = drm_detect_monitor_audio(edid); | ||
| 1652 | |||
| 1653 | connector->display_info.raw_edid = NULL; | ||
| 1654 | kfree(edid); | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | return has_audio; | ||
| 1658 | } | ||
| 1659 | |||
| 1642 | static int | 1660 | static int |
| 1643 | intel_dp_set_property(struct drm_connector *connector, | 1661 | intel_dp_set_property(struct drm_connector *connector, |
| 1644 | struct drm_property *property, | 1662 | struct drm_property *property, |
| @@ -1652,17 +1670,23 @@ intel_dp_set_property(struct drm_connector *connector, | |||
| 1652 | return ret; | 1670 | return ret; |
| 1653 | 1671 | ||
| 1654 | if (property == intel_dp->force_audio_property) { | 1672 | if (property == intel_dp->force_audio_property) { |
| 1655 | if (val == intel_dp->force_audio) | 1673 | int i = val; |
| 1674 | bool has_audio; | ||
| 1675 | |||
| 1676 | if (i == intel_dp->force_audio) | ||
| 1656 | return 0; | 1677 | return 0; |
| 1657 | 1678 | ||
| 1658 | intel_dp->force_audio = val; | 1679 | intel_dp->force_audio = i; |
| 1659 | 1680 | ||
| 1660 | if (val > 0 && intel_dp->has_audio) | 1681 | if (i == 0) |
| 1661 | return 0; | 1682 | has_audio = intel_dp_detect_audio(connector); |
| 1662 | if (val < 0 && !intel_dp->has_audio) | 1683 | else |
| 1684 | has_audio = i > 0; | ||
| 1685 | |||
| 1686 | if (has_audio == intel_dp->has_audio) | ||
| 1663 | return 0; | 1687 | return 0; |
| 1664 | 1688 | ||
| 1665 | intel_dp->has_audio = val > 0; | 1689 | intel_dp->has_audio = has_audio; |
| 1666 | goto done; | 1690 | goto done; |
| 1667 | } | 1691 | } |
| 1668 | 1692 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 74db2557d64..2c431049963 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -298,7 +298,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
| 298 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 298 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
| 299 | u16 *blue, int regno); | 299 | u16 *blue, int regno); |
| 300 | extern void intel_enable_clock_gating(struct drm_device *dev); | 300 | extern void intel_enable_clock_gating(struct drm_device *dev); |
| 301 | extern void intel_disable_clock_gating(struct drm_device *dev); | ||
| 302 | extern void ironlake_enable_drps(struct drm_device *dev); | 301 | extern void ironlake_enable_drps(struct drm_device *dev); |
| 303 | extern void ironlake_disable_drps(struct drm_device *dev); | 302 | extern void ironlake_disable_drps(struct drm_device *dev); |
| 304 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); | 303 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 0d0273e7b02..c635c9e357b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -251,6 +251,27 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) | |||
| 251 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | 251 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | static bool | ||
| 255 | intel_hdmi_detect_audio(struct drm_connector *connector) | ||
| 256 | { | ||
| 257 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | ||
| 258 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
| 259 | struct edid *edid; | ||
| 260 | bool has_audio = false; | ||
| 261 | |||
| 262 | edid = drm_get_edid(connector, | ||
| 263 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | ||
| 264 | if (edid) { | ||
| 265 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
| 266 | has_audio = drm_detect_monitor_audio(edid); | ||
| 267 | |||
| 268 | connector->display_info.raw_edid = NULL; | ||
| 269 | kfree(edid); | ||
| 270 | } | ||
| 271 | |||
| 272 | return has_audio; | ||
| 273 | } | ||
| 274 | |||
| 254 | static int | 275 | static int |
| 255 | intel_hdmi_set_property(struct drm_connector *connector, | 276 | intel_hdmi_set_property(struct drm_connector *connector, |
| 256 | struct drm_property *property, | 277 | struct drm_property *property, |
| @@ -264,17 +285,23 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
| 264 | return ret; | 285 | return ret; |
| 265 | 286 | ||
| 266 | if (property == intel_hdmi->force_audio_property) { | 287 | if (property == intel_hdmi->force_audio_property) { |
| 267 | if (val == intel_hdmi->force_audio) | 288 | int i = val; |
| 289 | bool has_audio; | ||
| 290 | |||
| 291 | if (i == intel_hdmi->force_audio) | ||
| 268 | return 0; | 292 | return 0; |
| 269 | 293 | ||
| 270 | intel_hdmi->force_audio = val; | 294 | intel_hdmi->force_audio = i; |
| 271 | 295 | ||
| 272 | if (val > 0 && intel_hdmi->has_audio) | 296 | if (i == 0) |
| 273 | return 0; | 297 | has_audio = intel_hdmi_detect_audio(connector); |
| 274 | if (val < 0 && !intel_hdmi->has_audio) | 298 | else |
| 299 | has_audio = i > 0; | ||
| 300 | |||
| 301 | if (has_audio == intel_hdmi->has_audio) | ||
| 275 | return 0; | 302 | return 0; |
| 276 | 303 | ||
| 277 | intel_hdmi->has_audio = val > 0; | 304 | intel_hdmi->has_audio = has_audio; |
| 278 | goto done; | 305 | goto done; |
| 279 | } | 306 | } |
| 280 | 307 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index ace8d5d30dd..bcdba7bd5cf 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -261,12 +261,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 261 | return true; | 261 | return true; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | /* Make sure pre-965s set dither correctly */ | ||
| 265 | if (INTEL_INFO(dev)->gen < 4) { | ||
| 266 | if (dev_priv->lvds_dither) | ||
| 267 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
| 268 | } | ||
| 269 | |||
| 270 | /* Native modes don't need fitting */ | 264 | /* Native modes don't need fitting */ |
| 271 | if (adjusted_mode->hdisplay == mode->hdisplay && | 265 | if (adjusted_mode->hdisplay == mode->hdisplay && |
| 272 | adjusted_mode->vdisplay == mode->vdisplay) | 266 | adjusted_mode->vdisplay == mode->vdisplay) |
| @@ -374,10 +368,16 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 374 | } | 368 | } |
| 375 | 369 | ||
| 376 | out: | 370 | out: |
| 371 | /* If not enabling scaling, be consistent and always use 0. */ | ||
| 377 | if ((pfit_control & PFIT_ENABLE) == 0) { | 372 | if ((pfit_control & PFIT_ENABLE) == 0) { |
| 378 | pfit_control = 0; | 373 | pfit_control = 0; |
| 379 | pfit_pgm_ratios = 0; | 374 | pfit_pgm_ratios = 0; |
| 380 | } | 375 | } |
| 376 | |||
| 377 | /* Make sure pre-965 set dither correctly */ | ||
| 378 | if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) | ||
| 379 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
| 380 | |||
| 381 | if (pfit_control != intel_lvds->pfit_control || | 381 | if (pfit_control != intel_lvds->pfit_control || |
| 382 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { | 382 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { |
| 383 | intel_lvds->pfit_control = pfit_control; | 383 | intel_lvds->pfit_control = pfit_control; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6218fa97aa1..445f27efe67 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -1059,22 +1059,25 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | |||
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| 1061 | static int gen6_ring_flush(struct intel_ring_buffer *ring, | 1061 | static int gen6_ring_flush(struct intel_ring_buffer *ring, |
| 1062 | u32 invalidate_domains, | 1062 | u32 invalidate, u32 flush) |
| 1063 | u32 flush_domains) | ||
| 1064 | { | 1063 | { |
| 1064 | uint32_t cmd; | ||
| 1065 | int ret; | 1065 | int ret; |
| 1066 | 1066 | ||
| 1067 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) | 1067 | if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0) |
| 1068 | return 0; | 1068 | return 0; |
| 1069 | 1069 | ||
| 1070 | ret = intel_ring_begin(ring, 4); | 1070 | ret = intel_ring_begin(ring, 4); |
| 1071 | if (ret) | 1071 | if (ret) |
| 1072 | return ret; | 1072 | return ret; |
| 1073 | 1073 | ||
| 1074 | intel_ring_emit(ring, MI_FLUSH_DW); | 1074 | cmd = MI_FLUSH_DW; |
| 1075 | intel_ring_emit(ring, 0); | 1075 | if (invalidate & I915_GEM_GPU_DOMAINS) |
| 1076 | cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; | ||
| 1077 | intel_ring_emit(ring, cmd); | ||
| 1076 | intel_ring_emit(ring, 0); | 1078 | intel_ring_emit(ring, 0); |
| 1077 | intel_ring_emit(ring, 0); | 1079 | intel_ring_emit(ring, 0); |
| 1080 | intel_ring_emit(ring, MI_NOOP); | ||
| 1078 | intel_ring_advance(ring); | 1081 | intel_ring_advance(ring); |
| 1079 | return 0; | 1082 | return 0; |
| 1080 | } | 1083 | } |
| @@ -1230,22 +1233,25 @@ static int blt_ring_begin(struct intel_ring_buffer *ring, | |||
| 1230 | } | 1233 | } |
| 1231 | 1234 | ||
| 1232 | static int blt_ring_flush(struct intel_ring_buffer *ring, | 1235 | static int blt_ring_flush(struct intel_ring_buffer *ring, |
| 1233 | u32 invalidate_domains, | 1236 | u32 invalidate, u32 flush) |
| 1234 | u32 flush_domains) | ||
| 1235 | { | 1237 | { |
| 1238 | uint32_t cmd; | ||
| 1236 | int ret; | 1239 | int ret; |
| 1237 | 1240 | ||
| 1238 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) | 1241 | if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0) |
| 1239 | return 0; | 1242 | return 0; |
| 1240 | 1243 | ||
| 1241 | ret = blt_ring_begin(ring, 4); | 1244 | ret = blt_ring_begin(ring, 4); |
| 1242 | if (ret) | 1245 | if (ret) |
| 1243 | return ret; | 1246 | return ret; |
| 1244 | 1247 | ||
| 1245 | intel_ring_emit(ring, MI_FLUSH_DW); | 1248 | cmd = MI_FLUSH_DW; |
| 1246 | intel_ring_emit(ring, 0); | 1249 | if (invalidate & I915_GEM_DOMAIN_RENDER) |
| 1250 | cmd |= MI_INVALIDATE_TLB; | ||
| 1251 | intel_ring_emit(ring, cmd); | ||
| 1247 | intel_ring_emit(ring, 0); | 1252 | intel_ring_emit(ring, 0); |
| 1248 | intel_ring_emit(ring, 0); | 1253 | intel_ring_emit(ring, 0); |
| 1254 | intel_ring_emit(ring, MI_NOOP); | ||
| 1249 | intel_ring_advance(ring); | 1255 | intel_ring_advance(ring); |
| 1250 | return 0; | 1256 | return 0; |
| 1251 | } | 1257 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 45cd37652a3..7c50cdce84f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | SDVO_TV_MASK) | 46 | SDVO_TV_MASK) |
| 47 | 47 | ||
| 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
| 49 | #define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) | ||
| 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 50 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
| 50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | 51 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) |
| 51 | 52 | ||
| @@ -473,20 +474,6 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
| 473 | return false; | 474 | return false; |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | i = 3; | ||
| 477 | while (status == SDVO_CMD_STATUS_PENDING && i--) { | ||
| 478 | if (!intel_sdvo_read_byte(intel_sdvo, | ||
| 479 | SDVO_I2C_CMD_STATUS, | ||
| 480 | &status)) | ||
| 481 | return false; | ||
| 482 | } | ||
| 483 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 484 | DRM_DEBUG_KMS("command returns response %s [%d]\n", | ||
| 485 | status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP ? cmd_status_names[status] : "???", | ||
| 486 | status); | ||
| 487 | return false; | ||
| 488 | } | ||
| 489 | |||
| 490 | return true; | 477 | return true; |
| 491 | } | 478 | } |
| 492 | 479 | ||
| @@ -497,6 +484,8 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
| 497 | u8 status; | 484 | u8 status; |
| 498 | int i; | 485 | int i; |
| 499 | 486 | ||
| 487 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); | ||
| 488 | |||
| 500 | /* | 489 | /* |
| 501 | * The documentation states that all commands will be | 490 | * The documentation states that all commands will be |
| 502 | * processed within 15µs, and that we need only poll | 491 | * processed within 15µs, and that we need only poll |
| @@ -505,14 +494,19 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
| 505 | * | 494 | * |
| 506 | * Check 5 times in case the hardware failed to read the docs. | 495 | * Check 5 times in case the hardware failed to read the docs. |
| 507 | */ | 496 | */ |
| 508 | do { | 497 | if (!intel_sdvo_read_byte(intel_sdvo, |
| 498 | SDVO_I2C_CMD_STATUS, | ||
| 499 | &status)) | ||
| 500 | goto log_fail; | ||
| 501 | |||
| 502 | while (status == SDVO_CMD_STATUS_PENDING && retry--) { | ||
| 503 | udelay(15); | ||
| 509 | if (!intel_sdvo_read_byte(intel_sdvo, | 504 | if (!intel_sdvo_read_byte(intel_sdvo, |
| 510 | SDVO_I2C_CMD_STATUS, | 505 | SDVO_I2C_CMD_STATUS, |
| 511 | &status)) | 506 | &status)) |
| 512 | return false; | 507 | goto log_fail; |
| 513 | } while (status == SDVO_CMD_STATUS_PENDING && --retry); | 508 | } |
| 514 | 509 | ||
| 515 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); | ||
| 516 | if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) | 510 | if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) |
| 517 | DRM_LOG_KMS("(%s)", cmd_status_names[status]); | 511 | DRM_LOG_KMS("(%s)", cmd_status_names[status]); |
| 518 | else | 512 | else |
| @@ -533,7 +527,7 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
| 533 | return true; | 527 | return true; |
| 534 | 528 | ||
| 535 | log_fail: | 529 | log_fail: |
| 536 | DRM_LOG_KMS("\n"); | 530 | DRM_LOG_KMS("... failed\n"); |
| 537 | return false; | 531 | return false; |
| 538 | } | 532 | } |
| 539 | 533 | ||
| @@ -550,6 +544,7 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
| 550 | static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | 544 | static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
| 551 | u8 ddc_bus) | 545 | u8 ddc_bus) |
| 552 | { | 546 | { |
| 547 | /* This must be the immediately preceding write before the i2c xfer */ | ||
| 553 | return intel_sdvo_write_cmd(intel_sdvo, | 548 | return intel_sdvo_write_cmd(intel_sdvo, |
| 554 | SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 549 | SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
| 555 | &ddc_bus, 1); | 550 | &ddc_bus, 1); |
| @@ -557,7 +552,10 @@ static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | |||
| 557 | 552 | ||
| 558 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) | 553 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
| 559 | { | 554 | { |
| 560 | return intel_sdvo_write_cmd(intel_sdvo, cmd, data, len); | 555 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
| 556 | return false; | ||
| 557 | |||
| 558 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
| 561 | } | 559 | } |
| 562 | 560 | ||
| 563 | static bool | 561 | static bool |
| @@ -859,18 +857,21 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
| 859 | 857 | ||
| 860 | intel_dip_infoframe_csum(&avi_if); | 858 | intel_dip_infoframe_csum(&avi_if); |
| 861 | 859 | ||
| 862 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, | 860 | if (!intel_sdvo_set_value(intel_sdvo, |
| 861 | SDVO_CMD_SET_HBUF_INDEX, | ||
| 863 | set_buf_index, 2)) | 862 | set_buf_index, 2)) |
| 864 | return false; | 863 | return false; |
| 865 | 864 | ||
| 866 | for (i = 0; i < sizeof(avi_if); i += 8) { | 865 | for (i = 0; i < sizeof(avi_if); i += 8) { |
| 867 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, | 866 | if (!intel_sdvo_set_value(intel_sdvo, |
| 867 | SDVO_CMD_SET_HBUF_DATA, | ||
| 868 | data, 8)) | 868 | data, 8)) |
| 869 | return false; | 869 | return false; |
| 870 | data++; | 870 | data++; |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, | 873 | return intel_sdvo_set_value(intel_sdvo, |
| 874 | SDVO_CMD_SET_HBUF_TXRATE, | ||
| 874 | &tx_rate, 1); | 875 | &tx_rate, 1); |
| 875 | } | 876 | } |
| 876 | 877 | ||
| @@ -1359,7 +1360,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
| 1359 | intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); | 1360 | intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); |
| 1360 | intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); | 1361 | intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); |
| 1361 | } | 1362 | } |
| 1362 | } | 1363 | } else |
| 1364 | status = connector_status_disconnected; | ||
| 1363 | connector->display_info.raw_edid = NULL; | 1365 | connector->display_info.raw_edid = NULL; |
| 1364 | kfree(edid); | 1366 | kfree(edid); |
| 1365 | } | 1367 | } |
| @@ -1407,10 +1409,25 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
| 1407 | 1409 | ||
| 1408 | if ((intel_sdvo_connector->output_flag & response) == 0) | 1410 | if ((intel_sdvo_connector->output_flag & response) == 0) |
| 1409 | ret = connector_status_disconnected; | 1411 | ret = connector_status_disconnected; |
| 1410 | else if (response & SDVO_TMDS_MASK) | 1412 | else if (IS_TMDS(intel_sdvo_connector)) |
| 1411 | ret = intel_sdvo_hdmi_sink_detect(connector); | 1413 | ret = intel_sdvo_hdmi_sink_detect(connector); |
| 1412 | else | 1414 | else { |
| 1413 | ret = connector_status_connected; | 1415 | struct edid *edid; |
| 1416 | |||
| 1417 | /* if we have an edid check it matches the connection */ | ||
| 1418 | edid = intel_sdvo_get_edid(connector); | ||
| 1419 | if (edid == NULL) | ||
| 1420 | edid = intel_sdvo_get_analog_edid(connector); | ||
| 1421 | if (edid != NULL) { | ||
| 1422 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
| 1423 | ret = connector_status_disconnected; | ||
| 1424 | else | ||
| 1425 | ret = connector_status_connected; | ||
| 1426 | connector->display_info.raw_edid = NULL; | ||
| 1427 | kfree(edid); | ||
| 1428 | } else | ||
| 1429 | ret = connector_status_connected; | ||
| 1430 | } | ||
| 1414 | 1431 | ||
| 1415 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | 1432 | /* May update encoder flag for like clock for SDVO TV, etc.*/ |
| 1416 | if (ret == connector_status_connected) { | 1433 | if (ret == connector_status_connected) { |
| @@ -1446,10 +1463,15 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
| 1446 | edid = intel_sdvo_get_analog_edid(connector); | 1463 | edid = intel_sdvo_get_analog_edid(connector); |
| 1447 | 1464 | ||
| 1448 | if (edid != NULL) { | 1465 | if (edid != NULL) { |
| 1449 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 1466 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1467 | bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | ||
| 1468 | bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector); | ||
| 1469 | |||
| 1470 | if (connector_is_digital == monitor_is_digital) { | ||
| 1450 | drm_mode_connector_update_edid_property(connector, edid); | 1471 | drm_mode_connector_update_edid_property(connector, edid); |
| 1451 | drm_add_edid_modes(connector, edid); | 1472 | drm_add_edid_modes(connector, edid); |
| 1452 | } | 1473 | } |
| 1474 | |||
| 1453 | connector->display_info.raw_edid = NULL; | 1475 | connector->display_info.raw_edid = NULL; |
| 1454 | kfree(edid); | 1476 | kfree(edid); |
| 1455 | } | 1477 | } |
| @@ -1668,6 +1690,22 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
| 1668 | kfree(connector); | 1690 | kfree(connector); |
| 1669 | } | 1691 | } |
| 1670 | 1692 | ||
| 1693 | static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) | ||
| 1694 | { | ||
| 1695 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
| 1696 | struct edid *edid; | ||
| 1697 | bool has_audio = false; | ||
| 1698 | |||
| 1699 | if (!intel_sdvo->is_hdmi) | ||
| 1700 | return false; | ||
| 1701 | |||
| 1702 | edid = intel_sdvo_get_edid(connector); | ||
| 1703 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) | ||
| 1704 | has_audio = drm_detect_monitor_audio(edid); | ||
| 1705 | |||
| 1706 | return has_audio; | ||
| 1707 | } | ||
| 1708 | |||
| 1671 | static int | 1709 | static int |
| 1672 | intel_sdvo_set_property(struct drm_connector *connector, | 1710 | intel_sdvo_set_property(struct drm_connector *connector, |
| 1673 | struct drm_property *property, | 1711 | struct drm_property *property, |
| @@ -1684,17 +1722,23 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
| 1684 | return ret; | 1722 | return ret; |
| 1685 | 1723 | ||
| 1686 | if (property == intel_sdvo_connector->force_audio_property) { | 1724 | if (property == intel_sdvo_connector->force_audio_property) { |
| 1687 | if (val == intel_sdvo_connector->force_audio) | 1725 | int i = val; |
| 1726 | bool has_audio; | ||
| 1727 | |||
| 1728 | if (i == intel_sdvo_connector->force_audio) | ||
| 1688 | return 0; | 1729 | return 0; |
| 1689 | 1730 | ||
| 1690 | intel_sdvo_connector->force_audio = val; | 1731 | intel_sdvo_connector->force_audio = i; |
| 1691 | 1732 | ||
| 1692 | if (val > 0 && intel_sdvo->has_hdmi_audio) | 1733 | if (i == 0) |
| 1693 | return 0; | 1734 | has_audio = intel_sdvo_detect_hdmi_audio(connector); |
| 1694 | if (val < 0 && !intel_sdvo->has_hdmi_audio) | 1735 | else |
| 1736 | has_audio = i > 0; | ||
| 1737 | |||
| 1738 | if (has_audio == intel_sdvo->has_hdmi_audio) | ||
| 1695 | return 0; | 1739 | return 0; |
| 1696 | 1740 | ||
| 1697 | intel_sdvo->has_hdmi_audio = val > 0; | 1741 | intel_sdvo->has_hdmi_audio = has_audio; |
| 1698 | goto done; | 1742 | goto done; |
| 1699 | } | 1743 | } |
| 1700 | 1744 | ||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 93206e4eaa6..fe4a53a50b8 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -1234,7 +1234,8 @@ static const struct drm_display_mode reported_modes[] = { | |||
| 1234 | * \return false if TV is disconnected. | 1234 | * \return false if TV is disconnected. |
| 1235 | */ | 1235 | */ |
| 1236 | static int | 1236 | static int |
| 1237 | intel_tv_detect_type (struct intel_tv *intel_tv) | 1237 | intel_tv_detect_type (struct intel_tv *intel_tv, |
| 1238 | struct drm_connector *connector) | ||
| 1238 | { | 1239 | { |
| 1239 | struct drm_encoder *encoder = &intel_tv->base.base; | 1240 | struct drm_encoder *encoder = &intel_tv->base.base; |
| 1240 | struct drm_device *dev = encoder->dev; | 1241 | struct drm_device *dev = encoder->dev; |
| @@ -1245,11 +1246,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
| 1245 | int type; | 1246 | int type; |
| 1246 | 1247 | ||
| 1247 | /* Disable TV interrupts around load detect or we'll recurse */ | 1248 | /* Disable TV interrupts around load detect or we'll recurse */ |
| 1248 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 1249 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { |
| 1249 | i915_disable_pipestat(dev_priv, 0, | 1250 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
| 1250 | PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1251 | i915_disable_pipestat(dev_priv, 0, |
| 1251 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1252 | PIPE_HOTPLUG_INTERRUPT_ENABLE | |
| 1252 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1253 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); |
| 1254 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
| 1255 | } | ||
| 1253 | 1256 | ||
| 1254 | save_tv_dac = tv_dac = I915_READ(TV_DAC); | 1257 | save_tv_dac = tv_dac = I915_READ(TV_DAC); |
| 1255 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); | 1258 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); |
| @@ -1302,11 +1305,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
| 1302 | I915_WRITE(TV_CTL, save_tv_ctl); | 1305 | I915_WRITE(TV_CTL, save_tv_ctl); |
| 1303 | 1306 | ||
| 1304 | /* Restore interrupt config */ | 1307 | /* Restore interrupt config */ |
| 1305 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 1308 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { |
| 1306 | i915_enable_pipestat(dev_priv, 0, | 1309 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
| 1307 | PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1310 | i915_enable_pipestat(dev_priv, 0, |
| 1308 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1311 | PIPE_HOTPLUG_INTERRUPT_ENABLE | |
| 1309 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1312 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); |
| 1313 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
| 1314 | } | ||
| 1310 | 1315 | ||
| 1311 | return type; | 1316 | return type; |
| 1312 | } | 1317 | } |
| @@ -1356,7 +1361,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
| 1356 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1361 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
| 1357 | 1362 | ||
| 1358 | if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { | 1363 | if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { |
| 1359 | type = intel_tv_detect_type(intel_tv); | 1364 | type = intel_tv_detect_type(intel_tv, connector); |
| 1360 | } else if (force) { | 1365 | } else if (force) { |
| 1361 | struct drm_crtc *crtc; | 1366 | struct drm_crtc *crtc; |
| 1362 | int dpms_mode; | 1367 | int dpms_mode; |
| @@ -1364,7 +1369,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
| 1364 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | 1369 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, |
| 1365 | &mode, &dpms_mode); | 1370 | &mode, &dpms_mode); |
| 1366 | if (crtc) { | 1371 | if (crtc) { |
| 1367 | type = intel_tv_detect_type(intel_tv); | 1372 | type = intel_tv_detect_type(intel_tv, connector); |
| 1368 | intel_release_load_detect_pipe(&intel_tv->base, connector, | 1373 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
| 1369 | dpms_mode); | 1374 | dpms_mode); |
| 1370 | } else | 1375 | } else |
| @@ -1658,6 +1663,18 @@ intel_tv_init(struct drm_device *dev) | |||
| 1658 | intel_encoder = &intel_tv->base; | 1663 | intel_encoder = &intel_tv->base; |
| 1659 | connector = &intel_connector->base; | 1664 | connector = &intel_connector->base; |
| 1660 | 1665 | ||
| 1666 | /* The documentation, for the older chipsets at least, recommend | ||
| 1667 | * using a polling method rather than hotplug detection for TVs. | ||
| 1668 | * This is because in order to perform the hotplug detection, the PLLs | ||
| 1669 | * for the TV must be kept alive increasing power drain and starving | ||
| 1670 | * bandwidth from other encoders. Notably for instance, it causes | ||
| 1671 | * pipe underruns on Crestline when this encoder is supposedly idle. | ||
| 1672 | * | ||
| 1673 | * More recent chipsets favour HDMI rather than integrated S-Video. | ||
| 1674 | */ | ||
| 1675 | connector->polled = | ||
| 1676 | DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | ||
| 1677 | |||
| 1661 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1678 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
| 1662 | DRM_MODE_CONNECTOR_SVIDEO); | 1679 | DRM_MODE_CONNECTOR_SVIDEO); |
| 1663 | 1680 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 49e5e99917e..6bdab891c64 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -6228,7 +6228,7 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
| 6228 | entry->tvconf.has_component_output = false; | 6228 | entry->tvconf.has_component_output = false; |
| 6229 | break; | 6229 | break; |
| 6230 | case OUTPUT_LVDS: | 6230 | case OUTPUT_LVDS: |
| 6231 | if ((conn & 0x00003f00) != 0x10) | 6231 | if ((conn & 0x00003f00) >> 8 != 0x10) |
| 6232 | entry->lvdsconf.use_straps_for_mode = true; | 6232 | entry->lvdsconf.use_straps_for_mode = true; |
| 6233 | entry->lvdsconf.use_power_scripts = true; | 6233 | entry->lvdsconf.use_power_scripts = true; |
| 6234 | break; | 6234 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a7fae26f465..d38a4d9f9b0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -128,6 +128,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | nvbo->bo.mem.num_pages = size >> PAGE_SHIFT; | ||
| 131 | nouveau_bo_placement_set(nvbo, flags, 0); | 132 | nouveau_bo_placement_set(nvbo, flags, 0); |
| 132 | 133 | ||
| 133 | nvbo->channel = chan; | 134 | nvbo->channel = chan; |
| @@ -166,17 +167,17 @@ static void | |||
| 166 | set_placement_range(struct nouveau_bo *nvbo, uint32_t type) | 167 | set_placement_range(struct nouveau_bo *nvbo, uint32_t type) |
| 167 | { | 168 | { |
| 168 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | 169 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); |
| 170 | int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; | ||
| 169 | 171 | ||
| 170 | if (dev_priv->card_type == NV_10 && | 172 | if (dev_priv->card_type == NV_10 && |
| 171 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) { | 173 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && |
| 174 | nvbo->bo.mem.num_pages < vram_pages / 2) { | ||
| 172 | /* | 175 | /* |
| 173 | * Make sure that the color and depth buffers are handled | 176 | * Make sure that the color and depth buffers are handled |
| 174 | * by independent memory controller units. Up to a 9x | 177 | * by independent memory controller units. Up to a 9x |
| 175 | * speed up when alpha-blending and depth-test are enabled | 178 | * speed up when alpha-blending and depth-test are enabled |
| 176 | * at the same time. | 179 | * at the same time. |
| 177 | */ | 180 | */ |
| 178 | int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; | ||
| 179 | |||
| 180 | if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { | 181 | if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { |
| 181 | nvbo->placement.fpfn = vram_pages / 2; | 182 | nvbo->placement.fpfn = vram_pages / 2; |
| 182 | nvbo->placement.lpfn = ~0; | 183 | nvbo->placement.lpfn = ~0; |
| @@ -785,7 +786,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
| 785 | if (ret) | 786 | if (ret) |
| 786 | goto out; | 787 | goto out; |
| 787 | 788 | ||
| 788 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); | 789 | ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); |
| 789 | out: | 790 | out: |
| 790 | ttm_bo_mem_put(bo, &tmp_mem); | 791 | ttm_bo_mem_put(bo, &tmp_mem); |
| 791 | return ret; | 792 | return ret; |
| @@ -811,11 +812,11 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
| 811 | if (ret) | 812 | if (ret) |
| 812 | return ret; | 813 | return ret; |
| 813 | 814 | ||
| 814 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, &tmp_mem); | 815 | ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); |
| 815 | if (ret) | 816 | if (ret) |
| 816 | goto out; | 817 | goto out; |
| 817 | 818 | ||
| 818 | ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); | 819 | ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, new_mem); |
| 819 | if (ret) | 820 | if (ret) |
| 820 | goto out; | 821 | goto out; |
| 821 | 822 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a21e0007683..390d82c3c4b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -507,6 +507,7 @@ nouveau_connector_native_mode(struct drm_connector *connector) | |||
| 507 | int high_w = 0, high_h = 0, high_v = 0; | 507 | int high_w = 0, high_h = 0, high_v = 0; |
| 508 | 508 | ||
| 509 | list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { | 509 | list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { |
| 510 | mode->vrefresh = drm_mode_vrefresh(mode); | ||
| 510 | if (helper->mode_valid(connector, mode) != MODE_OK || | 511 | if (helper->mode_valid(connector, mode) != MODE_OK || |
| 511 | (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 512 | (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
| 512 | continue; | 513 | continue; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index fb846a3fef1..4399e2f34db 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
| @@ -443,7 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev) | |||
| 443 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 443 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
| 444 | 444 | ||
| 445 | if (pm->hwmon) { | 445 | if (pm->hwmon) { |
| 446 | sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); | 446 | sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); |
| 447 | hwmon_device_unregister(pm->hwmon); | 447 | hwmon_device_unregister(pm->hwmon); |
| 448 | } | 448 | } |
| 449 | #endif | 449 | #endif |
| @@ -543,7 +543,7 @@ nouveau_pm_resume(struct drm_device *dev) | |||
| 543 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 543 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
| 544 | struct nouveau_pm_level *perflvl; | 544 | struct nouveau_pm_level *perflvl; |
| 545 | 545 | ||
| 546 | if (pm->cur == &pm->boot) | 546 | if (!pm->cur || pm->cur == &pm->boot) |
| 547 | return; | 547 | return; |
| 548 | 548 | ||
| 549 | perflvl = pm->cur; | 549 | perflvl = pm->cur; |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index ef23550407b..c82db37d9f4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
| @@ -342,8 +342,8 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, | |||
| 342 | if (nv_encoder->dcb->type == OUTPUT_LVDS) { | 342 | if (nv_encoder->dcb->type == OUTPUT_LVDS) { |
| 343 | bool duallink, dummy; | 343 | bool duallink, dummy; |
| 344 | 344 | ||
| 345 | nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode-> | 345 | nouveau_bios_parse_lvds_table(dev, output_mode->clock, |
| 346 | clock, &duallink, &dummy); | 346 | &duallink, &dummy); |
| 347 | if (duallink) | 347 | if (duallink) |
| 348 | regp->fp_control |= (8 << 28); | 348 | regp->fp_control |= (8 << 28); |
| 349 | } else | 349 | } else |
| @@ -518,8 +518,6 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 518 | return; | 518 | return; |
| 519 | 519 | ||
| 520 | if (nv_encoder->dcb->lvdsconf.use_power_scripts) { | 520 | if (nv_encoder->dcb->lvdsconf.use_power_scripts) { |
| 521 | struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); | ||
| 522 | |||
| 523 | /* when removing an output, crtc may not be set, but PANEL_OFF | 521 | /* when removing an output, crtc may not be set, but PANEL_OFF |
| 524 | * must still be run | 522 | * must still be run |
| 525 | */ | 523 | */ |
| @@ -527,12 +525,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 527 | nv04_dfp_get_bound_head(dev, nv_encoder->dcb); | 525 | nv04_dfp_get_bound_head(dev, nv_encoder->dcb); |
| 528 | 526 | ||
| 529 | if (mode == DRM_MODE_DPMS_ON) { | 527 | if (mode == DRM_MODE_DPMS_ON) { |
| 530 | if (!nv_connector->native_mode) { | ||
| 531 | NV_ERROR(dev, "Not turning on LVDS without native mode\n"); | ||
| 532 | return; | ||
| 533 | } | ||
| 534 | call_lvds_script(dev, nv_encoder->dcb, head, | 528 | call_lvds_script(dev, nv_encoder->dcb, head, |
| 535 | LVDS_PANEL_ON, nv_connector->native_mode->clock); | 529 | LVDS_PANEL_ON, nv_encoder->mode.clock); |
| 536 | } else | 530 | } else |
| 537 | /* pxclk of 0 is fine for PANEL_OFF, and for a | 531 | /* pxclk of 0 is fine for PANEL_OFF, and for a |
| 538 | * disconnected LVDS encoder there is no native_mode | 532 | * disconnected LVDS encoder there is no native_mode |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 8870d72388c..18d30c2c1aa 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
| @@ -211,18 +211,32 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) | |||
| 211 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; | 211 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; |
| 212 | 212 | ||
| 213 | switch (dev_priv->chipset) { | 213 | switch (dev_priv->chipset) { |
| 214 | case 0x40: | ||
| 215 | case 0x41: /* guess */ | ||
| 216 | case 0x42: | ||
| 217 | case 0x43: | ||
| 218 | case 0x45: /* guess */ | ||
| 219 | case 0x4e: | ||
| 220 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); | ||
| 221 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); | ||
| 222 | nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); | ||
| 223 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); | ||
| 224 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); | ||
| 225 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); | ||
| 226 | break; | ||
| 214 | case 0x44: | 227 | case 0x44: |
| 215 | case 0x4a: | 228 | case 0x4a: |
| 216 | case 0x4e: | ||
| 217 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); | 229 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); |
| 218 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); | 230 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); |
| 219 | nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); | 231 | nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); |
| 220 | break; | 232 | break; |
| 221 | |||
| 222 | case 0x46: | 233 | case 0x46: |
| 223 | case 0x47: | 234 | case 0x47: |
| 224 | case 0x49: | 235 | case 0x49: |
| 225 | case 0x4b: | 236 | case 0x4b: |
| 237 | case 0x4c: | ||
| 238 | case 0x67: | ||
| 239 | default: | ||
| 226 | nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); | 240 | nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); |
| 227 | nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); | 241 | nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); |
| 228 | nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); | 242 | nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); |
| @@ -230,15 +244,6 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) | |||
| 230 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); | 244 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); |
| 231 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); | 245 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); |
| 232 | break; | 246 | break; |
| 233 | |||
| 234 | default: | ||
| 235 | nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); | ||
| 236 | nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); | ||
| 237 | nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); | ||
| 238 | nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); | ||
| 239 | nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); | ||
| 240 | nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); | ||
| 241 | break; | ||
| 242 | } | 247 | } |
| 243 | } | 248 | } |
| 244 | 249 | ||
| @@ -396,17 +401,20 @@ nv40_graph_init(struct drm_device *dev) | |||
| 396 | break; | 401 | break; |
| 397 | default: | 402 | default: |
| 398 | switch (dev_priv->chipset) { | 403 | switch (dev_priv->chipset) { |
| 399 | case 0x46: | 404 | case 0x41: |
| 400 | case 0x47: | 405 | case 0x42: |
| 401 | case 0x49: | 406 | case 0x43: |
| 402 | case 0x4b: | 407 | case 0x45: |
| 403 | nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); | 408 | case 0x4e: |
| 404 | nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); | 409 | case 0x44: |
| 405 | break; | 410 | case 0x4a: |
| 406 | default: | ||
| 407 | nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); | 411 | nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); |
| 408 | nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); | 412 | nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); |
| 409 | break; | 413 | break; |
| 414 | default: | ||
| 415 | nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); | ||
| 416 | nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); | ||
| 417 | break; | ||
| 410 | } | 418 | } |
| 411 | nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); | 419 | nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); |
| 412 | nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); | 420 | nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); |
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index 14e24e906ee..0ea090f4244 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c | |||
| @@ -283,8 +283,7 @@ nv50_evo_create(struct drm_device *dev) | |||
| 283 | nv50_evo_channel_del(&dev_priv->evo); | 283 | nv50_evo_channel_del(&dev_priv->evo); |
| 284 | return ret; | 284 | return ret; |
| 285 | } | 285 | } |
| 286 | } else | 286 | } else { |
| 287 | if (dev_priv->chipset != 0x50) { | ||
| 288 | ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, | 287 | ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, |
| 289 | 0, 0xffffffff, 0x00010000); | 288 | 0, 0xffffffff, 0x00010000); |
| 290 | if (ret) { | 289 | if (ret) { |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 842954fe74c..a4e5e53e0a6 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -48,29 +48,29 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
| 48 | 48 | ||
| 49 | switch (radeon_crtc->rmx_type) { | 49 | switch (radeon_crtc->rmx_type) { |
| 50 | case RMX_CENTER: | 50 | case RMX_CENTER: |
| 51 | args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; | 51 | args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); |
| 52 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; | 52 | args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); |
| 53 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 53 | args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); |
| 54 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 54 | args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); |
| 55 | break; | 55 | break; |
| 56 | case RMX_ASPECT: | 56 | case RMX_ASPECT: |
| 57 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; | 57 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; |
| 58 | a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; | 58 | a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; |
| 59 | 59 | ||
| 60 | if (a1 > a2) { | 60 | if (a1 > a2) { |
| 61 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; | 61 | args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); |
| 62 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; | 62 | args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); |
| 63 | } else if (a2 > a1) { | 63 | } else if (a2 > a1) { |
| 64 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 64 | args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); |
| 65 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 65 | args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); |
| 66 | } | 66 | } |
| 67 | break; | 67 | break; |
| 68 | case RMX_FULL: | 68 | case RMX_FULL: |
| 69 | default: | 69 | default: |
| 70 | args.usOverscanRight = radeon_crtc->h_border; | 70 | args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border); |
| 71 | args.usOverscanLeft = radeon_crtc->h_border; | 71 | args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border); |
| 72 | args.usOverscanBottom = radeon_crtc->v_border; | 72 | args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border); |
| 73 | args.usOverscanTop = radeon_crtc->v_border; | 73 | args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border); |
| 74 | break; | 74 | break; |
| 75 | } | 75 | } |
| 76 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 76 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| @@ -419,23 +419,23 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
| 419 | memset(&args, 0, sizeof(args)); | 419 | memset(&args, 0, sizeof(args)); |
| 420 | 420 | ||
| 421 | if (ASIC_IS_DCE5(rdev)) { | 421 | if (ASIC_IS_DCE5(rdev)) { |
| 422 | args.v3.usSpreadSpectrumAmountFrac = 0; | 422 | args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); |
| 423 | args.v3.ucSpreadSpectrumType = ss->type; | 423 | args.v3.ucSpreadSpectrumType = ss->type; |
| 424 | switch (pll_id) { | 424 | switch (pll_id) { |
| 425 | case ATOM_PPLL1: | 425 | case ATOM_PPLL1: |
| 426 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; | 426 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; |
| 427 | args.v3.usSpreadSpectrumAmount = ss->amount; | 427 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
| 428 | args.v3.usSpreadSpectrumStep = ss->step; | 428 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
| 429 | break; | 429 | break; |
| 430 | case ATOM_PPLL2: | 430 | case ATOM_PPLL2: |
| 431 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; | 431 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; |
| 432 | args.v3.usSpreadSpectrumAmount = ss->amount; | 432 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
| 433 | args.v3.usSpreadSpectrumStep = ss->step; | 433 | args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
| 434 | break; | 434 | break; |
| 435 | case ATOM_DCPLL: | 435 | case ATOM_DCPLL: |
| 436 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; | 436 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; |
| 437 | args.v3.usSpreadSpectrumAmount = 0; | 437 | args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); |
| 438 | args.v3.usSpreadSpectrumStep = 0; | 438 | args.v3.usSpreadSpectrumStep = cpu_to_le16(0); |
| 439 | break; | 439 | break; |
| 440 | case ATOM_PPLL_INVALID: | 440 | case ATOM_PPLL_INVALID: |
| 441 | return; | 441 | return; |
| @@ -447,18 +447,18 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
| 447 | switch (pll_id) { | 447 | switch (pll_id) { |
| 448 | case ATOM_PPLL1: | 448 | case ATOM_PPLL1: |
| 449 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; | 449 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; |
| 450 | args.v2.usSpreadSpectrumAmount = ss->amount; | 450 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
| 451 | args.v2.usSpreadSpectrumStep = ss->step; | 451 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
| 452 | break; | 452 | break; |
| 453 | case ATOM_PPLL2: | 453 | case ATOM_PPLL2: |
| 454 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; | 454 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; |
| 455 | args.v2.usSpreadSpectrumAmount = ss->amount; | 455 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); |
| 456 | args.v2.usSpreadSpectrumStep = ss->step; | 456 | args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); |
| 457 | break; | 457 | break; |
| 458 | case ATOM_DCPLL: | 458 | case ATOM_DCPLL: |
| 459 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; | 459 | args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; |
| 460 | args.v2.usSpreadSpectrumAmount = 0; | 460 | args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); |
| 461 | args.v2.usSpreadSpectrumStep = 0; | 461 | args.v2.usSpreadSpectrumStep = cpu_to_le16(0); |
| 462 | break; | 462 | break; |
| 463 | case ATOM_PPLL_INVALID: | 463 | case ATOM_PPLL_INVALID: |
| 464 | return; | 464 | return; |
| @@ -538,7 +538,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 538 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 538 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 539 | else | 539 | else |
| 540 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 540 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 541 | |||
| 542 | } | 541 | } |
| 543 | 542 | ||
| 544 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 543 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| @@ -555,23 +554,28 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 555 | dp_clock = dig_connector->dp_clock; | 554 | dp_clock = dig_connector->dp_clock; |
| 556 | } | 555 | } |
| 557 | } | 556 | } |
| 558 | #if 0 /* doesn't work properly on some laptops */ | 557 | |
| 559 | /* use recommended ref_div for ss */ | 558 | /* use recommended ref_div for ss */ |
| 560 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 559 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
| 561 | if (ss_enabled) { | 560 | if (ss_enabled) { |
| 562 | if (ss->refdiv) { | 561 | if (ss->refdiv) { |
| 562 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | ||
| 563 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 563 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
| 564 | pll->reference_div = ss->refdiv; | 564 | pll->reference_div = ss->refdiv; |
| 565 | if (ASIC_IS_AVIVO(rdev)) | ||
| 566 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | ||
| 565 | } | 567 | } |
| 566 | } | 568 | } |
| 567 | } | 569 | } |
| 568 | #endif | 570 | |
| 569 | if (ASIC_IS_AVIVO(rdev)) { | 571 | if (ASIC_IS_AVIVO(rdev)) { |
| 570 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 572 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
| 571 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 573 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
| 572 | adjusted_clock = mode->clock * 2; | 574 | adjusted_clock = mode->clock * 2; |
| 573 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 575 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
| 574 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 576 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
| 577 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 578 | pll->flags |= RADEON_PLL_IS_LCD; | ||
| 575 | } else { | 579 | } else { |
| 576 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 580 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
| 577 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 581 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
| @@ -658,10 +662,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 658 | index, (uint32_t *)&args); | 662 | index, (uint32_t *)&args); |
| 659 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; | 663 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; |
| 660 | if (args.v3.sOutput.ucRefDiv) { | 664 | if (args.v3.sOutput.ucRefDiv) { |
| 665 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | ||
| 661 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 666 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
| 662 | pll->reference_div = args.v3.sOutput.ucRefDiv; | 667 | pll->reference_div = args.v3.sOutput.ucRefDiv; |
| 663 | } | 668 | } |
| 664 | if (args.v3.sOutput.ucPostDiv) { | 669 | if (args.v3.sOutput.ucPostDiv) { |
| 670 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | ||
| 665 | pll->flags |= RADEON_PLL_USE_POST_DIV; | 671 | pll->flags |= RADEON_PLL_USE_POST_DIV; |
| 666 | pll->post_div = args.v3.sOutput.ucPostDiv; | 672 | pll->post_div = args.v3.sOutput.ucPostDiv; |
| 667 | } | 673 | } |
| @@ -715,14 +721,14 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, | |||
| 715 | * SetPixelClock provides the dividers | 721 | * SetPixelClock provides the dividers |
| 716 | */ | 722 | */ |
| 717 | args.v5.ucCRTC = ATOM_CRTC_INVALID; | 723 | args.v5.ucCRTC = ATOM_CRTC_INVALID; |
| 718 | args.v5.usPixelClock = dispclk; | 724 | args.v5.usPixelClock = cpu_to_le16(dispclk); |
| 719 | args.v5.ucPpll = ATOM_DCPLL; | 725 | args.v5.ucPpll = ATOM_DCPLL; |
| 720 | break; | 726 | break; |
| 721 | case 6: | 727 | case 6: |
| 722 | /* if the default dcpll clock is specified, | 728 | /* if the default dcpll clock is specified, |
| 723 | * SetPixelClock provides the dividers | 729 | * SetPixelClock provides the dividers |
| 724 | */ | 730 | */ |
| 725 | args.v6.ulDispEngClkFreq = dispclk; | 731 | args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); |
| 726 | args.v6.ucPpll = ATOM_DCPLL; | 732 | args.v6.ucPpll = ATOM_DCPLL; |
| 727 | break; | 733 | break; |
| 728 | default: | 734 | default: |
| @@ -951,8 +957,12 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 951 | /* adjust pixel clock as needed */ | 957 | /* adjust pixel clock as needed */ |
| 952 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); | 958 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); |
| 953 | 959 | ||
| 954 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 960 | if (ASIC_IS_AVIVO(rdev)) |
| 955 | &ref_div, &post_div); | 961 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
| 962 | &ref_div, &post_div); | ||
| 963 | else | ||
| 964 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
| 965 | &ref_div, &post_div); | ||
| 956 | 966 | ||
| 957 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); | 967 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); |
| 958 | 968 | ||
| @@ -981,9 +991,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 981 | } | 991 | } |
| 982 | } | 992 | } |
| 983 | 993 | ||
| 984 | static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, | 994 | static int dce4_crtc_do_set_base(struct drm_crtc *crtc, |
| 985 | struct drm_framebuffer *fb, | 995 | struct drm_framebuffer *fb, |
| 986 | int x, int y, int atomic) | 996 | int x, int y, int atomic) |
| 987 | { | 997 | { |
| 988 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 998 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 989 | struct drm_device *dev = crtc->dev; | 999 | struct drm_device *dev = crtc->dev; |
| @@ -1123,12 +1133,6 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1123 | WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, | 1133 | WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, |
| 1124 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); | 1134 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); |
| 1125 | 1135 | ||
| 1126 | if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1127 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1128 | EVERGREEN_INTERLEAVE_EN); | ||
| 1129 | else | ||
| 1130 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1131 | |||
| 1132 | if (!atomic && fb && fb != crtc->fb) { | 1136 | if (!atomic && fb && fb != crtc->fb) { |
| 1133 | radeon_fb = to_radeon_framebuffer(fb); | 1137 | radeon_fb = to_radeon_framebuffer(fb); |
| 1134 | rbo = radeon_fb->obj->driver_private; | 1138 | rbo = radeon_fb->obj->driver_private; |
| @@ -1286,12 +1290,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1286 | WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, | 1290 | WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, |
| 1287 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); | 1291 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); |
| 1288 | 1292 | ||
| 1289 | if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1290 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1291 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
| 1292 | else | ||
| 1293 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1294 | |||
| 1295 | if (!atomic && fb && fb != crtc->fb) { | 1293 | if (!atomic && fb && fb != crtc->fb) { |
| 1296 | radeon_fb = to_radeon_framebuffer(fb); | 1294 | radeon_fb = to_radeon_framebuffer(fb); |
| 1297 | rbo = radeon_fb->obj->driver_private; | 1295 | rbo = radeon_fb->obj->driver_private; |
| @@ -1315,7 +1313,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1315 | struct radeon_device *rdev = dev->dev_private; | 1313 | struct radeon_device *rdev = dev->dev_private; |
| 1316 | 1314 | ||
| 1317 | if (ASIC_IS_DCE4(rdev)) | 1315 | if (ASIC_IS_DCE4(rdev)) |
| 1318 | return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0); | 1316 | return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0); |
| 1319 | else if (ASIC_IS_AVIVO(rdev)) | 1317 | else if (ASIC_IS_AVIVO(rdev)) |
| 1320 | return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); | 1318 | return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); |
| 1321 | else | 1319 | else |
| @@ -1330,7 +1328,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, | |||
| 1330 | struct radeon_device *rdev = dev->dev_private; | 1328 | struct radeon_device *rdev = dev->dev_private; |
| 1331 | 1329 | ||
| 1332 | if (ASIC_IS_DCE4(rdev)) | 1330 | if (ASIC_IS_DCE4(rdev)) |
| 1333 | return evergreen_crtc_do_set_base(crtc, fb, x, y, 1); | 1331 | return dce4_crtc_do_set_base(crtc, fb, x, y, 1); |
| 1334 | else if (ASIC_IS_AVIVO(rdev)) | 1332 | else if (ASIC_IS_AVIVO(rdev)) |
| 1335 | return avivo_crtc_do_set_base(crtc, fb, x, y, 1); | 1333 | return avivo_crtc_do_set_base(crtc, fb, x, y, 1); |
| 1336 | else | 1334 | else |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 677af91b555..d270b3ff896 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -97,26 +97,29 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
| 100 | u32 evergreen_get_temp(struct radeon_device *rdev) | 100 | int evergreen_get_temp(struct radeon_device *rdev) |
| 101 | { | 101 | { |
| 102 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | 102 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> |
| 103 | ASIC_T_SHIFT; | 103 | ASIC_T_SHIFT; |
| 104 | u32 actual_temp = 0; | 104 | u32 actual_temp = 0; |
| 105 | 105 | ||
| 106 | if ((temp >> 10) & 1) | 106 | if (temp & 0x400) |
| 107 | actual_temp = 0; | 107 | actual_temp = -256; |
| 108 | else if ((temp >> 9) & 1) | 108 | else if (temp & 0x200) |
| 109 | actual_temp = 255; | 109 | actual_temp = 255; |
| 110 | else | 110 | else if (temp & 0x100) { |
| 111 | actual_temp = (temp >> 1) & 0xff; | 111 | actual_temp = temp & 0x1ff; |
| 112 | actual_temp |= ~0x1ff; | ||
| 113 | } else | ||
| 114 | actual_temp = temp & 0xff; | ||
| 112 | 115 | ||
| 113 | return actual_temp * 1000; | 116 | return (actual_temp * 1000) / 2; |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | u32 sumo_get_temp(struct radeon_device *rdev) | 119 | int sumo_get_temp(struct radeon_device *rdev) |
| 117 | { | 120 | { |
| 118 | u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; | 121 | u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; |
| 119 | u32 actual_temp = (temp >> 1) & 0xff; | 122 | int actual_temp = temp - 49; |
| 120 | 123 | ||
| 121 | return actual_temp * 1000; | 124 | return actual_temp * 1000; |
| 122 | } | 125 | } |
| @@ -1182,6 +1185,22 @@ static void evergreen_mc_program(struct radeon_device *rdev) | |||
| 1182 | /* | 1185 | /* |
| 1183 | * CP. | 1186 | * CP. |
| 1184 | */ | 1187 | */ |
| 1188 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | ||
| 1189 | { | ||
| 1190 | /* set to DX10/11 mode */ | ||
| 1191 | radeon_ring_write(rdev, PACKET3(PACKET3_MODE_CONTROL, 0)); | ||
| 1192 | radeon_ring_write(rdev, 1); | ||
| 1193 | /* FIXME: implement */ | ||
| 1194 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | ||
| 1195 | radeon_ring_write(rdev, | ||
| 1196 | #ifdef __BIG_ENDIAN | ||
| 1197 | (2 << 0) | | ||
| 1198 | #endif | ||
| 1199 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
| 1200 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | ||
| 1201 | radeon_ring_write(rdev, ib->length_dw); | ||
| 1202 | } | ||
| 1203 | |||
| 1185 | 1204 | ||
| 1186 | static int evergreen_cp_load_microcode(struct radeon_device *rdev) | 1205 | static int evergreen_cp_load_microcode(struct radeon_device *rdev) |
| 1187 | { | 1206 | { |
| @@ -1192,7 +1211,11 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
| 1192 | return -EINVAL; | 1211 | return -EINVAL; |
| 1193 | 1212 | ||
| 1194 | r700_cp_stop(rdev); | 1213 | r700_cp_stop(rdev); |
| 1195 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); | 1214 | WREG32(CP_RB_CNTL, |
| 1215 | #ifdef __BIG_ENDIAN | ||
| 1216 | BUF_SWAP_32BIT | | ||
| 1217 | #endif | ||
| 1218 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
| 1196 | 1219 | ||
| 1197 | fw_data = (const __be32 *)rdev->pfp_fw->data; | 1220 | fw_data = (const __be32 *)rdev->pfp_fw->data; |
| 1198 | WREG32(CP_PFP_UCODE_ADDR, 0); | 1221 | WREG32(CP_PFP_UCODE_ADDR, 0); |
| @@ -1233,7 +1256,7 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
| 1233 | cp_me = 0xff; | 1256 | cp_me = 0xff; |
| 1234 | WREG32(CP_ME_CNTL, cp_me); | 1257 | WREG32(CP_ME_CNTL, cp_me); |
| 1235 | 1258 | ||
| 1236 | r = radeon_ring_lock(rdev, evergreen_default_size + 15); | 1259 | r = radeon_ring_lock(rdev, evergreen_default_size + 19); |
| 1237 | if (r) { | 1260 | if (r) { |
| 1238 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | 1261 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); |
| 1239 | return r; | 1262 | return r; |
| @@ -1266,6 +1289,11 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
| 1266 | radeon_ring_write(rdev, 0xffffffff); | 1289 | radeon_ring_write(rdev, 0xffffffff); |
| 1267 | radeon_ring_write(rdev, 0xffffffff); | 1290 | radeon_ring_write(rdev, 0xffffffff); |
| 1268 | 1291 | ||
| 1292 | radeon_ring_write(rdev, 0xc0026900); | ||
| 1293 | radeon_ring_write(rdev, 0x00000316); | ||
| 1294 | radeon_ring_write(rdev, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | ||
| 1295 | radeon_ring_write(rdev, 0x00000010); /* */ | ||
| 1296 | |||
| 1269 | radeon_ring_unlock_commit(rdev); | 1297 | radeon_ring_unlock_commit(rdev); |
| 1270 | 1298 | ||
| 1271 | return 0; | 1299 | return 0; |
| @@ -1306,7 +1334,11 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
| 1306 | WREG32(CP_RB_WPTR, 0); | 1334 | WREG32(CP_RB_WPTR, 0); |
| 1307 | 1335 | ||
| 1308 | /* set the wb address wether it's enabled or not */ | 1336 | /* set the wb address wether it's enabled or not */ |
| 1309 | WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); | 1337 | WREG32(CP_RB_RPTR_ADDR, |
| 1338 | #ifdef __BIG_ENDIAN | ||
| 1339 | RB_RPTR_SWAP(2) | | ||
| 1340 | #endif | ||
| 1341 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | ||
| 1310 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | 1342 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); |
| 1311 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | 1343 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); |
| 1312 | 1344 | ||
| @@ -2072,6 +2104,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 2072 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); | 2104 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); |
| 2073 | 2105 | ||
| 2074 | WREG32(VGT_GS_VERTEX_REUSE, 16); | 2106 | WREG32(VGT_GS_VERTEX_REUSE, 16); |
| 2107 | WREG32(PA_SU_LINE_STIPPLE_VALUE, 0); | ||
| 2075 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); | 2108 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); |
| 2076 | 2109 | ||
| 2077 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); | 2110 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); |
| @@ -2606,8 +2639,8 @@ restart_ih: | |||
| 2606 | while (rptr != wptr) { | 2639 | while (rptr != wptr) { |
| 2607 | /* wptr/rptr are in bytes! */ | 2640 | /* wptr/rptr are in bytes! */ |
| 2608 | ring_index = rptr / 4; | 2641 | ring_index = rptr / 4; |
| 2609 | src_id = rdev->ih.ring[ring_index] & 0xff; | 2642 | src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; |
| 2610 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | 2643 | src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; |
| 2611 | 2644 | ||
| 2612 | switch (src_id) { | 2645 | switch (src_id) { |
| 2613 | case 1: /* D1 vblank/vline */ | 2646 | case 1: /* D1 vblank/vline */ |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index d4d4db49a8b..2adfb03f479 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
| @@ -55,7 +55,7 @@ set_render_target(struct radeon_device *rdev, int format, | |||
| 55 | if (h < 8) | 55 | if (h < 8) |
| 56 | h = 8; | 56 | h = 8; |
| 57 | 57 | ||
| 58 | cb_color_info = ((format << 2) | (1 << 24)); | 58 | cb_color_info = ((format << 2) | (1 << 24) | (1 << 8)); |
| 59 | pitch = (w / 8) - 1; | 59 | pitch = (w / 8) - 1; |
| 60 | slice = ((w * h) / 64) - 1; | 60 | slice = ((w * h) / 64) - 1; |
| 61 | 61 | ||
| @@ -133,6 +133,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
| 133 | 133 | ||
| 134 | /* high addr, stride */ | 134 | /* high addr, stride */ |
| 135 | sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); | 135 | sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); |
| 136 | #ifdef __BIG_ENDIAN | ||
| 137 | sq_vtx_constant_word2 |= (2 << 30); | ||
| 138 | #endif | ||
| 136 | /* xyzw swizzles */ | 139 | /* xyzw swizzles */ |
| 137 | sq_vtx_constant_word3 = (0 << 3) | (1 << 6) | (2 << 9) | (3 << 12); | 140 | sq_vtx_constant_word3 = (0 << 3) | (1 << 6) | (2 << 9) | (3 << 12); |
| 138 | 141 | ||
| @@ -173,7 +176,7 @@ set_tex_resource(struct radeon_device *rdev, | |||
| 173 | sq_tex_resource_word0 = (1 << 0); /* 2D */ | 176 | sq_tex_resource_word0 = (1 << 0); /* 2D */ |
| 174 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) | | 177 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) | |
| 175 | ((w - 1) << 18)); | 178 | ((w - 1) << 18)); |
| 176 | sq_tex_resource_word1 = ((h - 1) << 0); | 179 | sq_tex_resource_word1 = ((h - 1) << 0) | (1 << 28); |
| 177 | /* xyzw swizzles */ | 180 | /* xyzw swizzles */ |
| 178 | sq_tex_resource_word4 = (0 << 16) | (1 << 19) | (2 << 22) | (3 << 25); | 181 | sq_tex_resource_word4 = (0 << 16) | (1 << 19) | (2 << 22) | (3 << 25); |
| 179 | 182 | ||
| @@ -221,7 +224,11 @@ draw_auto(struct radeon_device *rdev) | |||
| 221 | radeon_ring_write(rdev, DI_PT_RECTLIST); | 224 | radeon_ring_write(rdev, DI_PT_RECTLIST); |
| 222 | 225 | ||
| 223 | radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); | 226 | radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); |
| 224 | radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); | 227 | radeon_ring_write(rdev, |
| 228 | #ifdef __BIG_ENDIAN | ||
| 229 | (2 << 2) | | ||
| 230 | #endif | ||
| 231 | DI_INDEX_SIZE_16_BIT); | ||
| 225 | 232 | ||
| 226 | radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); | 233 | radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); |
| 227 | radeon_ring_write(rdev, 1); | 234 | radeon_ring_write(rdev, 1); |
| @@ -232,7 +239,7 @@ draw_auto(struct radeon_device *rdev) | |||
| 232 | 239 | ||
| 233 | } | 240 | } |
| 234 | 241 | ||
| 235 | /* emits 34 */ | 242 | /* emits 36 */ |
| 236 | static void | 243 | static void |
| 237 | set_default_state(struct radeon_device *rdev) | 244 | set_default_state(struct radeon_device *rdev) |
| 238 | { | 245 | { |
| @@ -499,6 +506,10 @@ set_default_state(struct radeon_device *rdev) | |||
| 499 | radeon_ring_write(rdev, 0x00000000); | 506 | radeon_ring_write(rdev, 0x00000000); |
| 500 | radeon_ring_write(rdev, 0x00000000); | 507 | radeon_ring_write(rdev, 0x00000000); |
| 501 | 508 | ||
| 509 | /* set to DX10/11 mode */ | ||
| 510 | radeon_ring_write(rdev, PACKET3(PACKET3_MODE_CONTROL, 0)); | ||
| 511 | radeon_ring_write(rdev, 1); | ||
| 512 | |||
| 502 | /* emit an IB pointing at default state */ | 513 | /* emit an IB pointing at default state */ |
| 503 | dwords = ALIGN(rdev->r600_blit.state_len, 0x10); | 514 | dwords = ALIGN(rdev->r600_blit.state_len, 0x10); |
| 504 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; | 515 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; |
| @@ -537,7 +548,7 @@ static inline uint32_t i2f(uint32_t input) | |||
| 537 | int evergreen_blit_init(struct radeon_device *rdev) | 548 | int evergreen_blit_init(struct radeon_device *rdev) |
| 538 | { | 549 | { |
| 539 | u32 obj_size; | 550 | u32 obj_size; |
| 540 | int r, dwords; | 551 | int i, r, dwords; |
| 541 | void *ptr; | 552 | void *ptr; |
| 542 | u32 packet2s[16]; | 553 | u32 packet2s[16]; |
| 543 | int num_packet2s = 0; | 554 | int num_packet2s = 0; |
| @@ -553,7 +564,7 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
| 553 | 564 | ||
| 554 | dwords = rdev->r600_blit.state_len; | 565 | dwords = rdev->r600_blit.state_len; |
| 555 | while (dwords & 0xf) { | 566 | while (dwords & 0xf) { |
| 556 | packet2s[num_packet2s++] = PACKET2(0); | 567 | packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); |
| 557 | dwords++; | 568 | dwords++; |
| 558 | } | 569 | } |
| 559 | 570 | ||
| @@ -594,8 +605,10 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
| 594 | if (num_packet2s) | 605 | if (num_packet2s) |
| 595 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), | 606 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), |
| 596 | packet2s, num_packet2s * 4); | 607 | packet2s, num_packet2s * 4); |
| 597 | memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4); | 608 | for (i = 0; i < evergreen_vs_size; i++) |
| 598 | memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4); | 609 | *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); |
| 610 | for (i = 0; i < evergreen_ps_size; i++) | ||
| 611 | *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); | ||
| 599 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | 612 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); |
| 600 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 613 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
| 601 | 614 | ||
| @@ -679,7 +692,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
| 679 | /* calculate number of loops correctly */ | 692 | /* calculate number of loops correctly */ |
| 680 | ring_size = num_loops * dwords_per_loop; | 693 | ring_size = num_loops * dwords_per_loop; |
| 681 | /* set default + shaders */ | 694 | /* set default + shaders */ |
| 682 | ring_size += 50; /* shaders + def state */ | 695 | ring_size += 52; /* shaders + def state */ |
| 683 | ring_size += 10; /* fence emit for VB IB */ | 696 | ring_size += 10; /* fence emit for VB IB */ |
| 684 | ring_size += 5; /* done copy */ | 697 | ring_size += 5; /* done copy */ |
| 685 | ring_size += 10; /* fence emit for done copy */ | 698 | ring_size += 10; /* fence emit for done copy */ |
| @@ -687,7 +700,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
| 687 | if (r) | 700 | if (r) |
| 688 | return r; | 701 | return r; |
| 689 | 702 | ||
| 690 | set_default_state(rdev); /* 34 */ | 703 | set_default_state(rdev); /* 36 */ |
| 691 | set_shaders(rdev); /* 16 */ | 704 | set_shaders(rdev); /* 16 */ |
| 692 | return 0; | 705 | return 0; |
| 693 | } | 706 | } |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c index ef1d28c07fb..3a10399e006 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c | |||
| @@ -311,11 +311,19 @@ const u32 evergreen_vs[] = | |||
| 311 | 0x00000000, | 311 | 0x00000000, |
| 312 | 0x3c000000, | 312 | 0x3c000000, |
| 313 | 0x67961001, | 313 | 0x67961001, |
| 314 | #ifdef __BIG_ENDIAN | ||
| 315 | 0x000a0000, | ||
| 316 | #else | ||
| 314 | 0x00080000, | 317 | 0x00080000, |
| 318 | #endif | ||
| 315 | 0x00000000, | 319 | 0x00000000, |
| 316 | 0x1c000000, | 320 | 0x1c000000, |
| 317 | 0x67961000, | 321 | 0x67961000, |
| 322 | #ifdef __BIG_ENDIAN | ||
| 323 | 0x00020008, | ||
| 324 | #else | ||
| 318 | 0x00000008, | 325 | 0x00000008, |
| 326 | #endif | ||
| 319 | 0x00000000, | 327 | 0x00000000, |
| 320 | }; | 328 | }; |
| 321 | 329 | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 36d32d83d86..eb4acf4528f 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -98,6 +98,7 @@ | |||
| 98 | #define BUF_SWAP_32BIT (2 << 16) | 98 | #define BUF_SWAP_32BIT (2 << 16) |
| 99 | #define CP_RB_RPTR 0x8700 | 99 | #define CP_RB_RPTR 0x8700 |
| 100 | #define CP_RB_RPTR_ADDR 0xC10C | 100 | #define CP_RB_RPTR_ADDR 0xC10C |
| 101 | #define RB_RPTR_SWAP(x) ((x) << 0) | ||
| 101 | #define CP_RB_RPTR_ADDR_HI 0xC110 | 102 | #define CP_RB_RPTR_ADDR_HI 0xC110 |
| 102 | #define CP_RB_RPTR_WR 0xC108 | 103 | #define CP_RB_RPTR_WR 0xC108 |
| 103 | #define CP_RB_WPTR 0xC114 | 104 | #define CP_RB_WPTR 0xC114 |
| @@ -240,6 +241,7 @@ | |||
| 240 | #define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) | 241 | #define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) |
| 241 | #define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) | 242 | #define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) |
| 242 | #define PA_SC_LINE_STIPPLE 0x28A0C | 243 | #define PA_SC_LINE_STIPPLE 0x28A0C |
| 244 | #define PA_SU_LINE_STIPPLE_VALUE 0x8A60 | ||
| 243 | #define PA_SC_LINE_STIPPLE_STATE 0x8B10 | 245 | #define PA_SC_LINE_STIPPLE_STATE 0x8B10 |
| 244 | 246 | ||
| 245 | #define SCRATCH_REG0 0x8500 | 247 | #define SCRATCH_REG0 0x8500 |
| @@ -652,6 +654,7 @@ | |||
| 652 | #define PACKET3_DISPATCH_DIRECT 0x15 | 654 | #define PACKET3_DISPATCH_DIRECT 0x15 |
| 653 | #define PACKET3_DISPATCH_INDIRECT 0x16 | 655 | #define PACKET3_DISPATCH_INDIRECT 0x16 |
| 654 | #define PACKET3_INDIRECT_BUFFER_END 0x17 | 656 | #define PACKET3_INDIRECT_BUFFER_END 0x17 |
| 657 | #define PACKET3_MODE_CONTROL 0x18 | ||
| 655 | #define PACKET3_SET_PREDICATION 0x20 | 658 | #define PACKET3_SET_PREDICATION 0x20 |
| 656 | #define PACKET3_REG_RMW 0x21 | 659 | #define PACKET3_REG_RMW 0x21 |
| 657 | #define PACKET3_COND_EXEC 0x22 | 660 | #define PACKET3_COND_EXEC 0x22 |
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index 607241c6a8a..5a82b6b7584 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c | |||
| @@ -673,8 +673,10 @@ static int parser_auth(struct table *t, const char *filename) | |||
| 673 | last_reg = strtol(last_reg_s, NULL, 16); | 673 | last_reg = strtol(last_reg_s, NULL, 16); |
| 674 | 674 | ||
| 675 | do { | 675 | do { |
| 676 | if (fgets(buf, 1024, file) == NULL) | 676 | if (fgets(buf, 1024, file) == NULL) { |
| 677 | fclose(file); | ||
| 677 | return -1; | 678 | return -1; |
| 679 | } | ||
| 678 | len = strlen(buf); | 680 | len = strlen(buf); |
| 679 | if (ftell(file) == end) | 681 | if (ftell(file) == end) |
| 680 | done = 1; | 682 | done = 1; |
| @@ -685,6 +687,7 @@ static int parser_auth(struct table *t, const char *filename) | |||
| 685 | fprintf(stderr, | 687 | fprintf(stderr, |
| 686 | "Error matching regular expression %d in %s\n", | 688 | "Error matching regular expression %d in %s\n", |
| 687 | r, filename); | 689 | r, filename); |
| 690 | fclose(file); | ||
| 688 | return -1; | 691 | return -1; |
| 689 | } else { | 692 | } else { |
| 690 | buf[match[0].rm_eo] = 0; | 693 | buf[match[0].rm_eo] = 0; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 5f15820efe1..56deae5bf02 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -1427,6 +1427,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1427 | } | 1427 | } |
| 1428 | track->zb.robj = reloc->robj; | 1428 | track->zb.robj = reloc->robj; |
| 1429 | track->zb.offset = idx_value; | 1429 | track->zb.offset = idx_value; |
| 1430 | track->zb_dirty = true; | ||
| 1430 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1431 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1431 | break; | 1432 | break; |
| 1432 | case RADEON_RB3D_COLOROFFSET: | 1433 | case RADEON_RB3D_COLOROFFSET: |
| @@ -1439,6 +1440,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1439 | } | 1440 | } |
| 1440 | track->cb[0].robj = reloc->robj; | 1441 | track->cb[0].robj = reloc->robj; |
| 1441 | track->cb[0].offset = idx_value; | 1442 | track->cb[0].offset = idx_value; |
| 1443 | track->cb_dirty = true; | ||
| 1442 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1444 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1443 | break; | 1445 | break; |
| 1444 | case RADEON_PP_TXOFFSET_0: | 1446 | case RADEON_PP_TXOFFSET_0: |
| @@ -1454,6 +1456,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1454 | } | 1456 | } |
| 1455 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1457 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1456 | track->textures[i].robj = reloc->robj; | 1458 | track->textures[i].robj = reloc->robj; |
| 1459 | track->tex_dirty = true; | ||
| 1457 | break; | 1460 | break; |
| 1458 | case RADEON_PP_CUBIC_OFFSET_T0_0: | 1461 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
| 1459 | case RADEON_PP_CUBIC_OFFSET_T0_1: | 1462 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
| @@ -1471,6 +1474,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1471 | track->textures[0].cube_info[i].offset = idx_value; | 1474 | track->textures[0].cube_info[i].offset = idx_value; |
| 1472 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1475 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1473 | track->textures[0].cube_info[i].robj = reloc->robj; | 1476 | track->textures[0].cube_info[i].robj = reloc->robj; |
| 1477 | track->tex_dirty = true; | ||
| 1474 | break; | 1478 | break; |
| 1475 | case RADEON_PP_CUBIC_OFFSET_T1_0: | 1479 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
| 1476 | case RADEON_PP_CUBIC_OFFSET_T1_1: | 1480 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
| @@ -1488,6 +1492,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1488 | track->textures[1].cube_info[i].offset = idx_value; | 1492 | track->textures[1].cube_info[i].offset = idx_value; |
| 1489 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1493 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1490 | track->textures[1].cube_info[i].robj = reloc->robj; | 1494 | track->textures[1].cube_info[i].robj = reloc->robj; |
| 1495 | track->tex_dirty = true; | ||
| 1491 | break; | 1496 | break; |
| 1492 | case RADEON_PP_CUBIC_OFFSET_T2_0: | 1497 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
| 1493 | case RADEON_PP_CUBIC_OFFSET_T2_1: | 1498 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
| @@ -1505,9 +1510,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1505 | track->textures[2].cube_info[i].offset = idx_value; | 1510 | track->textures[2].cube_info[i].offset = idx_value; |
| 1506 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1511 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1507 | track->textures[2].cube_info[i].robj = reloc->robj; | 1512 | track->textures[2].cube_info[i].robj = reloc->robj; |
| 1513 | track->tex_dirty = true; | ||
| 1508 | break; | 1514 | break; |
| 1509 | case RADEON_RE_WIDTH_HEIGHT: | 1515 | case RADEON_RE_WIDTH_HEIGHT: |
| 1510 | track->maxy = ((idx_value >> 16) & 0x7FF); | 1516 | track->maxy = ((idx_value >> 16) & 0x7FF); |
| 1517 | track->cb_dirty = true; | ||
| 1518 | track->zb_dirty = true; | ||
| 1511 | break; | 1519 | break; |
| 1512 | case RADEON_RB3D_COLORPITCH: | 1520 | case RADEON_RB3D_COLORPITCH: |
| 1513 | r = r100_cs_packet_next_reloc(p, &reloc); | 1521 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1528,9 +1536,11 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1528 | ib[idx] = tmp; | 1536 | ib[idx] = tmp; |
| 1529 | 1537 | ||
| 1530 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; | 1538 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
| 1539 | track->cb_dirty = true; | ||
| 1531 | break; | 1540 | break; |
| 1532 | case RADEON_RB3D_DEPTHPITCH: | 1541 | case RADEON_RB3D_DEPTHPITCH: |
| 1533 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; | 1542 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
| 1543 | track->zb_dirty = true; | ||
| 1534 | break; | 1544 | break; |
| 1535 | case RADEON_RB3D_CNTL: | 1545 | case RADEON_RB3D_CNTL: |
| 1536 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { | 1546 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
| @@ -1555,6 +1565,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1555 | return -EINVAL; | 1565 | return -EINVAL; |
| 1556 | } | 1566 | } |
| 1557 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); | 1567 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
| 1568 | track->cb_dirty = true; | ||
| 1569 | track->zb_dirty = true; | ||
| 1558 | break; | 1570 | break; |
| 1559 | case RADEON_RB3D_ZSTENCILCNTL: | 1571 | case RADEON_RB3D_ZSTENCILCNTL: |
| 1560 | switch (idx_value & 0xf) { | 1572 | switch (idx_value & 0xf) { |
| @@ -1572,6 +1584,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1572 | default: | 1584 | default: |
| 1573 | break; | 1585 | break; |
| 1574 | } | 1586 | } |
| 1587 | track->zb_dirty = true; | ||
| 1575 | break; | 1588 | break; |
| 1576 | case RADEON_RB3D_ZPASS_ADDR: | 1589 | case RADEON_RB3D_ZPASS_ADDR: |
| 1577 | r = r100_cs_packet_next_reloc(p, &reloc); | 1590 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1588,6 +1601,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1588 | uint32_t temp = idx_value >> 4; | 1601 | uint32_t temp = idx_value >> 4; |
| 1589 | for (i = 0; i < track->num_texture; i++) | 1602 | for (i = 0; i < track->num_texture; i++) |
| 1590 | track->textures[i].enabled = !!(temp & (1 << i)); | 1603 | track->textures[i].enabled = !!(temp & (1 << i)); |
| 1604 | track->tex_dirty = true; | ||
| 1591 | } | 1605 | } |
| 1592 | break; | 1606 | break; |
| 1593 | case RADEON_SE_VF_CNTL: | 1607 | case RADEON_SE_VF_CNTL: |
| @@ -1602,12 +1616,14 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1602 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; | 1616 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
| 1603 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; | 1617 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
| 1604 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; | 1618 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
| 1619 | track->tex_dirty = true; | ||
| 1605 | break; | 1620 | break; |
| 1606 | case RADEON_PP_TEX_PITCH_0: | 1621 | case RADEON_PP_TEX_PITCH_0: |
| 1607 | case RADEON_PP_TEX_PITCH_1: | 1622 | case RADEON_PP_TEX_PITCH_1: |
| 1608 | case RADEON_PP_TEX_PITCH_2: | 1623 | case RADEON_PP_TEX_PITCH_2: |
| 1609 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; | 1624 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
| 1610 | track->textures[i].pitch = idx_value + 32; | 1625 | track->textures[i].pitch = idx_value + 32; |
| 1626 | track->tex_dirty = true; | ||
| 1611 | break; | 1627 | break; |
| 1612 | case RADEON_PP_TXFILTER_0: | 1628 | case RADEON_PP_TXFILTER_0: |
| 1613 | case RADEON_PP_TXFILTER_1: | 1629 | case RADEON_PP_TXFILTER_1: |
| @@ -1621,6 +1637,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1621 | tmp = (idx_value >> 27) & 0x7; | 1637 | tmp = (idx_value >> 27) & 0x7; |
| 1622 | if (tmp == 2 || tmp == 6) | 1638 | if (tmp == 2 || tmp == 6) |
| 1623 | track->textures[i].roundup_h = false; | 1639 | track->textures[i].roundup_h = false; |
| 1640 | track->tex_dirty = true; | ||
| 1624 | break; | 1641 | break; |
| 1625 | case RADEON_PP_TXFORMAT_0: | 1642 | case RADEON_PP_TXFORMAT_0: |
| 1626 | case RADEON_PP_TXFORMAT_1: | 1643 | case RADEON_PP_TXFORMAT_1: |
| @@ -1673,6 +1690,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1673 | } | 1690 | } |
| 1674 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); | 1691 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
| 1675 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); | 1692 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
| 1693 | track->tex_dirty = true; | ||
| 1676 | break; | 1694 | break; |
| 1677 | case RADEON_PP_CUBIC_FACES_0: | 1695 | case RADEON_PP_CUBIC_FACES_0: |
| 1678 | case RADEON_PP_CUBIC_FACES_1: | 1696 | case RADEON_PP_CUBIC_FACES_1: |
| @@ -1683,6 +1701,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1683 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); | 1701 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
| 1684 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); | 1702 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
| 1685 | } | 1703 | } |
| 1704 | track->tex_dirty = true; | ||
| 1686 | break; | 1705 | break; |
| 1687 | default: | 1706 | default: |
| 1688 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1707 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
| @@ -3318,9 +3337,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
| 3318 | unsigned long size; | 3337 | unsigned long size; |
| 3319 | unsigned prim_walk; | 3338 | unsigned prim_walk; |
| 3320 | unsigned nverts; | 3339 | unsigned nverts; |
| 3321 | unsigned num_cb = track->num_cb; | 3340 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; |
| 3322 | 3341 | ||
| 3323 | if (!track->zb_cb_clear && !track->color_channel_mask && | 3342 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && |
| 3324 | !track->blend_read_enable) | 3343 | !track->blend_read_enable) |
| 3325 | num_cb = 0; | 3344 | num_cb = 0; |
| 3326 | 3345 | ||
| @@ -3341,7 +3360,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
| 3341 | return -EINVAL; | 3360 | return -EINVAL; |
| 3342 | } | 3361 | } |
| 3343 | } | 3362 | } |
| 3344 | if (track->z_enabled) { | 3363 | track->cb_dirty = false; |
| 3364 | |||
| 3365 | if (track->zb_dirty && track->z_enabled) { | ||
| 3345 | if (track->zb.robj == NULL) { | 3366 | if (track->zb.robj == NULL) { |
| 3346 | DRM_ERROR("[drm] No buffer for z buffer !\n"); | 3367 | DRM_ERROR("[drm] No buffer for z buffer !\n"); |
| 3347 | return -EINVAL; | 3368 | return -EINVAL; |
| @@ -3358,6 +3379,28 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
| 3358 | return -EINVAL; | 3379 | return -EINVAL; |
| 3359 | } | 3380 | } |
| 3360 | } | 3381 | } |
| 3382 | track->zb_dirty = false; | ||
| 3383 | |||
| 3384 | if (track->aa_dirty && track->aaresolve) { | ||
| 3385 | if (track->aa.robj == NULL) { | ||
| 3386 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); | ||
| 3387 | return -EINVAL; | ||
| 3388 | } | ||
| 3389 | /* I believe the format comes from colorbuffer0. */ | ||
| 3390 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; | ||
| 3391 | size += track->aa.offset; | ||
| 3392 | if (size > radeon_bo_size(track->aa.robj)) { | ||
| 3393 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " | ||
| 3394 | "(need %lu have %lu) !\n", i, size, | ||
| 3395 | radeon_bo_size(track->aa.robj)); | ||
| 3396 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", | ||
| 3397 | i, track->aa.pitch, track->cb[0].cpp, | ||
| 3398 | track->aa.offset, track->maxy); | ||
| 3399 | return -EINVAL; | ||
| 3400 | } | ||
| 3401 | } | ||
| 3402 | track->aa_dirty = false; | ||
| 3403 | |||
| 3361 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | 3404 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
| 3362 | if (track->vap_vf_cntl & (1 << 14)) { | 3405 | if (track->vap_vf_cntl & (1 << 14)) { |
| 3363 | nverts = track->vap_alt_nverts; | 3406 | nverts = track->vap_alt_nverts; |
| @@ -3417,13 +3460,23 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
| 3417 | prim_walk); | 3460 | prim_walk); |
| 3418 | return -EINVAL; | 3461 | return -EINVAL; |
| 3419 | } | 3462 | } |
| 3420 | return r100_cs_track_texture_check(rdev, track); | 3463 | |
| 3464 | if (track->tex_dirty) { | ||
| 3465 | track->tex_dirty = false; | ||
| 3466 | return r100_cs_track_texture_check(rdev, track); | ||
| 3467 | } | ||
| 3468 | return 0; | ||
| 3421 | } | 3469 | } |
| 3422 | 3470 | ||
| 3423 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) | 3471 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) |
| 3424 | { | 3472 | { |
| 3425 | unsigned i, face; | 3473 | unsigned i, face; |
| 3426 | 3474 | ||
| 3475 | track->cb_dirty = true; | ||
| 3476 | track->zb_dirty = true; | ||
| 3477 | track->tex_dirty = true; | ||
| 3478 | track->aa_dirty = true; | ||
| 3479 | |||
| 3427 | if (rdev->family < CHIP_R300) { | 3480 | if (rdev->family < CHIP_R300) { |
| 3428 | track->num_cb = 1; | 3481 | track->num_cb = 1; |
| 3429 | if (rdev->family <= CHIP_RS200) | 3482 | if (rdev->family <= CHIP_RS200) |
| @@ -3437,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track | |||
| 3437 | track->num_texture = 16; | 3490 | track->num_texture = 16; |
| 3438 | track->maxy = 4096; | 3491 | track->maxy = 4096; |
| 3439 | track->separate_cube = 0; | 3492 | track->separate_cube = 0; |
| 3493 | track->aaresolve = true; | ||
| 3494 | track->aa.robj = NULL; | ||
| 3440 | } | 3495 | } |
| 3441 | 3496 | ||
| 3442 | for (i = 0; i < track->num_cb; i++) { | 3497 | for (i = 0; i < track->num_cb; i++) { |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index af65600e656..2fef9de7f36 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h | |||
| @@ -52,14 +52,7 @@ struct r100_cs_track_texture { | |||
| 52 | unsigned compress_format; | 52 | unsigned compress_format; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | struct r100_cs_track_limits { | ||
| 56 | unsigned num_cb; | ||
| 57 | unsigned num_texture; | ||
| 58 | unsigned max_levels; | ||
| 59 | }; | ||
| 60 | |||
| 61 | struct r100_cs_track { | 55 | struct r100_cs_track { |
| 62 | struct radeon_device *rdev; | ||
| 63 | unsigned num_cb; | 56 | unsigned num_cb; |
| 64 | unsigned num_texture; | 57 | unsigned num_texture; |
| 65 | unsigned maxy; | 58 | unsigned maxy; |
| @@ -73,11 +66,17 @@ struct r100_cs_track { | |||
| 73 | struct r100_cs_track_array arrays[11]; | 66 | struct r100_cs_track_array arrays[11]; |
| 74 | struct r100_cs_track_cb cb[R300_MAX_CB]; | 67 | struct r100_cs_track_cb cb[R300_MAX_CB]; |
| 75 | struct r100_cs_track_cb zb; | 68 | struct r100_cs_track_cb zb; |
| 69 | struct r100_cs_track_cb aa; | ||
| 76 | struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; | 70 | struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; |
| 77 | bool z_enabled; | 71 | bool z_enabled; |
| 78 | bool separate_cube; | 72 | bool separate_cube; |
| 79 | bool zb_cb_clear; | 73 | bool zb_cb_clear; |
| 80 | bool blend_read_enable; | 74 | bool blend_read_enable; |
| 75 | bool cb_dirty; | ||
| 76 | bool zb_dirty; | ||
| 77 | bool tex_dirty; | ||
| 78 | bool aa_dirty; | ||
| 79 | bool aaresolve; | ||
| 81 | }; | 80 | }; |
| 82 | 81 | ||
| 83 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); | 82 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index d2408c39561..f2405830041 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
| @@ -184,6 +184,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 184 | } | 184 | } |
| 185 | track->zb.robj = reloc->robj; | 185 | track->zb.robj = reloc->robj; |
| 186 | track->zb.offset = idx_value; | 186 | track->zb.offset = idx_value; |
| 187 | track->zb_dirty = true; | ||
| 187 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 188 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 188 | break; | 189 | break; |
| 189 | case RADEON_RB3D_COLOROFFSET: | 190 | case RADEON_RB3D_COLOROFFSET: |
| @@ -196,6 +197,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 196 | } | 197 | } |
| 197 | track->cb[0].robj = reloc->robj; | 198 | track->cb[0].robj = reloc->robj; |
| 198 | track->cb[0].offset = idx_value; | 199 | track->cb[0].offset = idx_value; |
| 200 | track->cb_dirty = true; | ||
| 199 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 201 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 200 | break; | 202 | break; |
| 201 | case R200_PP_TXOFFSET_0: | 203 | case R200_PP_TXOFFSET_0: |
| @@ -214,6 +216,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 214 | } | 216 | } |
| 215 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 217 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 216 | track->textures[i].robj = reloc->robj; | 218 | track->textures[i].robj = reloc->robj; |
| 219 | track->tex_dirty = true; | ||
| 217 | break; | 220 | break; |
| 218 | case R200_PP_CUBIC_OFFSET_F1_0: | 221 | case R200_PP_CUBIC_OFFSET_F1_0: |
| 219 | case R200_PP_CUBIC_OFFSET_F2_0: | 222 | case R200_PP_CUBIC_OFFSET_F2_0: |
| @@ -257,9 +260,12 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 257 | track->textures[i].cube_info[face - 1].offset = idx_value; | 260 | track->textures[i].cube_info[face - 1].offset = idx_value; |
| 258 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 261 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 259 | track->textures[i].cube_info[face - 1].robj = reloc->robj; | 262 | track->textures[i].cube_info[face - 1].robj = reloc->robj; |
| 263 | track->tex_dirty = true; | ||
| 260 | break; | 264 | break; |
| 261 | case RADEON_RE_WIDTH_HEIGHT: | 265 | case RADEON_RE_WIDTH_HEIGHT: |
| 262 | track->maxy = ((idx_value >> 16) & 0x7FF); | 266 | track->maxy = ((idx_value >> 16) & 0x7FF); |
| 267 | track->cb_dirty = true; | ||
| 268 | track->zb_dirty = true; | ||
| 263 | break; | 269 | break; |
| 264 | case RADEON_RB3D_COLORPITCH: | 270 | case RADEON_RB3D_COLORPITCH: |
| 265 | r = r100_cs_packet_next_reloc(p, &reloc); | 271 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -280,9 +286,11 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 280 | ib[idx] = tmp; | 286 | ib[idx] = tmp; |
| 281 | 287 | ||
| 282 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; | 288 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
| 289 | track->cb_dirty = true; | ||
| 283 | break; | 290 | break; |
| 284 | case RADEON_RB3D_DEPTHPITCH: | 291 | case RADEON_RB3D_DEPTHPITCH: |
| 285 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; | 292 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
| 293 | track->zb_dirty = true; | ||
| 286 | break; | 294 | break; |
| 287 | case RADEON_RB3D_CNTL: | 295 | case RADEON_RB3D_CNTL: |
| 288 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { | 296 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
| @@ -312,6 +320,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 312 | } | 320 | } |
| 313 | 321 | ||
| 314 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); | 322 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
| 323 | track->cb_dirty = true; | ||
| 324 | track->zb_dirty = true; | ||
| 315 | break; | 325 | break; |
| 316 | case RADEON_RB3D_ZSTENCILCNTL: | 326 | case RADEON_RB3D_ZSTENCILCNTL: |
| 317 | switch (idx_value & 0xf) { | 327 | switch (idx_value & 0xf) { |
| @@ -329,6 +339,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 329 | default: | 339 | default: |
| 330 | break; | 340 | break; |
| 331 | } | 341 | } |
| 342 | track->zb_dirty = true; | ||
| 332 | break; | 343 | break; |
| 333 | case RADEON_RB3D_ZPASS_ADDR: | 344 | case RADEON_RB3D_ZPASS_ADDR: |
| 334 | r = r100_cs_packet_next_reloc(p, &reloc); | 345 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -345,6 +356,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 345 | uint32_t temp = idx_value >> 4; | 356 | uint32_t temp = idx_value >> 4; |
| 346 | for (i = 0; i < track->num_texture; i++) | 357 | for (i = 0; i < track->num_texture; i++) |
| 347 | track->textures[i].enabled = !!(temp & (1 << i)); | 358 | track->textures[i].enabled = !!(temp & (1 << i)); |
| 359 | track->tex_dirty = true; | ||
| 348 | } | 360 | } |
| 349 | break; | 361 | break; |
| 350 | case RADEON_SE_VF_CNTL: | 362 | case RADEON_SE_VF_CNTL: |
| @@ -369,6 +381,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 369 | i = (reg - R200_PP_TXSIZE_0) / 32; | 381 | i = (reg - R200_PP_TXSIZE_0) / 32; |
| 370 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; | 382 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
| 371 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; | 383 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
| 384 | track->tex_dirty = true; | ||
| 372 | break; | 385 | break; |
| 373 | case R200_PP_TXPITCH_0: | 386 | case R200_PP_TXPITCH_0: |
| 374 | case R200_PP_TXPITCH_1: | 387 | case R200_PP_TXPITCH_1: |
| @@ -378,6 +391,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 378 | case R200_PP_TXPITCH_5: | 391 | case R200_PP_TXPITCH_5: |
| 379 | i = (reg - R200_PP_TXPITCH_0) / 32; | 392 | i = (reg - R200_PP_TXPITCH_0) / 32; |
| 380 | track->textures[i].pitch = idx_value + 32; | 393 | track->textures[i].pitch = idx_value + 32; |
| 394 | track->tex_dirty = true; | ||
| 381 | break; | 395 | break; |
| 382 | case R200_PP_TXFILTER_0: | 396 | case R200_PP_TXFILTER_0: |
| 383 | case R200_PP_TXFILTER_1: | 397 | case R200_PP_TXFILTER_1: |
| @@ -394,6 +408,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 394 | tmp = (idx_value >> 27) & 0x7; | 408 | tmp = (idx_value >> 27) & 0x7; |
| 395 | if (tmp == 2 || tmp == 6) | 409 | if (tmp == 2 || tmp == 6) |
| 396 | track->textures[i].roundup_h = false; | 410 | track->textures[i].roundup_h = false; |
| 411 | track->tex_dirty = true; | ||
| 397 | break; | 412 | break; |
| 398 | case R200_PP_TXMULTI_CTL_0: | 413 | case R200_PP_TXMULTI_CTL_0: |
| 399 | case R200_PP_TXMULTI_CTL_1: | 414 | case R200_PP_TXMULTI_CTL_1: |
| @@ -432,6 +447,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 432 | track->textures[i].tex_coord_type = 1; | 447 | track->textures[i].tex_coord_type = 1; |
| 433 | break; | 448 | break; |
| 434 | } | 449 | } |
| 450 | track->tex_dirty = true; | ||
| 435 | break; | 451 | break; |
| 436 | case R200_PP_TXFORMAT_0: | 452 | case R200_PP_TXFORMAT_0: |
| 437 | case R200_PP_TXFORMAT_1: | 453 | case R200_PP_TXFORMAT_1: |
| @@ -488,6 +504,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 488 | } | 504 | } |
| 489 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); | 505 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
| 490 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); | 506 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
| 507 | track->tex_dirty = true; | ||
| 491 | break; | 508 | break; |
| 492 | case R200_PP_CUBIC_FACES_0: | 509 | case R200_PP_CUBIC_FACES_0: |
| 493 | case R200_PP_CUBIC_FACES_1: | 510 | case R200_PP_CUBIC_FACES_1: |
| @@ -501,6 +518,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 501 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); | 518 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
| 502 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); | 519 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
| 503 | } | 520 | } |
| 521 | track->tex_dirty = true; | ||
| 504 | break; | 522 | break; |
| 505 | default: | 523 | default: |
| 506 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 524 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 55fe5ba7def..069efa8c8ec 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -667,6 +667,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 667 | } | 667 | } |
| 668 | track->cb[i].robj = reloc->robj; | 668 | track->cb[i].robj = reloc->robj; |
| 669 | track->cb[i].offset = idx_value; | 669 | track->cb[i].offset = idx_value; |
| 670 | track->cb_dirty = true; | ||
| 670 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 671 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 671 | break; | 672 | break; |
| 672 | case R300_ZB_DEPTHOFFSET: | 673 | case R300_ZB_DEPTHOFFSET: |
| @@ -679,6 +680,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 679 | } | 680 | } |
| 680 | track->zb.robj = reloc->robj; | 681 | track->zb.robj = reloc->robj; |
| 681 | track->zb.offset = idx_value; | 682 | track->zb.offset = idx_value; |
| 683 | track->zb_dirty = true; | ||
| 682 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 684 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 683 | break; | 685 | break; |
| 684 | case R300_TX_OFFSET_0: | 686 | case R300_TX_OFFSET_0: |
| @@ -717,6 +719,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 717 | tmp |= tile_flags; | 719 | tmp |= tile_flags; |
| 718 | ib[idx] = tmp; | 720 | ib[idx] = tmp; |
| 719 | track->textures[i].robj = reloc->robj; | 721 | track->textures[i].robj = reloc->robj; |
| 722 | track->tex_dirty = true; | ||
| 720 | break; | 723 | break; |
| 721 | /* Tracked registers */ | 724 | /* Tracked registers */ |
| 722 | case 0x2084: | 725 | case 0x2084: |
| @@ -743,6 +746,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 743 | if (p->rdev->family < CHIP_RV515) { | 746 | if (p->rdev->family < CHIP_RV515) { |
| 744 | track->maxy -= 1440; | 747 | track->maxy -= 1440; |
| 745 | } | 748 | } |
| 749 | track->cb_dirty = true; | ||
| 750 | track->zb_dirty = true; | ||
| 746 | break; | 751 | break; |
| 747 | case 0x4E00: | 752 | case 0x4E00: |
| 748 | /* RB3D_CCTL */ | 753 | /* RB3D_CCTL */ |
| @@ -752,6 +757,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 752 | return -EINVAL; | 757 | return -EINVAL; |
| 753 | } | 758 | } |
| 754 | track->num_cb = ((idx_value >> 5) & 0x3) + 1; | 759 | track->num_cb = ((idx_value >> 5) & 0x3) + 1; |
| 760 | track->cb_dirty = true; | ||
| 755 | break; | 761 | break; |
| 756 | case 0x4E38: | 762 | case 0x4E38: |
| 757 | case 0x4E3C: | 763 | case 0x4E3C: |
| @@ -814,6 +820,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 814 | ((idx_value >> 21) & 0xF)); | 820 | ((idx_value >> 21) & 0xF)); |
| 815 | return -EINVAL; | 821 | return -EINVAL; |
| 816 | } | 822 | } |
| 823 | track->cb_dirty = true; | ||
| 817 | break; | 824 | break; |
| 818 | case 0x4F00: | 825 | case 0x4F00: |
| 819 | /* ZB_CNTL */ | 826 | /* ZB_CNTL */ |
| @@ -822,6 +829,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 822 | } else { | 829 | } else { |
| 823 | track->z_enabled = false; | 830 | track->z_enabled = false; |
| 824 | } | 831 | } |
| 832 | track->zb_dirty = true; | ||
| 825 | break; | 833 | break; |
| 826 | case 0x4F10: | 834 | case 0x4F10: |
| 827 | /* ZB_FORMAT */ | 835 | /* ZB_FORMAT */ |
| @@ -838,6 +846,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 838 | (idx_value & 0xF)); | 846 | (idx_value & 0xF)); |
| 839 | return -EINVAL; | 847 | return -EINVAL; |
| 840 | } | 848 | } |
| 849 | track->zb_dirty = true; | ||
| 841 | break; | 850 | break; |
| 842 | case 0x4F24: | 851 | case 0x4F24: |
| 843 | /* ZB_DEPTHPITCH */ | 852 | /* ZB_DEPTHPITCH */ |
| @@ -861,14 +870,17 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 861 | ib[idx] = tmp; | 870 | ib[idx] = tmp; |
| 862 | 871 | ||
| 863 | track->zb.pitch = idx_value & 0x3FFC; | 872 | track->zb.pitch = idx_value & 0x3FFC; |
| 873 | track->zb_dirty = true; | ||
| 864 | break; | 874 | break; |
| 865 | case 0x4104: | 875 | case 0x4104: |
| 876 | /* TX_ENABLE */ | ||
| 866 | for (i = 0; i < 16; i++) { | 877 | for (i = 0; i < 16; i++) { |
| 867 | bool enabled; | 878 | bool enabled; |
| 868 | 879 | ||
| 869 | enabled = !!(idx_value & (1 << i)); | 880 | enabled = !!(idx_value & (1 << i)); |
| 870 | track->textures[i].enabled = enabled; | 881 | track->textures[i].enabled = enabled; |
| 871 | } | 882 | } |
| 883 | track->tex_dirty = true; | ||
| 872 | break; | 884 | break; |
| 873 | case 0x44C0: | 885 | case 0x44C0: |
| 874 | case 0x44C4: | 886 | case 0x44C4: |
| @@ -898,6 +910,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 898 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; | 910 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
| 899 | break; | 911 | break; |
| 900 | case R300_TX_FORMAT_X16: | 912 | case R300_TX_FORMAT_X16: |
| 913 | case R300_TX_FORMAT_FL_I16: | ||
| 901 | case R300_TX_FORMAT_Y8X8: | 914 | case R300_TX_FORMAT_Y8X8: |
| 902 | case R300_TX_FORMAT_Z5Y6X5: | 915 | case R300_TX_FORMAT_Z5Y6X5: |
| 903 | case R300_TX_FORMAT_Z6Y5X5: | 916 | case R300_TX_FORMAT_Z6Y5X5: |
| @@ -910,6 +923,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 910 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; | 923 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
| 911 | break; | 924 | break; |
| 912 | case R300_TX_FORMAT_Y16X16: | 925 | case R300_TX_FORMAT_Y16X16: |
| 926 | case R300_TX_FORMAT_FL_I16A16: | ||
| 913 | case R300_TX_FORMAT_Z11Y11X10: | 927 | case R300_TX_FORMAT_Z11Y11X10: |
| 914 | case R300_TX_FORMAT_Z10Y11X11: | 928 | case R300_TX_FORMAT_Z10Y11X11: |
| 915 | case R300_TX_FORMAT_W8Z8Y8X8: | 929 | case R300_TX_FORMAT_W8Z8Y8X8: |
| @@ -951,8 +965,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 951 | DRM_ERROR("Invalid texture format %u\n", | 965 | DRM_ERROR("Invalid texture format %u\n", |
| 952 | (idx_value & 0x1F)); | 966 | (idx_value & 0x1F)); |
| 953 | return -EINVAL; | 967 | return -EINVAL; |
| 954 | break; | ||
| 955 | } | 968 | } |
| 969 | track->tex_dirty = true; | ||
| 956 | break; | 970 | break; |
| 957 | case 0x4400: | 971 | case 0x4400: |
| 958 | case 0x4404: | 972 | case 0x4404: |
| @@ -980,6 +994,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 980 | if (tmp == 2 || tmp == 4 || tmp == 6) { | 994 | if (tmp == 2 || tmp == 4 || tmp == 6) { |
| 981 | track->textures[i].roundup_h = false; | 995 | track->textures[i].roundup_h = false; |
| 982 | } | 996 | } |
| 997 | track->tex_dirty = true; | ||
| 983 | break; | 998 | break; |
| 984 | case 0x4500: | 999 | case 0x4500: |
| 985 | case 0x4504: | 1000 | case 0x4504: |
| @@ -1017,6 +1032,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1017 | DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); | 1032 | DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); |
| 1018 | return -EINVAL; | 1033 | return -EINVAL; |
| 1019 | } | 1034 | } |
| 1035 | track->tex_dirty = true; | ||
| 1020 | break; | 1036 | break; |
| 1021 | case 0x4480: | 1037 | case 0x4480: |
| 1022 | case 0x4484: | 1038 | case 0x4484: |
| @@ -1046,6 +1062,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1046 | track->textures[i].use_pitch = !!tmp; | 1062 | track->textures[i].use_pitch = !!tmp; |
| 1047 | tmp = (idx_value >> 22) & 0xF; | 1063 | tmp = (idx_value >> 22) & 0xF; |
| 1048 | track->textures[i].txdepth = tmp; | 1064 | track->textures[i].txdepth = tmp; |
| 1065 | track->tex_dirty = true; | ||
| 1049 | break; | 1066 | break; |
| 1050 | case R300_ZB_ZPASS_ADDR: | 1067 | case R300_ZB_ZPASS_ADDR: |
| 1051 | r = r100_cs_packet_next_reloc(p, &reloc); | 1068 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1060,6 +1077,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1060 | case 0x4e0c: | 1077 | case 0x4e0c: |
| 1061 | /* RB3D_COLOR_CHANNEL_MASK */ | 1078 | /* RB3D_COLOR_CHANNEL_MASK */ |
| 1062 | track->color_channel_mask = idx_value; | 1079 | track->color_channel_mask = idx_value; |
| 1080 | track->cb_dirty = true; | ||
| 1063 | break; | 1081 | break; |
| 1064 | case 0x43a4: | 1082 | case 0x43a4: |
| 1065 | /* SC_HYPERZ_EN */ | 1083 | /* SC_HYPERZ_EN */ |
| @@ -1073,6 +1091,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1073 | case 0x4f1c: | 1091 | case 0x4f1c: |
| 1074 | /* ZB_BW_CNTL */ | 1092 | /* ZB_BW_CNTL */ |
| 1075 | track->zb_cb_clear = !!(idx_value & (1 << 5)); | 1093 | track->zb_cb_clear = !!(idx_value & (1 << 5)); |
| 1094 | track->cb_dirty = true; | ||
| 1095 | track->zb_dirty = true; | ||
| 1076 | if (p->rdev->hyperz_filp != p->filp) { | 1096 | if (p->rdev->hyperz_filp != p->filp) { |
| 1077 | if (idx_value & (R300_HIZ_ENABLE | | 1097 | if (idx_value & (R300_HIZ_ENABLE | |
| 1078 | R300_RD_COMP_ENABLE | | 1098 | R300_RD_COMP_ENABLE | |
| @@ -1084,8 +1104,28 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1084 | case 0x4e04: | 1104 | case 0x4e04: |
| 1085 | /* RB3D_BLENDCNTL */ | 1105 | /* RB3D_BLENDCNTL */ |
| 1086 | track->blend_read_enable = !!(idx_value & (1 << 2)); | 1106 | track->blend_read_enable = !!(idx_value & (1 << 2)); |
| 1107 | track->cb_dirty = true; | ||
| 1108 | break; | ||
| 1109 | case R300_RB3D_AARESOLVE_OFFSET: | ||
| 1110 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1111 | if (r) { | ||
| 1112 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
| 1113 | idx, reg); | ||
| 1114 | r100_cs_dump_packet(p, pkt); | ||
| 1115 | return r; | ||
| 1116 | } | ||
| 1117 | track->aa.robj = reloc->robj; | ||
| 1118 | track->aa.offset = idx_value; | ||
| 1119 | track->aa_dirty = true; | ||
| 1120 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | ||
| 1121 | break; | ||
| 1122 | case R300_RB3D_AARESOLVE_PITCH: | ||
| 1123 | track->aa.pitch = idx_value & 0x3FFE; | ||
| 1124 | track->aa_dirty = true; | ||
| 1087 | break; | 1125 | break; |
| 1088 | case 0x4f28: /* ZB_DEPTHCLEARVALUE */ | 1126 | case R300_RB3D_AARESOLVE_CTL: |
| 1127 | track->aaresolve = idx_value & 0x1; | ||
| 1128 | track->aa_dirty = true; | ||
| 1089 | break; | 1129 | break; |
| 1090 | case 0x4f30: /* ZB_MASK_OFFSET */ | 1130 | case 0x4f30: /* ZB_MASK_OFFSET */ |
| 1091 | case 0x4f34: /* ZB_ZMASK_PITCH */ | 1131 | case 0x4f34: /* ZB_ZMASK_PITCH */ |
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index 1a0d5362cd7..f0bce399c9f 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h | |||
| @@ -1371,6 +1371,8 @@ | |||
| 1371 | #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ | 1371 | #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ |
| 1372 | #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ | 1372 | #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ |
| 1373 | 1373 | ||
| 1374 | #define R300_RB3D_AARESOLVE_OFFSET 0x4E80 | ||
| 1375 | #define R300_RB3D_AARESOLVE_PITCH 0x4E84 | ||
| 1374 | #define R300_RB3D_AARESOLVE_CTL 0x4E88 | 1376 | #define R300_RB3D_AARESOLVE_CTL 0x4E88 |
| 1375 | /* gap */ | 1377 | /* gap */ |
| 1376 | 1378 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1e10e3e2ba2..de88624d5f8 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -97,12 +97,16 @@ void r600_irq_disable(struct radeon_device *rdev); | |||
| 97 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | 97 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); |
| 98 | 98 | ||
| 99 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
| 100 | u32 rv6xx_get_temp(struct radeon_device *rdev) | 100 | int rv6xx_get_temp(struct radeon_device *rdev) |
| 101 | { | 101 | { |
| 102 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> | 102 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> |
| 103 | ASIC_T_SHIFT; | 103 | ASIC_T_SHIFT; |
| 104 | int actual_temp = temp & 0xff; | ||
| 104 | 105 | ||
| 105 | return temp * 1000; | 106 | if (temp & 0x100) |
| 107 | actual_temp -= 256; | ||
| 108 | |||
| 109 | return actual_temp * 1000; | ||
| 106 | } | 110 | } |
| 107 | 111 | ||
| 108 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) | 112 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) |
| @@ -2101,7 +2105,11 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) | |||
| 2101 | 2105 | ||
| 2102 | r600_cp_stop(rdev); | 2106 | r600_cp_stop(rdev); |
| 2103 | 2107 | ||
| 2104 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | 2108 | WREG32(CP_RB_CNTL, |
| 2109 | #ifdef __BIG_ENDIAN | ||
| 2110 | BUF_SWAP_32BIT | | ||
| 2111 | #endif | ||
| 2112 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
| 2105 | 2113 | ||
| 2106 | /* Reset cp */ | 2114 | /* Reset cp */ |
| 2107 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | 2115 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); |
| @@ -2188,7 +2196,11 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
| 2188 | WREG32(CP_RB_WPTR, 0); | 2196 | WREG32(CP_RB_WPTR, 0); |
| 2189 | 2197 | ||
| 2190 | /* set the wb address whether it's enabled or not */ | 2198 | /* set the wb address whether it's enabled or not */ |
| 2191 | WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); | 2199 | WREG32(CP_RB_RPTR_ADDR, |
| 2200 | #ifdef __BIG_ENDIAN | ||
| 2201 | RB_RPTR_SWAP(2) | | ||
| 2202 | #endif | ||
| 2203 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | ||
| 2192 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | 2204 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); |
| 2193 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | 2205 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); |
| 2194 | 2206 | ||
| @@ -2624,7 +2636,11 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 2624 | { | 2636 | { |
| 2625 | /* FIXME: implement */ | 2637 | /* FIXME: implement */ |
| 2626 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 2638 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
| 2627 | radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); | 2639 | radeon_ring_write(rdev, |
| 2640 | #ifdef __BIG_ENDIAN | ||
| 2641 | (2 << 0) | | ||
| 2642 | #endif | ||
| 2643 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
| 2628 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | 2644 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); |
| 2629 | radeon_ring_write(rdev, ib->length_dw); | 2645 | radeon_ring_write(rdev, ib->length_dw); |
| 2630 | } | 2646 | } |
| @@ -3293,8 +3309,8 @@ restart_ih: | |||
| 3293 | while (rptr != wptr) { | 3309 | while (rptr != wptr) { |
| 3294 | /* wptr/rptr are in bytes! */ | 3310 | /* wptr/rptr are in bytes! */ |
| 3295 | ring_index = rptr / 4; | 3311 | ring_index = rptr / 4; |
| 3296 | src_id = rdev->ih.ring[ring_index] & 0xff; | 3312 | src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; |
| 3297 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | 3313 | src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; |
| 3298 | 3314 | ||
| 3299 | switch (src_id) { | 3315 | switch (src_id) { |
| 3300 | case 1: /* D1 vblank/vline */ | 3316 | case 1: /* D1 vblank/vline */ |
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c index ca5c29f7077..7f1043448d2 100644 --- a/drivers/gpu/drm/radeon/r600_blit.c +++ b/drivers/gpu/drm/radeon/r600_blit.c | |||
| @@ -137,9 +137,9 @@ set_shaders(struct drm_device *dev) | |||
| 137 | ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); | 137 | ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); |
| 138 | 138 | ||
| 139 | for (i = 0; i < r6xx_vs_size; i++) | 139 | for (i = 0; i < r6xx_vs_size; i++) |
| 140 | vs[i] = r6xx_vs[i]; | 140 | vs[i] = cpu_to_le32(r6xx_vs[i]); |
| 141 | for (i = 0; i < r6xx_ps_size; i++) | 141 | for (i = 0; i < r6xx_ps_size; i++) |
| 142 | ps[i] = r6xx_ps[i]; | 142 | ps[i] = cpu_to_le32(r6xx_ps[i]); |
| 143 | 143 | ||
| 144 | dev_priv->blit_vb->used = 512; | 144 | dev_priv->blit_vb->used = 512; |
| 145 | 145 | ||
| @@ -192,6 +192,9 @@ set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) | |||
| 192 | DRM_DEBUG("\n"); | 192 | DRM_DEBUG("\n"); |
| 193 | 193 | ||
| 194 | sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); | 194 | sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); |
| 195 | #ifdef __BIG_ENDIAN | ||
| 196 | sq_vtx_constant_word2 |= (2 << 30); | ||
| 197 | #endif | ||
| 195 | 198 | ||
| 196 | BEGIN_RING(9); | 199 | BEGIN_RING(9); |
| 197 | OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); | 200 | OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); |
| @@ -291,7 +294,11 @@ draw_auto(drm_radeon_private_t *dev_priv) | |||
| 291 | OUT_RING(DI_PT_RECTLIST); | 294 | OUT_RING(DI_PT_RECTLIST); |
| 292 | 295 | ||
| 293 | OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); | 296 | OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); |
| 297 | #ifdef __BIG_ENDIAN | ||
| 298 | OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT); | ||
| 299 | #else | ||
| 294 | OUT_RING(DI_INDEX_SIZE_16_BIT); | 300 | OUT_RING(DI_INDEX_SIZE_16_BIT); |
| 301 | #endif | ||
| 295 | 302 | ||
| 296 | OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); | 303 | OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); |
| 297 | OUT_RING(1); | 304 | OUT_RING(1); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 86e5aa07f0d..41f7aafc97c 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -54,7 +54,7 @@ set_render_target(struct radeon_device *rdev, int format, | |||
| 54 | if (h < 8) | 54 | if (h < 8) |
| 55 | h = 8; | 55 | h = 8; |
| 56 | 56 | ||
| 57 | cb_color_info = ((format << 2) | (1 << 27)); | 57 | cb_color_info = ((format << 2) | (1 << 27) | (1 << 8)); |
| 58 | pitch = (w / 8) - 1; | 58 | pitch = (w / 8) - 1; |
| 59 | slice = ((w * h) / 64) - 1; | 59 | slice = ((w * h) / 64) - 1; |
| 60 | 60 | ||
| @@ -165,6 +165,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
| 165 | u32 sq_vtx_constant_word2; | 165 | u32 sq_vtx_constant_word2; |
| 166 | 166 | ||
| 167 | sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); | 167 | sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); |
| 168 | #ifdef __BIG_ENDIAN | ||
| 169 | sq_vtx_constant_word2 |= (2 << 30); | ||
| 170 | #endif | ||
| 168 | 171 | ||
| 169 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); | 172 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); |
| 170 | radeon_ring_write(rdev, 0x460); | 173 | radeon_ring_write(rdev, 0x460); |
| @@ -199,7 +202,7 @@ set_tex_resource(struct radeon_device *rdev, | |||
| 199 | if (h < 1) | 202 | if (h < 1) |
| 200 | h = 1; | 203 | h = 1; |
| 201 | 204 | ||
| 202 | sq_tex_resource_word0 = (1 << 0); | 205 | sq_tex_resource_word0 = (1 << 0) | (1 << 3); |
| 203 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | | 206 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | |
| 204 | ((w - 1) << 19)); | 207 | ((w - 1) << 19)); |
| 205 | 208 | ||
| @@ -253,7 +256,11 @@ draw_auto(struct radeon_device *rdev) | |||
| 253 | radeon_ring_write(rdev, DI_PT_RECTLIST); | 256 | radeon_ring_write(rdev, DI_PT_RECTLIST); |
| 254 | 257 | ||
| 255 | radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); | 258 | radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); |
| 256 | radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); | 259 | radeon_ring_write(rdev, |
| 260 | #ifdef __BIG_ENDIAN | ||
| 261 | (2 << 2) | | ||
| 262 | #endif | ||
| 263 | DI_INDEX_SIZE_16_BIT); | ||
| 257 | 264 | ||
| 258 | radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); | 265 | radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); |
| 259 | radeon_ring_write(rdev, 1); | 266 | radeon_ring_write(rdev, 1); |
| @@ -424,7 +431,11 @@ set_default_state(struct radeon_device *rdev) | |||
| 424 | dwords = ALIGN(rdev->r600_blit.state_len, 0x10); | 431 | dwords = ALIGN(rdev->r600_blit.state_len, 0x10); |
| 425 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; | 432 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; |
| 426 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 433 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
| 427 | radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); | 434 | radeon_ring_write(rdev, |
| 435 | #ifdef __BIG_ENDIAN | ||
| 436 | (2 << 0) | | ||
| 437 | #endif | ||
| 438 | (gpu_addr & 0xFFFFFFFC)); | ||
| 428 | radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); | 439 | radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); |
| 429 | radeon_ring_write(rdev, dwords); | 440 | radeon_ring_write(rdev, dwords); |
| 430 | 441 | ||
| @@ -467,7 +478,7 @@ static inline uint32_t i2f(uint32_t input) | |||
| 467 | int r600_blit_init(struct radeon_device *rdev) | 478 | int r600_blit_init(struct radeon_device *rdev) |
| 468 | { | 479 | { |
| 469 | u32 obj_size; | 480 | u32 obj_size; |
| 470 | int r, dwords; | 481 | int i, r, dwords; |
| 471 | void *ptr; | 482 | void *ptr; |
| 472 | u32 packet2s[16]; | 483 | u32 packet2s[16]; |
| 473 | int num_packet2s = 0; | 484 | int num_packet2s = 0; |
| @@ -486,7 +497,7 @@ int r600_blit_init(struct radeon_device *rdev) | |||
| 486 | 497 | ||
| 487 | dwords = rdev->r600_blit.state_len; | 498 | dwords = rdev->r600_blit.state_len; |
| 488 | while (dwords & 0xf) { | 499 | while (dwords & 0xf) { |
| 489 | packet2s[num_packet2s++] = PACKET2(0); | 500 | packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); |
| 490 | dwords++; | 501 | dwords++; |
| 491 | } | 502 | } |
| 492 | 503 | ||
| @@ -529,8 +540,10 @@ int r600_blit_init(struct radeon_device *rdev) | |||
| 529 | if (num_packet2s) | 540 | if (num_packet2s) |
| 530 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), | 541 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), |
| 531 | packet2s, num_packet2s * 4); | 542 | packet2s, num_packet2s * 4); |
| 532 | memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); | 543 | for (i = 0; i < r6xx_vs_size; i++) |
| 533 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); | 544 | *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]); |
| 545 | for (i = 0; i < r6xx_ps_size; i++) | ||
| 546 | *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]); | ||
| 534 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | 547 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); |
| 535 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 548 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
| 536 | 549 | ||
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index e8151c1d55b..2d1f6c5ee2a 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c | |||
| @@ -684,7 +684,11 @@ const u32 r6xx_vs[] = | |||
| 684 | 0x00000000, | 684 | 0x00000000, |
| 685 | 0x3c000000, | 685 | 0x3c000000, |
| 686 | 0x68cd1000, | 686 | 0x68cd1000, |
| 687 | #ifdef __BIG_ENDIAN | ||
| 688 | 0x000a0000, | ||
| 689 | #else | ||
| 687 | 0x00080000, | 690 | 0x00080000, |
| 691 | #endif | ||
| 688 | 0x00000000, | 692 | 0x00000000, |
| 689 | }; | 693 | }; |
| 690 | 694 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 4f4cd8b286d..c3ab959bdc7 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
| @@ -396,6 +396,9 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
| 396 | r600_do_cp_stop(dev_priv); | 396 | r600_do_cp_stop(dev_priv); |
| 397 | 397 | ||
| 398 | RADEON_WRITE(R600_CP_RB_CNTL, | 398 | RADEON_WRITE(R600_CP_RB_CNTL, |
| 399 | #ifdef __BIG_ENDIAN | ||
| 400 | R600_BUF_SWAP_32BIT | | ||
| 401 | #endif | ||
| 399 | R600_RB_NO_UPDATE | | 402 | R600_RB_NO_UPDATE | |
| 400 | R600_RB_BLKSZ(15) | | 403 | R600_RB_BLKSZ(15) | |
| 401 | R600_RB_BUFSZ(3)); | 404 | R600_RB_BUFSZ(3)); |
| @@ -486,9 +489,12 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
| 486 | r600_do_cp_stop(dev_priv); | 489 | r600_do_cp_stop(dev_priv); |
| 487 | 490 | ||
| 488 | RADEON_WRITE(R600_CP_RB_CNTL, | 491 | RADEON_WRITE(R600_CP_RB_CNTL, |
| 492 | #ifdef __BIG_ENDIAN | ||
| 493 | R600_BUF_SWAP_32BIT | | ||
| 494 | #endif | ||
| 489 | R600_RB_NO_UPDATE | | 495 | R600_RB_NO_UPDATE | |
| 490 | (15 << 8) | | 496 | R600_RB_BLKSZ(15) | |
| 491 | (3 << 0)); | 497 | R600_RB_BUFSZ(3)); |
| 492 | 498 | ||
| 493 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 499 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
| 494 | RADEON_READ(R600_GRBM_SOFT_RESET); | 500 | RADEON_READ(R600_GRBM_SOFT_RESET); |
| @@ -550,8 +556,12 @@ static void r600_test_writeback(drm_radeon_private_t *dev_priv) | |||
| 550 | 556 | ||
| 551 | if (!dev_priv->writeback_works) { | 557 | if (!dev_priv->writeback_works) { |
| 552 | /* Disable writeback to avoid unnecessary bus master transfer */ | 558 | /* Disable writeback to avoid unnecessary bus master transfer */ |
| 553 | RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | | 559 | RADEON_WRITE(R600_CP_RB_CNTL, |
| 554 | RADEON_RB_NO_UPDATE); | 560 | #ifdef __BIG_ENDIAN |
| 561 | R600_BUF_SWAP_32BIT | | ||
| 562 | #endif | ||
| 563 | RADEON_READ(R600_CP_RB_CNTL) | | ||
| 564 | R600_RB_NO_UPDATE); | ||
| 555 | RADEON_WRITE(R600_SCRATCH_UMSK, 0); | 565 | RADEON_WRITE(R600_SCRATCH_UMSK, 0); |
| 556 | } | 566 | } |
| 557 | } | 567 | } |
| @@ -575,7 +585,11 @@ int r600_do_engine_reset(struct drm_device *dev) | |||
| 575 | 585 | ||
| 576 | RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); | 586 | RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); |
| 577 | cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); | 587 | cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); |
| 578 | RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); | 588 | RADEON_WRITE(R600_CP_RB_CNTL, |
| 589 | #ifdef __BIG_ENDIAN | ||
| 590 | R600_BUF_SWAP_32BIT | | ||
| 591 | #endif | ||
| 592 | R600_RB_RPTR_WR_ENA); | ||
| 579 | 593 | ||
| 580 | RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); | 594 | RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); |
| 581 | RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); | 595 | RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); |
| @@ -1838,7 +1852,10 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
| 1838 | + dev_priv->gart_vm_start; | 1852 | + dev_priv->gart_vm_start; |
| 1839 | } | 1853 | } |
| 1840 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, | 1854 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, |
| 1841 | rptr_addr & 0xffffffff); | 1855 | #ifdef __BIG_ENDIAN |
| 1856 | (2 << 0) | | ||
| 1857 | #endif | ||
| 1858 | (rptr_addr & 0xfffffffc)); | ||
| 1842 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, | 1859 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, |
| 1843 | upper_32_bits(rptr_addr)); | 1860 | upper_32_bits(rptr_addr)); |
| 1844 | 1861 | ||
| @@ -1889,7 +1906,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
| 1889 | { | 1906 | { |
| 1890 | u64 scratch_addr; | 1907 | u64 scratch_addr; |
| 1891 | 1908 | ||
| 1892 | scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); | 1909 | scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR) & 0xFFFFFFFC; |
| 1893 | scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; | 1910 | scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; |
| 1894 | scratch_addr += R600_SCRATCH_REG_OFFSET; | 1911 | scratch_addr += R600_SCRATCH_REG_OFFSET; |
| 1895 | scratch_addr >>= 8; | 1912 | scratch_addr >>= 8; |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 7831e089021..153095fba62 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -295,17 +295,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | if (!IS_ALIGNED(pitch, pitch_align)) { | 297 | if (!IS_ALIGNED(pitch, pitch_align)) { |
| 298 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | 298 | dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n", |
| 299 | __func__, __LINE__, pitch); | 299 | __func__, __LINE__, pitch, pitch_align, array_mode); |
| 300 | return -EINVAL; | 300 | return -EINVAL; |
| 301 | } | 301 | } |
| 302 | if (!IS_ALIGNED(height, height_align)) { | 302 | if (!IS_ALIGNED(height, height_align)) { |
| 303 | dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", | 303 | dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n", |
| 304 | __func__, __LINE__, height); | 304 | __func__, __LINE__, height, height_align, array_mode); |
| 305 | return -EINVAL; | 305 | return -EINVAL; |
| 306 | } | 306 | } |
| 307 | if (!IS_ALIGNED(base_offset, base_align)) { | 307 | if (!IS_ALIGNED(base_offset, base_align)) { |
| 308 | dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); | 308 | dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i, |
| 309 | base_offset, base_align, array_mode); | ||
| 309 | return -EINVAL; | 310 | return -EINVAL; |
| 310 | } | 311 | } |
| 311 | 312 | ||
| @@ -320,7 +321,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 320 | * broken userspace. | 321 | * broken userspace. |
| 321 | */ | 322 | */ |
| 322 | } else { | 323 | } else { |
| 323 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | 324 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i, |
| 325 | array_mode, | ||
| 326 | track->cb_color_bo_offset[i], tmp, | ||
| 327 | radeon_bo_size(track->cb_color_bo[i])); | ||
| 324 | return -EINVAL; | 328 | return -EINVAL; |
| 325 | } | 329 | } |
| 326 | } | 330 | } |
| @@ -455,17 +459,18 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 455 | } | 459 | } |
| 456 | 460 | ||
| 457 | if (!IS_ALIGNED(pitch, pitch_align)) { | 461 | if (!IS_ALIGNED(pitch, pitch_align)) { |
| 458 | dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", | 462 | dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", |
| 459 | __func__, __LINE__, pitch); | 463 | __func__, __LINE__, pitch, pitch_align, array_mode); |
| 460 | return -EINVAL; | 464 | return -EINVAL; |
| 461 | } | 465 | } |
| 462 | if (!IS_ALIGNED(height, height_align)) { | 466 | if (!IS_ALIGNED(height, height_align)) { |
| 463 | dev_warn(p->dev, "%s:%d db height (%d) invalid\n", | 467 | dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", |
| 464 | __func__, __LINE__, height); | 468 | __func__, __LINE__, height, height_align, array_mode); |
| 465 | return -EINVAL; | 469 | return -EINVAL; |
| 466 | } | 470 | } |
| 467 | if (!IS_ALIGNED(base_offset, base_align)) { | 471 | if (!IS_ALIGNED(base_offset, base_align)) { |
| 468 | dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); | 472 | dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i, |
| 473 | base_offset, base_align, array_mode); | ||
| 469 | return -EINVAL; | 474 | return -EINVAL; |
| 470 | } | 475 | } |
| 471 | 476 | ||
| @@ -473,9 +478,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 473 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 478 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
| 474 | tmp = ntiles * bpe * 64 * nviews; | 479 | tmp = ntiles * bpe * 64 * nviews; |
| 475 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | 480 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { |
| 476 | dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", | 481 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", |
| 477 | track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, | 482 | array_mode, |
| 478 | radeon_bo_size(track->db_bo)); | 483 | track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, |
| 484 | radeon_bo_size(track->db_bo)); | ||
| 479 | return -EINVAL; | 485 | return -EINVAL; |
| 480 | } | 486 | } |
| 481 | } | 487 | } |
| @@ -1227,18 +1233,18 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i | |||
| 1227 | /* XXX check height as well... */ | 1233 | /* XXX check height as well... */ |
| 1228 | 1234 | ||
| 1229 | if (!IS_ALIGNED(pitch, pitch_align)) { | 1235 | if (!IS_ALIGNED(pitch, pitch_align)) { |
| 1230 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", | 1236 | dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n", |
| 1231 | __func__, __LINE__, pitch); | 1237 | __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0)); |
| 1232 | return -EINVAL; | 1238 | return -EINVAL; |
| 1233 | } | 1239 | } |
| 1234 | if (!IS_ALIGNED(base_offset, base_align)) { | 1240 | if (!IS_ALIGNED(base_offset, base_align)) { |
| 1235 | dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", | 1241 | dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n", |
| 1236 | __func__, __LINE__, base_offset); | 1242 | __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0)); |
| 1237 | return -EINVAL; | 1243 | return -EINVAL; |
| 1238 | } | 1244 | } |
| 1239 | if (!IS_ALIGNED(mip_offset, base_align)) { | 1245 | if (!IS_ALIGNED(mip_offset, base_align)) { |
| 1240 | dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", | 1246 | dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n", |
| 1241 | __func__, __LINE__, mip_offset); | 1247 | __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0)); |
| 1242 | return -EINVAL; | 1248 | return -EINVAL; |
| 1243 | } | 1249 | } |
| 1244 | 1250 | ||
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a5d898b4bad..04bac0bbd3e 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -154,13 +154,14 @@ | |||
| 154 | #define ROQ_IB2_START(x) ((x) << 8) | 154 | #define ROQ_IB2_START(x) ((x) << 8) |
| 155 | #define CP_RB_BASE 0xC100 | 155 | #define CP_RB_BASE 0xC100 |
| 156 | #define CP_RB_CNTL 0xC104 | 156 | #define CP_RB_CNTL 0xC104 |
| 157 | #define RB_BUFSZ(x) ((x)<<0) | 157 | #define RB_BUFSZ(x) ((x) << 0) |
| 158 | #define RB_BLKSZ(x) ((x)<<8) | 158 | #define RB_BLKSZ(x) ((x) << 8) |
| 159 | #define RB_NO_UPDATE (1<<27) | 159 | #define RB_NO_UPDATE (1 << 27) |
| 160 | #define RB_RPTR_WR_ENA (1<<31) | 160 | #define RB_RPTR_WR_ENA (1 << 31) |
| 161 | #define BUF_SWAP_32BIT (2 << 16) | 161 | #define BUF_SWAP_32BIT (2 << 16) |
| 162 | #define CP_RB_RPTR 0x8700 | 162 | #define CP_RB_RPTR 0x8700 |
| 163 | #define CP_RB_RPTR_ADDR 0xC10C | 163 | #define CP_RB_RPTR_ADDR 0xC10C |
| 164 | #define RB_RPTR_SWAP(x) ((x) << 0) | ||
| 164 | #define CP_RB_RPTR_ADDR_HI 0xC110 | 165 | #define CP_RB_RPTR_ADDR_HI 0xC110 |
| 165 | #define CP_RB_RPTR_WR 0xC108 | 166 | #define CP_RB_RPTR_WR 0xC108 |
| 166 | #define CP_RB_WPTR 0xC114 | 167 | #define CP_RB_WPTR 0xC114 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 71d2a554bbe..56c48b67ef3 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -179,10 +179,10 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev); | |||
| 179 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); | 179 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
| 180 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); | 180 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); |
| 181 | void rs690_pm_info(struct radeon_device *rdev); | 181 | void rs690_pm_info(struct radeon_device *rdev); |
| 182 | extern u32 rv6xx_get_temp(struct radeon_device *rdev); | 182 | extern int rv6xx_get_temp(struct radeon_device *rdev); |
| 183 | extern u32 rv770_get_temp(struct radeon_device *rdev); | 183 | extern int rv770_get_temp(struct radeon_device *rdev); |
| 184 | extern u32 evergreen_get_temp(struct radeon_device *rdev); | 184 | extern int evergreen_get_temp(struct radeon_device *rdev); |
| 185 | extern u32 sumo_get_temp(struct radeon_device *rdev); | 185 | extern int sumo_get_temp(struct radeon_device *rdev); |
| 186 | 186 | ||
| 187 | /* | 187 | /* |
| 188 | * Fences. | 188 | * Fences. |
| @@ -812,8 +812,7 @@ struct radeon_pm { | |||
| 812 | fixed20_12 sclk; | 812 | fixed20_12 sclk; |
| 813 | fixed20_12 mclk; | 813 | fixed20_12 mclk; |
| 814 | fixed20_12 needed_bandwidth; | 814 | fixed20_12 needed_bandwidth; |
| 815 | /* XXX: use a define for num power modes */ | 815 | struct radeon_power_state *power_state; |
| 816 | struct radeon_power_state power_state[8]; | ||
| 817 | /* number of valid power states */ | 816 | /* number of valid power states */ |
| 818 | int num_power_states; | 817 | int num_power_states; |
| 819 | int current_power_state_index; | 818 | int current_power_state_index; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 3a1b1618622..e75d63b8e21 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -759,7 +759,7 @@ static struct radeon_asic evergreen_asic = { | |||
| 759 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, | 759 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 760 | .gart_set_page = &rs600_gart_set_page, | 760 | .gart_set_page = &rs600_gart_set_page, |
| 761 | .ring_test = &r600_ring_test, | 761 | .ring_test = &r600_ring_test, |
| 762 | .ring_ib_execute = &r600_ring_ib_execute, | 762 | .ring_ib_execute = &evergreen_ring_ib_execute, |
| 763 | .irq_set = &evergreen_irq_set, | 763 | .irq_set = &evergreen_irq_set, |
| 764 | .irq_process = &evergreen_irq_process, | 764 | .irq_process = &evergreen_irq_process, |
| 765 | .get_vblank_counter = &evergreen_get_vblank_counter, | 765 | .get_vblank_counter = &evergreen_get_vblank_counter, |
| @@ -805,7 +805,7 @@ static struct radeon_asic sumo_asic = { | |||
| 805 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, | 805 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 806 | .gart_set_page = &rs600_gart_set_page, | 806 | .gart_set_page = &rs600_gart_set_page, |
| 807 | .ring_test = &r600_ring_test, | 807 | .ring_test = &r600_ring_test, |
| 808 | .ring_ib_execute = &r600_ring_ib_execute, | 808 | .ring_ib_execute = &evergreen_ring_ib_execute, |
| 809 | .irq_set = &evergreen_irq_set, | 809 | .irq_set = &evergreen_irq_set, |
| 810 | .irq_process = &evergreen_irq_process, | 810 | .irq_process = &evergreen_irq_process, |
| 811 | .get_vblank_counter = &evergreen_get_vblank_counter, | 811 | .get_vblank_counter = &evergreen_get_vblank_counter, |
| @@ -848,7 +848,7 @@ static struct radeon_asic btc_asic = { | |||
| 848 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, | 848 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| 849 | .gart_set_page = &rs600_gart_set_page, | 849 | .gart_set_page = &rs600_gart_set_page, |
| 850 | .ring_test = &r600_ring_test, | 850 | .ring_test = &r600_ring_test, |
| 851 | .ring_ib_execute = &r600_ring_ib_execute, | 851 | .ring_ib_execute = &evergreen_ring_ib_execute, |
| 852 | .irq_set = &evergreen_irq_set, | 852 | .irq_set = &evergreen_irq_set, |
| 853 | .irq_process = &evergreen_irq_process, | 853 | .irq_process = &evergreen_irq_process, |
| 854 | .get_vblank_counter = &evergreen_get_vblank_counter, | 854 | .get_vblank_counter = &evergreen_get_vblank_counter, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index e01f0771853..c59bd98a202 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -355,6 +355,7 @@ int evergreen_resume(struct radeon_device *rdev); | |||
| 355 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev); | 355 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev); |
| 356 | int evergreen_asic_reset(struct radeon_device *rdev); | 356 | int evergreen_asic_reset(struct radeon_device *rdev); |
| 357 | void evergreen_bandwidth_update(struct radeon_device *rdev); | 357 | void evergreen_bandwidth_update(struct radeon_device *rdev); |
| 358 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | ||
| 358 | int evergreen_copy_blit(struct radeon_device *rdev, | 359 | int evergreen_copy_blit(struct radeon_device *rdev, |
| 359 | uint64_t src_offset, uint64_t dst_offset, | 360 | uint64_t src_offset, uint64_t dst_offset, |
| 360 | unsigned num_pages, struct radeon_fence *fence); | 361 | unsigned num_pages, struct radeon_fence *fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 52777902bbc..02d5c415f49 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -88,7 +88,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
| 88 | /* some evergreen boards have bad data for this entry */ | 88 | /* some evergreen boards have bad data for this entry */ |
| 89 | if (ASIC_IS_DCE4(rdev)) { | 89 | if (ASIC_IS_DCE4(rdev)) { |
| 90 | if ((i == 7) && | 90 | if ((i == 7) && |
| 91 | (gpio->usClkMaskRegisterIndex == 0x1936) && | 91 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && |
| 92 | (gpio->sucI2cId.ucAccess == 0)) { | 92 | (gpio->sucI2cId.ucAccess == 0)) { |
| 93 | gpio->sucI2cId.ucAccess = 0x97; | 93 | gpio->sucI2cId.ucAccess = 0x97; |
| 94 | gpio->ucDataMaskShift = 8; | 94 | gpio->ucDataMaskShift = 8; |
| @@ -101,7 +101,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
| 101 | /* some DCE3 boards have bad data for this entry */ | 101 | /* some DCE3 boards have bad data for this entry */ |
| 102 | if (ASIC_IS_DCE3(rdev)) { | 102 | if (ASIC_IS_DCE3(rdev)) { |
| 103 | if ((i == 4) && | 103 | if ((i == 4) && |
| 104 | (gpio->usClkMaskRegisterIndex == 0x1fda) && | 104 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && |
| 105 | (gpio->sucI2cId.ucAccess == 0x94)) | 105 | (gpio->sucI2cId.ucAccess == 0x94)) |
| 106 | gpio->sucI2cId.ucAccess = 0x14; | 106 | gpio->sucI2cId.ucAccess = 0x14; |
| 107 | } | 107 | } |
| @@ -172,7 +172,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
| 172 | /* some evergreen boards have bad data for this entry */ | 172 | /* some evergreen boards have bad data for this entry */ |
| 173 | if (ASIC_IS_DCE4(rdev)) { | 173 | if (ASIC_IS_DCE4(rdev)) { |
| 174 | if ((i == 7) && | 174 | if ((i == 7) && |
| 175 | (gpio->usClkMaskRegisterIndex == 0x1936) && | 175 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && |
| 176 | (gpio->sucI2cId.ucAccess == 0)) { | 176 | (gpio->sucI2cId.ucAccess == 0)) { |
| 177 | gpio->sucI2cId.ucAccess = 0x97; | 177 | gpio->sucI2cId.ucAccess = 0x97; |
| 178 | gpio->ucDataMaskShift = 8; | 178 | gpio->ucDataMaskShift = 8; |
| @@ -185,7 +185,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
| 185 | /* some DCE3 boards have bad data for this entry */ | 185 | /* some DCE3 boards have bad data for this entry */ |
| 186 | if (ASIC_IS_DCE3(rdev)) { | 186 | if (ASIC_IS_DCE3(rdev)) { |
| 187 | if ((i == 4) && | 187 | if ((i == 4) && |
| 188 | (gpio->usClkMaskRegisterIndex == 0x1fda) && | 188 | (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && |
| 189 | (gpio->sucI2cId.ucAccess == 0x94)) | 189 | (gpio->sucI2cId.ucAccess == 0x94)) |
| 190 | gpio->sucI2cId.ucAccess = 0x14; | 190 | gpio->sucI2cId.ucAccess = 0x14; |
| 191 | } | 191 | } |
| @@ -252,7 +252,7 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd | |||
| 252 | pin = &gpio_info->asGPIO_Pin[i]; | 252 | pin = &gpio_info->asGPIO_Pin[i]; |
| 253 | if (id == pin->ucGPIO_ID) { | 253 | if (id == pin->ucGPIO_ID) { |
| 254 | gpio.id = pin->ucGPIO_ID; | 254 | gpio.id = pin->ucGPIO_ID; |
| 255 | gpio.reg = pin->usGpioPin_AIndex * 4; | 255 | gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; |
| 256 | gpio.mask = (1 << pin->ucGpioPinBitShift); | 256 | gpio.mask = (1 << pin->ucGpioPinBitShift); |
| 257 | gpio.valid = true; | 257 | gpio.valid = true; |
| 258 | break; | 258 | break; |
| @@ -1163,16 +1163,6 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1163 | p1pll->pll_out_min = 64800; | 1163 | p1pll->pll_out_min = 64800; |
| 1164 | else | 1164 | else |
| 1165 | p1pll->pll_out_min = 20000; | 1165 | p1pll->pll_out_min = 20000; |
| 1166 | } else if (p1pll->pll_out_min > 64800) { | ||
| 1167 | /* Limiting the pll output range is a good thing generally as | ||
| 1168 | * it limits the number of possible pll combinations for a given | ||
| 1169 | * frequency presumably to the ones that work best on each card. | ||
| 1170 | * However, certain duallink DVI monitors seem to like | ||
| 1171 | * pll combinations that would be limited by this at least on | ||
| 1172 | * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per | ||
| 1173 | * family. | ||
| 1174 | */ | ||
| 1175 | p1pll->pll_out_min = 64800; | ||
| 1176 | } | 1166 | } |
| 1177 | 1167 | ||
| 1178 | p1pll->pll_in_min = | 1168 | p1pll->pll_in_min = |
| @@ -1284,11 +1274,11 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
| 1284 | data_offset); | 1274 | data_offset); |
| 1285 | switch (crev) { | 1275 | switch (crev) { |
| 1286 | case 1: | 1276 | case 1: |
| 1287 | if (igp_info->info.ulBootUpMemoryClock) | 1277 | if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock)) |
| 1288 | return true; | 1278 | return true; |
| 1289 | break; | 1279 | break; |
| 1290 | case 2: | 1280 | case 2: |
| 1291 | if (igp_info->info_2.ulBootUpSidePortClock) | 1281 | if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock)) |
| 1292 | return true; | 1282 | return true; |
| 1293 | break; | 1283 | break; |
| 1294 | default: | 1284 | default: |
| @@ -1452,7 +1442,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
| 1452 | 1442 | ||
| 1453 | for (i = 0; i < num_indices; i++) { | 1443 | for (i = 0; i < num_indices; i++) { |
| 1454 | if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && | 1444 | if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && |
| 1455 | (clock <= ss_info->info.asSpreadSpectrum[i].ulTargetClockRange)) { | 1445 | (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { |
| 1456 | ss->percentage = | 1446 | ss->percentage = |
| 1457 | le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1447 | le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
| 1458 | ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1448 | ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
| @@ -1466,7 +1456,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
| 1466 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); | 1456 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); |
| 1467 | for (i = 0; i < num_indices; i++) { | 1457 | for (i = 0; i < num_indices; i++) { |
| 1468 | if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && | 1458 | if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && |
| 1469 | (clock <= ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange)) { | 1459 | (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { |
| 1470 | ss->percentage = | 1460 | ss->percentage = |
| 1471 | le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1461 | le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
| 1472 | ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1462 | ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
| @@ -1480,7 +1470,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
| 1480 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); | 1470 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); |
| 1481 | for (i = 0; i < num_indices; i++) { | 1471 | for (i = 0; i < num_indices; i++) { |
| 1482 | if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && | 1472 | if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && |
| 1483 | (clock <= ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange)) { | 1473 | (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { |
| 1484 | ss->percentage = | 1474 | ss->percentage = |
| 1485 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1475 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
| 1486 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1476 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
| @@ -1563,8 +1553,8 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1563 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | 1553 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
| 1564 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; | 1554 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; |
| 1565 | 1555 | ||
| 1566 | lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize; | 1556 | lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize); |
| 1567 | lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize; | 1557 | lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize); |
| 1568 | 1558 | ||
| 1569 | /* set crtc values */ | 1559 | /* set crtc values */ |
| 1570 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | 1560 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
| @@ -1579,13 +1569,13 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1579 | lvds->linkb = false; | 1569 | lvds->linkb = false; |
| 1580 | 1570 | ||
| 1581 | /* parse the lcd record table */ | 1571 | /* parse the lcd record table */ |
| 1582 | if (lvds_info->info.usModePatchTableOffset) { | 1572 | if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) { |
| 1583 | ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; | 1573 | ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; |
| 1584 | ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; | 1574 | ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; |
| 1585 | bool bad_record = false; | 1575 | bool bad_record = false; |
| 1586 | u8 *record = (u8 *)(mode_info->atom_context->bios + | 1576 | u8 *record = (u8 *)(mode_info->atom_context->bios + |
| 1587 | data_offset + | 1577 | data_offset + |
| 1588 | lvds_info->info.usModePatchTableOffset); | 1578 | le16_to_cpu(lvds_info->info.usModePatchTableOffset)); |
| 1589 | while (*record != ATOM_RECORD_END_TYPE) { | 1579 | while (*record != ATOM_RECORD_END_TYPE) { |
| 1590 | switch (*record) { | 1580 | switch (*record) { |
| 1591 | case LCD_MODE_PATCH_RECORD_MODE_TYPE: | 1581 | case LCD_MODE_PATCH_RECORD_MODE_TYPE: |
| @@ -1987,6 +1977,9 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
| 1987 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 1977 | num_modes = power_info->info.ucNumOfPowerModeEntries; |
| 1988 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 1978 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) |
| 1989 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 1979 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; |
| 1980 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); | ||
| 1981 | if (!rdev->pm.power_state) | ||
| 1982 | return state_index; | ||
| 1990 | /* last mode is usually default, array is low to high */ | 1983 | /* last mode is usually default, array is low to high */ |
| 1991 | for (i = 0; i < num_modes; i++) { | 1984 | for (i = 0; i < num_modes; i++) { |
| 1992 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 1985 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
| @@ -2196,7 +2189,7 @@ static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) | |||
| 2196 | firmware_info = | 2189 | firmware_info = |
| 2197 | (union firmware_info *)(mode_info->atom_context->bios + | 2190 | (union firmware_info *)(mode_info->atom_context->bios + |
| 2198 | data_offset); | 2191 | data_offset); |
| 2199 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; | 2192 | vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); |
| 2200 | } | 2193 | } |
| 2201 | 2194 | ||
| 2202 | return vddc; | 2195 | return vddc; |
| @@ -2291,7 +2284,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 2291 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2284 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
| 2292 | VOLTAGE_SW; | 2285 | VOLTAGE_SW; |
| 2293 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2286 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
| 2294 | clock_info->evergreen.usVDDC; | 2287 | le16_to_cpu(clock_info->evergreen.usVDDC); |
| 2295 | } else { | 2288 | } else { |
| 2296 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | 2289 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); |
| 2297 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | 2290 | sclk |= clock_info->r600.ucEngineClockHigh << 16; |
| @@ -2302,7 +2295,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 2302 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2295 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
| 2303 | VOLTAGE_SW; | 2296 | VOLTAGE_SW; |
| 2304 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2297 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
| 2305 | clock_info->r600.usVDDC; | 2298 | le16_to_cpu(clock_info->r600.usVDDC); |
| 2306 | } | 2299 | } |
| 2307 | 2300 | ||
| 2308 | if (rdev->flags & RADEON_IS_IGP) { | 2301 | if (rdev->flags & RADEON_IS_IGP) { |
| @@ -2338,6 +2331,10 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) | |||
| 2338 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 2331 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
| 2339 | 2332 | ||
| 2340 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | 2333 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
| 2334 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * | ||
| 2335 | power_info->pplib.ucNumStates, GFP_KERNEL); | ||
| 2336 | if (!rdev->pm.power_state) | ||
| 2337 | return state_index; | ||
| 2341 | /* first mode is usually default, followed by low to high */ | 2338 | /* first mode is usually default, followed by low to high */ |
| 2342 | for (i = 0; i < power_info->pplib.ucNumStates; i++) { | 2339 | for (i = 0; i < power_info->pplib.ucNumStates; i++) { |
| 2343 | mode_index = 0; | 2340 | mode_index = 0; |
| @@ -2411,13 +2408,17 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | |||
| 2411 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | 2408 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
| 2412 | state_array = (struct StateArray *) | 2409 | state_array = (struct StateArray *) |
| 2413 | (mode_info->atom_context->bios + data_offset + | 2410 | (mode_info->atom_context->bios + data_offset + |
| 2414 | power_info->pplib.usStateArrayOffset); | 2411 | le16_to_cpu(power_info->pplib.usStateArrayOffset)); |
| 2415 | clock_info_array = (struct ClockInfoArray *) | 2412 | clock_info_array = (struct ClockInfoArray *) |
| 2416 | (mode_info->atom_context->bios + data_offset + | 2413 | (mode_info->atom_context->bios + data_offset + |
| 2417 | power_info->pplib.usClockInfoArrayOffset); | 2414 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset)); |
| 2418 | non_clock_info_array = (struct NonClockInfoArray *) | 2415 | non_clock_info_array = (struct NonClockInfoArray *) |
| 2419 | (mode_info->atom_context->bios + data_offset + | 2416 | (mode_info->atom_context->bios + data_offset + |
| 2420 | power_info->pplib.usNonClockInfoArrayOffset); | 2417 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); |
| 2418 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * | ||
| 2419 | state_array->ucNumEntries, GFP_KERNEL); | ||
| 2420 | if (!rdev->pm.power_state) | ||
| 2421 | return state_index; | ||
| 2421 | for (i = 0; i < state_array->ucNumEntries; i++) { | 2422 | for (i = 0; i < state_array->ucNumEntries; i++) { |
| 2422 | mode_index = 0; | 2423 | mode_index = 0; |
| 2423 | power_state = (union pplib_power_state *)&state_array->states[i]; | 2424 | power_state = (union pplib_power_state *)&state_array->states[i]; |
| @@ -2491,19 +2492,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
| 2491 | break; | 2492 | break; |
| 2492 | } | 2493 | } |
| 2493 | } else { | 2494 | } else { |
| 2494 | /* add the default mode */ | 2495 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); |
| 2495 | rdev->pm.power_state[state_index].type = | 2496 | if (rdev->pm.power_state) { |
| 2496 | POWER_STATE_TYPE_DEFAULT; | 2497 | /* add the default mode */ |
| 2497 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2498 | rdev->pm.power_state[state_index].type = |
| 2498 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; | 2499 | POWER_STATE_TYPE_DEFAULT; |
| 2499 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; | 2500 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2500 | rdev->pm.power_state[state_index].default_clock_mode = | 2501 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; |
| 2501 | &rdev->pm.power_state[state_index].clock_info[0]; | 2502 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; |
| 2502 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 2503 | rdev->pm.power_state[state_index].default_clock_mode = |
| 2503 | rdev->pm.power_state[state_index].pcie_lanes = 16; | 2504 | &rdev->pm.power_state[state_index].clock_info[0]; |
| 2504 | rdev->pm.default_power_state_index = state_index; | 2505 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
| 2505 | rdev->pm.power_state[state_index].flags = 0; | 2506 | rdev->pm.power_state[state_index].pcie_lanes = 16; |
| 2506 | state_index++; | 2507 | rdev->pm.default_power_state_index = state_index; |
| 2508 | rdev->pm.power_state[state_index].flags = 0; | ||
| 2509 | state_index++; | ||
| 2510 | } | ||
| 2507 | } | 2511 | } |
| 2508 | 2512 | ||
| 2509 | rdev->pm.num_power_states = state_index; | 2513 | rdev->pm.num_power_states = state_index; |
| @@ -2529,7 +2533,7 @@ uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) | |||
| 2529 | int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); | 2533 | int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); |
| 2530 | 2534 | ||
| 2531 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2535 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 2532 | return args.ulReturnEngineClock; | 2536 | return le32_to_cpu(args.ulReturnEngineClock); |
| 2533 | } | 2537 | } |
| 2534 | 2538 | ||
| 2535 | uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) | 2539 | uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) |
| @@ -2538,7 +2542,7 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) | |||
| 2538 | int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); | 2542 | int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); |
| 2539 | 2543 | ||
| 2540 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2544 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 2541 | return args.ulReturnMemoryClock; | 2545 | return le32_to_cpu(args.ulReturnMemoryClock); |
| 2542 | } | 2546 | } |
| 2543 | 2547 | ||
| 2544 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, | 2548 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, |
| @@ -2547,7 +2551,7 @@ void radeon_atom_set_engine_clock(struct radeon_device *rdev, | |||
| 2547 | SET_ENGINE_CLOCK_PS_ALLOCATION args; | 2551 | SET_ENGINE_CLOCK_PS_ALLOCATION args; |
| 2548 | int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); | 2552 | int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); |
| 2549 | 2553 | ||
| 2550 | args.ulTargetEngineClock = eng_clock; /* 10 khz */ | 2554 | args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */ |
| 2551 | 2555 | ||
| 2552 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2556 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 2553 | } | 2557 | } |
| @@ -2561,7 +2565,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, | |||
| 2561 | if (rdev->flags & RADEON_IS_IGP) | 2565 | if (rdev->flags & RADEON_IS_IGP) |
| 2562 | return; | 2566 | return; |
| 2563 | 2567 | ||
| 2564 | args.ulTargetMemoryClock = mem_clock; /* 10 khz */ | 2568 | args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ |
| 2565 | 2569 | ||
| 2566 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2570 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 2567 | } | 2571 | } |
| @@ -2619,7 +2623,7 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) | |||
| 2619 | bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; | 2623 | bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; |
| 2620 | 2624 | ||
| 2621 | /* tell the bios not to handle mode switching */ | 2625 | /* tell the bios not to handle mode switching */ |
| 2622 | bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH | ATOM_S6_ACC_MODE); | 2626 | bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; |
| 2623 | 2627 | ||
| 2624 | if (rdev->family >= CHIP_R600) { | 2628 | if (rdev->family >= CHIP_R600) { |
| 2625 | WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); | 2629 | WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); |
| @@ -2670,10 +2674,13 @@ void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) | |||
| 2670 | else | 2674 | else |
| 2671 | bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); | 2675 | bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); |
| 2672 | 2676 | ||
| 2673 | if (lock) | 2677 | if (lock) { |
| 2674 | bios_6_scratch |= ATOM_S6_CRITICAL_STATE; | 2678 | bios_6_scratch |= ATOM_S6_CRITICAL_STATE; |
| 2675 | else | 2679 | bios_6_scratch &= ~ATOM_S6_ACC_MODE; |
| 2680 | } else { | ||
| 2676 | bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; | 2681 | bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; |
| 2682 | bios_6_scratch |= ATOM_S6_ACC_MODE; | ||
| 2683 | } | ||
| 2677 | 2684 | ||
| 2678 | if (rdev->family >= CHIP_R600) | 2685 | if (rdev->family >= CHIP_R600) |
| 2679 | WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); | 2686 | WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 591fcae8f22..cf7c8d5b4ec 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -1504,6 +1504,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1504 | (rdev->pdev->subsystem_device == 0x4a48)) { | 1504 | (rdev->pdev->subsystem_device == 0x4a48)) { |
| 1505 | /* Mac X800 */ | 1505 | /* Mac X800 */ |
| 1506 | rdev->mode_info.connector_table = CT_MAC_X800; | 1506 | rdev->mode_info.connector_table = CT_MAC_X800; |
| 1507 | } else if ((rdev->pdev->device == 0x4150) && | ||
| 1508 | (rdev->pdev->subsystem_vendor == 0x1002) && | ||
| 1509 | (rdev->pdev->subsystem_device == 0x4150)) { | ||
| 1510 | /* Mac G5 9600 */ | ||
| 1511 | rdev->mode_info.connector_table = CT_MAC_G5_9600; | ||
| 1507 | } else | 1512 | } else |
| 1508 | #endif /* CONFIG_PPC_PMAC */ | 1513 | #endif /* CONFIG_PPC_PMAC */ |
| 1509 | #ifdef CONFIG_PPC64 | 1514 | #ifdef CONFIG_PPC64 |
| @@ -2022,6 +2027,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 2022 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, | 2027 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, |
| 2023 | &hpd); | 2028 | &hpd); |
| 2024 | break; | 2029 | break; |
| 2030 | case CT_MAC_G5_9600: | ||
| 2031 | DRM_INFO("Connector Table: %d (mac g5 9600)\n", | ||
| 2032 | rdev->mode_info.connector_table); | ||
| 2033 | /* DVI - tv dac, dvo */ | ||
| 2034 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | ||
| 2035 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
| 2036 | radeon_add_legacy_encoder(dev, | ||
| 2037 | radeon_get_encoder_enum(dev, | ||
| 2038 | ATOM_DEVICE_DFP2_SUPPORT, | ||
| 2039 | 0), | ||
| 2040 | ATOM_DEVICE_DFP2_SUPPORT); | ||
| 2041 | radeon_add_legacy_encoder(dev, | ||
| 2042 | radeon_get_encoder_enum(dev, | ||
| 2043 | ATOM_DEVICE_CRT2_SUPPORT, | ||
| 2044 | 2), | ||
| 2045 | ATOM_DEVICE_CRT2_SUPPORT); | ||
| 2046 | radeon_add_legacy_connector(dev, 0, | ||
| 2047 | ATOM_DEVICE_DFP2_SUPPORT | | ||
| 2048 | ATOM_DEVICE_CRT2_SUPPORT, | ||
| 2049 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
| 2050 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
| 2051 | &hpd); | ||
| 2052 | /* ADC - primary dac, internal tmds */ | ||
| 2053 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | ||
| 2054 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
| 2055 | radeon_add_legacy_encoder(dev, | ||
| 2056 | radeon_get_encoder_enum(dev, | ||
| 2057 | ATOM_DEVICE_DFP1_SUPPORT, | ||
| 2058 | 0), | ||
| 2059 | ATOM_DEVICE_DFP1_SUPPORT); | ||
| 2060 | radeon_add_legacy_encoder(dev, | ||
| 2061 | radeon_get_encoder_enum(dev, | ||
| 2062 | ATOM_DEVICE_CRT1_SUPPORT, | ||
| 2063 | 1), | ||
| 2064 | ATOM_DEVICE_CRT1_SUPPORT); | ||
| 2065 | radeon_add_legacy_connector(dev, 1, | ||
| 2066 | ATOM_DEVICE_DFP1_SUPPORT | | ||
| 2067 | ATOM_DEVICE_CRT1_SUPPORT, | ||
| 2068 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
| 2069 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
| 2070 | &hpd); | ||
| 2071 | break; | ||
| 2025 | default: | 2072 | default: |
| 2026 | DRM_INFO("Connector table: %d (invalid)\n", | 2073 | DRM_INFO("Connector table: %d (invalid)\n", |
| 2027 | rdev->mode_info.connector_table); | 2074 | rdev->mode_info.connector_table); |
| @@ -2442,6 +2489,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) | |||
| 2442 | 2489 | ||
| 2443 | rdev->pm.default_power_state_index = -1; | 2490 | rdev->pm.default_power_state_index = -1; |
| 2444 | 2491 | ||
| 2492 | /* allocate 2 power states */ | ||
| 2493 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); | ||
| 2494 | if (!rdev->pm.power_state) { | ||
| 2495 | rdev->pm.default_power_state_index = state_index; | ||
| 2496 | rdev->pm.num_power_states = 0; | ||
| 2497 | |||
| 2498 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | ||
| 2499 | rdev->pm.current_clock_mode_index = 0; | ||
| 2500 | return; | ||
| 2501 | } | ||
| 2502 | |||
| 2445 | if (rdev->flags & RADEON_IS_MOBILITY) { | 2503 | if (rdev->flags & RADEON_IS_MOBILITY) { |
| 2446 | offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); | 2504 | offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); |
| 2447 | if (offset) { | 2505 | if (offset) { |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0d478932b1a..4954e2d6ffa 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -936,8 +936,11 @@ int radeon_resume_kms(struct drm_device *dev) | |||
| 936 | int radeon_gpu_reset(struct radeon_device *rdev) | 936 | int radeon_gpu_reset(struct radeon_device *rdev) |
| 937 | { | 937 | { |
| 938 | int r; | 938 | int r; |
| 939 | int resched; | ||
| 939 | 940 | ||
| 940 | radeon_save_bios_scratch_regs(rdev); | 941 | radeon_save_bios_scratch_regs(rdev); |
| 942 | /* block TTM */ | ||
| 943 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | ||
| 941 | radeon_suspend(rdev); | 944 | radeon_suspend(rdev); |
| 942 | 945 | ||
| 943 | r = radeon_asic_reset(rdev); | 946 | r = radeon_asic_reset(rdev); |
| @@ -946,6 +949,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
| 946 | radeon_resume(rdev); | 949 | radeon_resume(rdev); |
| 947 | radeon_restore_bios_scratch_regs(rdev); | 950 | radeon_restore_bios_scratch_regs(rdev); |
| 948 | drm_helper_resume_force_mode(rdev->ddev); | 951 | drm_helper_resume_force_mode(rdev->ddev); |
| 952 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | ||
| 949 | return 0; | 953 | return 0; |
| 950 | } | 954 | } |
| 951 | /* bad news, how to tell it to userspace ? */ | 955 | /* bad news, how to tell it to userspace ? */ |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d26dabf878d..0e657095de7 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -780,6 +780,125 @@ static int radeon_ddc_dump(struct drm_connector *connector) | |||
| 780 | return ret; | 780 | return ret; |
| 781 | } | 781 | } |
| 782 | 782 | ||
| 783 | /* avivo */ | ||
| 784 | static void avivo_get_fb_div(struct radeon_pll *pll, | ||
| 785 | u32 target_clock, | ||
| 786 | u32 post_div, | ||
| 787 | u32 ref_div, | ||
| 788 | u32 *fb_div, | ||
| 789 | u32 *frac_fb_div) | ||
| 790 | { | ||
| 791 | u32 tmp = post_div * ref_div; | ||
| 792 | |||
| 793 | tmp *= target_clock; | ||
| 794 | *fb_div = tmp / pll->reference_freq; | ||
| 795 | *frac_fb_div = tmp % pll->reference_freq; | ||
| 796 | |||
| 797 | if (*fb_div > pll->max_feedback_div) | ||
| 798 | *fb_div = pll->max_feedback_div; | ||
| 799 | else if (*fb_div < pll->min_feedback_div) | ||
| 800 | *fb_div = pll->min_feedback_div; | ||
| 801 | } | ||
| 802 | |||
| 803 | static u32 avivo_get_post_div(struct radeon_pll *pll, | ||
| 804 | u32 target_clock) | ||
| 805 | { | ||
| 806 | u32 vco, post_div, tmp; | ||
| 807 | |||
| 808 | if (pll->flags & RADEON_PLL_USE_POST_DIV) | ||
| 809 | return pll->post_div; | ||
| 810 | |||
| 811 | if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) { | ||
| 812 | if (pll->flags & RADEON_PLL_IS_LCD) | ||
| 813 | vco = pll->lcd_pll_out_min; | ||
| 814 | else | ||
| 815 | vco = pll->pll_out_min; | ||
| 816 | } else { | ||
| 817 | if (pll->flags & RADEON_PLL_IS_LCD) | ||
| 818 | vco = pll->lcd_pll_out_max; | ||
| 819 | else | ||
| 820 | vco = pll->pll_out_max; | ||
| 821 | } | ||
| 822 | |||
| 823 | post_div = vco / target_clock; | ||
| 824 | tmp = vco % target_clock; | ||
| 825 | |||
| 826 | if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) { | ||
| 827 | if (tmp) | ||
| 828 | post_div++; | ||
| 829 | } else { | ||
| 830 | if (!tmp) | ||
| 831 | post_div--; | ||
| 832 | } | ||
| 833 | |||
| 834 | if (post_div > pll->max_post_div) | ||
| 835 | post_div = pll->max_post_div; | ||
| 836 | else if (post_div < pll->min_post_div) | ||
| 837 | post_div = pll->min_post_div; | ||
| 838 | |||
| 839 | return post_div; | ||
| 840 | } | ||
| 841 | |||
| 842 | #define MAX_TOLERANCE 10 | ||
| 843 | |||
| 844 | void radeon_compute_pll_avivo(struct radeon_pll *pll, | ||
| 845 | u32 freq, | ||
| 846 | u32 *dot_clock_p, | ||
| 847 | u32 *fb_div_p, | ||
| 848 | u32 *frac_fb_div_p, | ||
| 849 | u32 *ref_div_p, | ||
| 850 | u32 *post_div_p) | ||
| 851 | { | ||
| 852 | u32 target_clock = freq / 10; | ||
| 853 | u32 post_div = avivo_get_post_div(pll, target_clock); | ||
| 854 | u32 ref_div = pll->min_ref_div; | ||
| 855 | u32 fb_div = 0, frac_fb_div = 0, tmp; | ||
| 856 | |||
| 857 | if (pll->flags & RADEON_PLL_USE_REF_DIV) | ||
| 858 | ref_div = pll->reference_div; | ||
| 859 | |||
| 860 | if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { | ||
| 861 | avivo_get_fb_div(pll, target_clock, post_div, ref_div, &fb_div, &frac_fb_div); | ||
| 862 | frac_fb_div = (100 * frac_fb_div) / pll->reference_freq; | ||
| 863 | if (frac_fb_div >= 5) { | ||
| 864 | frac_fb_div -= 5; | ||
| 865 | frac_fb_div = frac_fb_div / 10; | ||
| 866 | frac_fb_div++; | ||
| 867 | } | ||
| 868 | if (frac_fb_div >= 10) { | ||
| 869 | fb_div++; | ||
| 870 | frac_fb_div = 0; | ||
| 871 | } | ||
| 872 | } else { | ||
| 873 | while (ref_div <= pll->max_ref_div) { | ||
| 874 | avivo_get_fb_div(pll, target_clock, post_div, ref_div, | ||
| 875 | &fb_div, &frac_fb_div); | ||
| 876 | if (frac_fb_div >= (pll->reference_freq / 2)) | ||
| 877 | fb_div++; | ||
| 878 | frac_fb_div = 0; | ||
| 879 | tmp = (pll->reference_freq * fb_div) / (post_div * ref_div); | ||
| 880 | tmp = (tmp * 10000) / target_clock; | ||
| 881 | |||
| 882 | if (tmp > (10000 + MAX_TOLERANCE)) | ||
| 883 | ref_div++; | ||
| 884 | else if (tmp >= (10000 - MAX_TOLERANCE)) | ||
| 885 | break; | ||
| 886 | else | ||
| 887 | ref_div++; | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | *dot_clock_p = ((pll->reference_freq * fb_div * 10) + (pll->reference_freq * frac_fb_div)) / | ||
| 892 | (ref_div * post_div * 10); | ||
| 893 | *fb_div_p = fb_div; | ||
| 894 | *frac_fb_div_p = frac_fb_div; | ||
| 895 | *ref_div_p = ref_div; | ||
| 896 | *post_div_p = post_div; | ||
| 897 | DRM_DEBUG_KMS("%d, pll dividers - fb: %d.%d ref: %d, post %d\n", | ||
| 898 | *dot_clock_p, fb_div, frac_fb_div, ref_div, post_div); | ||
| 899 | } | ||
| 900 | |||
| 901 | /* pre-avivo */ | ||
| 783 | static inline uint32_t radeon_div(uint64_t n, uint32_t d) | 902 | static inline uint32_t radeon_div(uint64_t n, uint32_t d) |
| 784 | { | 903 | { |
| 785 | uint64_t mod; | 904 | uint64_t mod; |
| @@ -790,13 +909,13 @@ static inline uint32_t radeon_div(uint64_t n, uint32_t d) | |||
| 790 | return n; | 909 | return n; |
| 791 | } | 910 | } |
| 792 | 911 | ||
| 793 | void radeon_compute_pll(struct radeon_pll *pll, | 912 | void radeon_compute_pll_legacy(struct radeon_pll *pll, |
| 794 | uint64_t freq, | 913 | uint64_t freq, |
| 795 | uint32_t *dot_clock_p, | 914 | uint32_t *dot_clock_p, |
| 796 | uint32_t *fb_div_p, | 915 | uint32_t *fb_div_p, |
| 797 | uint32_t *frac_fb_div_p, | 916 | uint32_t *frac_fb_div_p, |
| 798 | uint32_t *ref_div_p, | 917 | uint32_t *ref_div_p, |
| 799 | uint32_t *post_div_p) | 918 | uint32_t *post_div_p) |
| 800 | { | 919 | { |
| 801 | uint32_t min_ref_div = pll->min_ref_div; | 920 | uint32_t min_ref_div = pll->min_ref_div; |
| 802 | uint32_t max_ref_div = pll->max_ref_div; | 921 | uint32_t max_ref_div = pll->max_ref_div; |
| @@ -826,6 +945,9 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 826 | pll_out_max = pll->pll_out_max; | 945 | pll_out_max = pll->pll_out_max; |
| 827 | } | 946 | } |
| 828 | 947 | ||
| 948 | if (pll_out_min > 64800) | ||
| 949 | pll_out_min = 64800; | ||
| 950 | |||
| 829 | if (pll->flags & RADEON_PLL_USE_REF_DIV) | 951 | if (pll->flags & RADEON_PLL_USE_REF_DIV) |
| 830 | min_ref_div = max_ref_div = pll->reference_div; | 952 | min_ref_div = max_ref_div = pll->reference_div; |
| 831 | else { | 953 | else { |
| @@ -849,7 +971,7 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 849 | max_fractional_feed_div = pll->max_frac_feedback_div; | 971 | max_fractional_feed_div = pll->max_frac_feedback_div; |
| 850 | } | 972 | } |
| 851 | 973 | ||
| 852 | for (post_div = max_post_div; post_div >= min_post_div; --post_div) { | 974 | for (post_div = min_post_div; post_div <= max_post_div; ++post_div) { |
| 853 | uint32_t ref_div; | 975 | uint32_t ref_div; |
| 854 | 976 | ||
| 855 | if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) | 977 | if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) |
| @@ -965,6 +1087,10 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 965 | *frac_fb_div_p = best_frac_feedback_div; | 1087 | *frac_fb_div_p = best_frac_feedback_div; |
| 966 | *ref_div_p = best_ref_div; | 1088 | *ref_div_p = best_ref_div; |
| 967 | *post_div_p = best_post_div; | 1089 | *post_div_p = best_post_div; |
| 1090 | DRM_DEBUG_KMS("%d %d, pll dividers - fb: %d.%d ref: %d, post %d\n", | ||
| 1091 | freq, best_freq / 1000, best_feedback_div, best_frac_feedback_div, | ||
| 1092 | best_ref_div, best_post_div); | ||
| 1093 | |||
| 968 | } | 1094 | } |
| 969 | 1095 | ||
| 970 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | 1096 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 448eba89d1e..5cba46b9779 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
| @@ -1524,6 +1524,7 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); | |||
| 1524 | #define R600_CP_RB_CNTL 0xc104 | 1524 | #define R600_CP_RB_CNTL 0xc104 |
| 1525 | # define R600_RB_BUFSZ(x) ((x) << 0) | 1525 | # define R600_RB_BUFSZ(x) ((x) << 0) |
| 1526 | # define R600_RB_BLKSZ(x) ((x) << 8) | 1526 | # define R600_RB_BLKSZ(x) ((x) << 8) |
| 1527 | # define R600_BUF_SWAP_32BIT (2 << 16) | ||
| 1527 | # define R600_RB_NO_UPDATE (1 << 27) | 1528 | # define R600_RB_NO_UPDATE (1 << 27) |
| 1528 | # define R600_RB_RPTR_WR_ENA (1 << 31) | 1529 | # define R600_RB_RPTR_WR_ENA (1 << 31) |
| 1529 | #define R600_CP_RB_RPTR_WR 0xc108 | 1530 | #define R600_CP_RB_RPTR_WR 0xc108 |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 5e90984d5ad..b4274883227 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -910,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 910 | 910 | ||
| 911 | args.v1.ucAction = action; | 911 | args.v1.ucAction = action; |
| 912 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 912 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
| 913 | args.v1.usInitInfo = connector_object_id; | 913 | args.v1.usInitInfo = cpu_to_le16(connector_object_id); |
| 914 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | 914 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { |
| 915 | args.v1.asMode.ucLaneSel = lane_num; | 915 | args.v1.asMode.ucLaneSel = lane_num; |
| 916 | args.v1.asMode.ucLaneSet = lane_set; | 916 | args.v1.asMode.ucLaneSet = lane_set; |
| @@ -1063,7 +1063,7 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action) | |||
| 1063 | if (!ASIC_IS_DCE4(rdev)) | 1063 | if (!ASIC_IS_DCE4(rdev)) |
| 1064 | return; | 1064 | return; |
| 1065 | 1065 | ||
| 1066 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) || | 1066 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && |
| 1067 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | 1067 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) |
| 1068 | return; | 1068 | return; |
| 1069 | 1069 | ||
| @@ -1140,7 +1140,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1140 | case 3: | 1140 | case 3: |
| 1141 | args.v3.sExtEncoder.ucAction = action; | 1141 | args.v3.sExtEncoder.ucAction = action; |
| 1142 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | 1142 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) |
| 1143 | args.v3.sExtEncoder.usConnectorId = connector_object_id; | 1143 | args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); |
| 1144 | else | 1144 | else |
| 1145 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 1145 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| 1146 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | 1146 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); |
| @@ -1570,11 +1570,21 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
| 1570 | } | 1570 | } |
| 1571 | 1571 | ||
| 1572 | /* set scaler clears this on some chips */ | 1572 | /* set scaler clears this on some chips */ |
| 1573 | /* XXX check DCE4 */ | 1573 | if (ASIC_IS_AVIVO(rdev) && |
| 1574 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { | 1574 | (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { |
| 1575 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1575 | if (ASIC_IS_DCE4(rdev)) { |
| 1576 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | 1576 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
| 1577 | AVIVO_D1MODE_INTERLEAVE_EN); | 1577 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, |
| 1578 | EVERGREEN_INTERLEAVE_EN); | ||
| 1579 | else | ||
| 1580 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1581 | } else { | ||
| 1582 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1583 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1584 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
| 1585 | else | ||
| 1586 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1587 | } | ||
| 1578 | } | 1588 | } |
| 1579 | } | 1589 | } |
| 1580 | 1590 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index ace2e6384d4..cf0638c3b7c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -778,9 +778,9 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 778 | DRM_DEBUG_KMS("\n"); | 778 | DRM_DEBUG_KMS("\n"); |
| 779 | 779 | ||
| 780 | if (!use_bios_divs) { | 780 | if (!use_bios_divs) { |
| 781 | radeon_compute_pll(pll, mode->clock, | 781 | radeon_compute_pll_legacy(pll, mode->clock, |
| 782 | &freq, &feedback_div, &frac_fb_div, | 782 | &freq, &feedback_div, &frac_fb_div, |
| 783 | &reference_div, &post_divider); | 783 | &reference_div, &post_divider); |
| 784 | 784 | ||
| 785 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | 785 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { |
| 786 | if (post_div->divider == post_divider) | 786 | if (post_div->divider == post_divider) |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 12bdeab91c8..a670caaee29 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -149,6 +149,7 @@ struct radeon_tmds_pll { | |||
| 149 | #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) | 149 | #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) |
| 150 | #define RADEON_PLL_USE_POST_DIV (1 << 12) | 150 | #define RADEON_PLL_USE_POST_DIV (1 << 12) |
| 151 | #define RADEON_PLL_IS_LCD (1 << 13) | 151 | #define RADEON_PLL_IS_LCD (1 << 13) |
| 152 | #define RADEON_PLL_PREFER_MINM_OVER_MAXP (1 << 14) | ||
| 152 | 153 | ||
| 153 | struct radeon_pll { | 154 | struct radeon_pll { |
| 154 | /* reference frequency */ | 155 | /* reference frequency */ |
| @@ -208,6 +209,7 @@ enum radeon_connector_table { | |||
| 208 | CT_EMAC, | 209 | CT_EMAC, |
| 209 | CT_RN50_POWER, | 210 | CT_RN50_POWER, |
| 210 | CT_MAC_X800, | 211 | CT_MAC_X800, |
| 212 | CT_MAC_G5_9600, | ||
| 211 | }; | 213 | }; |
| 212 | 214 | ||
| 213 | enum radeon_dvo_chip { | 215 | enum radeon_dvo_chip { |
| @@ -510,13 +512,21 @@ extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
| 510 | struct radeon_atom_ss *ss, | 512 | struct radeon_atom_ss *ss, |
| 511 | int id, u32 clock); | 513 | int id, u32 clock); |
| 512 | 514 | ||
| 513 | extern void radeon_compute_pll(struct radeon_pll *pll, | 515 | extern void radeon_compute_pll_legacy(struct radeon_pll *pll, |
| 514 | uint64_t freq, | 516 | uint64_t freq, |
| 515 | uint32_t *dot_clock_p, | 517 | uint32_t *dot_clock_p, |
| 516 | uint32_t *fb_div_p, | 518 | uint32_t *fb_div_p, |
| 517 | uint32_t *frac_fb_div_p, | 519 | uint32_t *frac_fb_div_p, |
| 518 | uint32_t *ref_div_p, | 520 | uint32_t *ref_div_p, |
| 519 | uint32_t *post_div_p); | 521 | uint32_t *post_div_p); |
| 522 | |||
| 523 | extern void radeon_compute_pll_avivo(struct radeon_pll *pll, | ||
| 524 | u32 freq, | ||
| 525 | u32 *dot_clock_p, | ||
| 526 | u32 *fb_div_p, | ||
| 527 | u32 *frac_fb_div_p, | ||
| 528 | u32 *ref_div_p, | ||
| 529 | u32 *post_div_p); | ||
| 520 | 530 | ||
| 521 | extern void radeon_setup_encoder_clones(struct drm_device *dev); | 531 | extern void radeon_setup_encoder_clones(struct drm_device *dev); |
| 522 | 532 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 3b1b2bf9cdd..2aed03bde4b 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -430,7 +430,7 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, | |||
| 430 | { | 430 | { |
| 431 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); | 431 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); |
| 432 | struct radeon_device *rdev = ddev->dev_private; | 432 | struct radeon_device *rdev = ddev->dev_private; |
| 433 | u32 temp; | 433 | int temp; |
| 434 | 434 | ||
| 435 | switch (rdev->pm.int_thermal_type) { | 435 | switch (rdev->pm.int_thermal_type) { |
| 436 | case THERMAL_TYPE_RV6XX: | 436 | case THERMAL_TYPE_RV6XX: |
| @@ -646,6 +646,9 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
| 646 | #endif | 646 | #endif |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | if (rdev->pm.power_state) | ||
| 650 | kfree(rdev->pm.power_state); | ||
| 651 | |||
| 649 | radeon_hwmon_fini(rdev); | 652 | radeon_hwmon_fini(rdev); |
| 650 | } | 653 | } |
| 651 | 654 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 1272e4b6a1d..e5b2cf10cbf 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -787,9 +787,9 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) | |||
| 787 | radeon_mem_types_list[i].show = &radeon_mm_dump_table; | 787 | radeon_mem_types_list[i].show = &radeon_mm_dump_table; |
| 788 | radeon_mem_types_list[i].driver_features = 0; | 788 | radeon_mem_types_list[i].driver_features = 0; |
| 789 | if (i == 0) | 789 | if (i == 0) |
| 790 | radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].priv; | 790 | radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; |
| 791 | else | 791 | else |
| 792 | radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].priv; | 792 | radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; |
| 793 | 793 | ||
| 794 | } | 794 | } |
| 795 | /* Add ttm page pool to debugfs */ | 795 | /* Add ttm page pool to debugfs */ |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index b506ec1cab4..e8a1786b642 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 | |||
| @@ -683,9 +683,7 @@ r300 0x4f60 | |||
| 683 | 0x4DF4 US_ALU_CONST_G_31 | 683 | 0x4DF4 US_ALU_CONST_G_31 |
| 684 | 0x4DF8 US_ALU_CONST_B_31 | 684 | 0x4DF8 US_ALU_CONST_B_31 |
| 685 | 0x4DFC US_ALU_CONST_A_31 | 685 | 0x4DFC US_ALU_CONST_A_31 |
| 686 | 0x4E04 RB3D_BLENDCNTL_R3 | ||
| 687 | 0x4E08 RB3D_ABLENDCNTL_R3 | 686 | 0x4E08 RB3D_ABLENDCNTL_R3 |
| 688 | 0x4E0C RB3D_COLOR_CHANNEL_MASK | ||
| 689 | 0x4E10 RB3D_CONSTANT_COLOR | 687 | 0x4E10 RB3D_CONSTANT_COLOR |
| 690 | 0x4E14 RB3D_COLOR_CLEAR_VALUE | 688 | 0x4E14 RB3D_COLOR_CLEAR_VALUE |
| 691 | 0x4E18 RB3D_ROPCNTL_R3 | 689 | 0x4E18 RB3D_ROPCNTL_R3 |
| @@ -706,13 +704,11 @@ r300 0x4f60 | |||
| 706 | 0x4E74 RB3D_CMASK_WRINDEX | 704 | 0x4E74 RB3D_CMASK_WRINDEX |
| 707 | 0x4E78 RB3D_CMASK_DWORD | 705 | 0x4E78 RB3D_CMASK_DWORD |
| 708 | 0x4E7C RB3D_CMASK_RDINDEX | 706 | 0x4E7C RB3D_CMASK_RDINDEX |
| 709 | 0x4E80 RB3D_AARESOLVE_OFFSET | ||
| 710 | 0x4E84 RB3D_AARESOLVE_PITCH | ||
| 711 | 0x4E88 RB3D_AARESOLVE_CTL | ||
| 712 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD | 707 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD |
| 713 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD | 708 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD |
| 714 | 0x4F04 ZB_ZSTENCILCNTL | 709 | 0x4F04 ZB_ZSTENCILCNTL |
| 715 | 0x4F08 ZB_STENCILREFMASK | 710 | 0x4F08 ZB_STENCILREFMASK |
| 716 | 0x4F14 ZB_ZTOP | 711 | 0x4F14 ZB_ZTOP |
| 717 | 0x4F18 ZB_ZCACHE_CTLSTAT | 712 | 0x4F18 ZB_ZCACHE_CTLSTAT |
| 713 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
| 718 | 0x4F58 ZB_ZPASS_DATA | 714 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 8c1214c2390..722074e21e2 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 | |||
| @@ -130,7 +130,6 @@ r420 0x4f60 | |||
| 130 | 0x401C GB_SELECT | 130 | 0x401C GB_SELECT |
| 131 | 0x4020 GB_AA_CONFIG | 131 | 0x4020 GB_AA_CONFIG |
| 132 | 0x4024 GB_FIFO_SIZE | 132 | 0x4024 GB_FIFO_SIZE |
| 133 | 0x4028 GB_Z_PEQ_CONFIG | ||
| 134 | 0x4100 TX_INVALTAGS | 133 | 0x4100 TX_INVALTAGS |
| 135 | 0x4200 GA_POINT_S0 | 134 | 0x4200 GA_POINT_S0 |
| 136 | 0x4204 GA_POINT_T0 | 135 | 0x4204 GA_POINT_T0 |
| @@ -750,9 +749,7 @@ r420 0x4f60 | |||
| 750 | 0x4DF4 US_ALU_CONST_G_31 | 749 | 0x4DF4 US_ALU_CONST_G_31 |
| 751 | 0x4DF8 US_ALU_CONST_B_31 | 750 | 0x4DF8 US_ALU_CONST_B_31 |
| 752 | 0x4DFC US_ALU_CONST_A_31 | 751 | 0x4DFC US_ALU_CONST_A_31 |
| 753 | 0x4E04 RB3D_BLENDCNTL_R3 | ||
| 754 | 0x4E08 RB3D_ABLENDCNTL_R3 | 752 | 0x4E08 RB3D_ABLENDCNTL_R3 |
| 755 | 0x4E0C RB3D_COLOR_CHANNEL_MASK | ||
| 756 | 0x4E10 RB3D_CONSTANT_COLOR | 753 | 0x4E10 RB3D_CONSTANT_COLOR |
| 757 | 0x4E14 RB3D_COLOR_CLEAR_VALUE | 754 | 0x4E14 RB3D_COLOR_CLEAR_VALUE |
| 758 | 0x4E18 RB3D_ROPCNTL_R3 | 755 | 0x4E18 RB3D_ROPCNTL_R3 |
| @@ -773,13 +770,11 @@ r420 0x4f60 | |||
| 773 | 0x4E74 RB3D_CMASK_WRINDEX | 770 | 0x4E74 RB3D_CMASK_WRINDEX |
| 774 | 0x4E78 RB3D_CMASK_DWORD | 771 | 0x4E78 RB3D_CMASK_DWORD |
| 775 | 0x4E7C RB3D_CMASK_RDINDEX | 772 | 0x4E7C RB3D_CMASK_RDINDEX |
| 776 | 0x4E80 RB3D_AARESOLVE_OFFSET | ||
| 777 | 0x4E84 RB3D_AARESOLVE_PITCH | ||
| 778 | 0x4E88 RB3D_AARESOLVE_CTL | ||
| 779 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD | 773 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD |
| 780 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD | 774 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD |
| 781 | 0x4F04 ZB_ZSTENCILCNTL | 775 | 0x4F04 ZB_ZSTENCILCNTL |
| 782 | 0x4F08 ZB_STENCILREFMASK | 776 | 0x4F08 ZB_STENCILREFMASK |
| 783 | 0x4F14 ZB_ZTOP | 777 | 0x4F14 ZB_ZTOP |
| 784 | 0x4F18 ZB_ZCACHE_CTLSTAT | 778 | 0x4F18 ZB_ZCACHE_CTLSTAT |
| 779 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
| 785 | 0x4F58 ZB_ZPASS_DATA | 780 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 0828d80396f..d9f62866bbc 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 | |||
| @@ -749,9 +749,7 @@ rs600 0x6d40 | |||
| 749 | 0x4DF4 US_ALU_CONST_G_31 | 749 | 0x4DF4 US_ALU_CONST_G_31 |
| 750 | 0x4DF8 US_ALU_CONST_B_31 | 750 | 0x4DF8 US_ALU_CONST_B_31 |
| 751 | 0x4DFC US_ALU_CONST_A_31 | 751 | 0x4DFC US_ALU_CONST_A_31 |
| 752 | 0x4E04 RB3D_BLENDCNTL_R3 | ||
| 753 | 0x4E08 RB3D_ABLENDCNTL_R3 | 752 | 0x4E08 RB3D_ABLENDCNTL_R3 |
| 754 | 0x4E0C RB3D_COLOR_CHANNEL_MASK | ||
| 755 | 0x4E10 RB3D_CONSTANT_COLOR | 753 | 0x4E10 RB3D_CONSTANT_COLOR |
| 756 | 0x4E14 RB3D_COLOR_CLEAR_VALUE | 754 | 0x4E14 RB3D_COLOR_CLEAR_VALUE |
| 757 | 0x4E18 RB3D_ROPCNTL_R3 | 755 | 0x4E18 RB3D_ROPCNTL_R3 |
| @@ -772,13 +770,11 @@ rs600 0x6d40 | |||
| 772 | 0x4E74 RB3D_CMASK_WRINDEX | 770 | 0x4E74 RB3D_CMASK_WRINDEX |
| 773 | 0x4E78 RB3D_CMASK_DWORD | 771 | 0x4E78 RB3D_CMASK_DWORD |
| 774 | 0x4E7C RB3D_CMASK_RDINDEX | 772 | 0x4E7C RB3D_CMASK_RDINDEX |
| 775 | 0x4E80 RB3D_AARESOLVE_OFFSET | ||
| 776 | 0x4E84 RB3D_AARESOLVE_PITCH | ||
| 777 | 0x4E88 RB3D_AARESOLVE_CTL | ||
| 778 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD | 773 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD |
| 779 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD | 774 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD |
| 780 | 0x4F04 ZB_ZSTENCILCNTL | 775 | 0x4F04 ZB_ZSTENCILCNTL |
| 781 | 0x4F08 ZB_STENCILREFMASK | 776 | 0x4F08 ZB_STENCILREFMASK |
| 782 | 0x4F14 ZB_ZTOP | 777 | 0x4F14 ZB_ZTOP |
| 783 | 0x4F18 ZB_ZCACHE_CTLSTAT | 778 | 0x4F18 ZB_ZCACHE_CTLSTAT |
| 779 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
| 784 | 0x4F58 ZB_ZPASS_DATA | 780 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index ef422bbacfc..911a8fbd32b 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
| @@ -164,7 +164,6 @@ rv515 0x6d40 | |||
| 164 | 0x401C GB_SELECT | 164 | 0x401C GB_SELECT |
| 165 | 0x4020 GB_AA_CONFIG | 165 | 0x4020 GB_AA_CONFIG |
| 166 | 0x4024 GB_FIFO_SIZE | 166 | 0x4024 GB_FIFO_SIZE |
| 167 | 0x4028 GB_Z_PEQ_CONFIG | ||
| 168 | 0x4100 TX_INVALTAGS | 167 | 0x4100 TX_INVALTAGS |
| 169 | 0x4114 SU_TEX_WRAP_PS3 | 168 | 0x4114 SU_TEX_WRAP_PS3 |
| 170 | 0x4118 PS3_ENABLE | 169 | 0x4118 PS3_ENABLE |
| @@ -461,9 +460,7 @@ rv515 0x6d40 | |||
| 461 | 0x4DF4 US_ALU_CONST_G_31 | 460 | 0x4DF4 US_ALU_CONST_G_31 |
| 462 | 0x4DF8 US_ALU_CONST_B_31 | 461 | 0x4DF8 US_ALU_CONST_B_31 |
| 463 | 0x4DFC US_ALU_CONST_A_31 | 462 | 0x4DFC US_ALU_CONST_A_31 |
| 464 | 0x4E04 RB3D_BLENDCNTL_R3 | ||
| 465 | 0x4E08 RB3D_ABLENDCNTL_R3 | 463 | 0x4E08 RB3D_ABLENDCNTL_R3 |
| 466 | 0x4E0C RB3D_COLOR_CHANNEL_MASK | ||
| 467 | 0x4E10 RB3D_CONSTANT_COLOR | 464 | 0x4E10 RB3D_CONSTANT_COLOR |
| 468 | 0x4E14 RB3D_COLOR_CLEAR_VALUE | 465 | 0x4E14 RB3D_COLOR_CLEAR_VALUE |
| 469 | 0x4E18 RB3D_ROPCNTL_R3 | 466 | 0x4E18 RB3D_ROPCNTL_R3 |
| @@ -484,9 +481,6 @@ rv515 0x6d40 | |||
| 484 | 0x4E74 RB3D_CMASK_WRINDEX | 481 | 0x4E74 RB3D_CMASK_WRINDEX |
| 485 | 0x4E78 RB3D_CMASK_DWORD | 482 | 0x4E78 RB3D_CMASK_DWORD |
| 486 | 0x4E7C RB3D_CMASK_RDINDEX | 483 | 0x4E7C RB3D_CMASK_RDINDEX |
| 487 | 0x4E80 RB3D_AARESOLVE_OFFSET | ||
| 488 | 0x4E84 RB3D_AARESOLVE_PITCH | ||
| 489 | 0x4E88 RB3D_AARESOLVE_CTL | ||
| 490 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD | 484 | 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD |
| 491 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD | 485 | 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD |
| 492 | 0x4EF8 RB3D_CONSTANT_COLOR_AR | 486 | 0x4EF8 RB3D_CONSTANT_COLOR_AR |
| @@ -496,4 +490,5 @@ rv515 0x6d40 | |||
| 496 | 0x4F14 ZB_ZTOP | 490 | 0x4F14 ZB_ZTOP |
| 497 | 0x4F18 ZB_ZCACHE_CTLSTAT | 491 | 0x4F18 ZB_ZCACHE_CTLSTAT |
| 498 | 0x4F58 ZB_ZPASS_DATA | 492 | 0x4F58 ZB_ZPASS_DATA |
| 493 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
| 499 | 0x4FD4 ZB_STENCILREFMASK_BF | 494 | 0x4FD4 ZB_STENCILREFMASK_BF |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0137d3e3728..6638c8e4c81 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
| @@ -77,9 +77,9 @@ void rs690_pm_info(struct radeon_device *rdev) | |||
| 77 | switch (crev) { | 77 | switch (crev) { |
| 78 | case 1: | 78 | case 1: |
| 79 | tmp.full = dfixed_const(100); | 79 | tmp.full = dfixed_const(100); |
| 80 | rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock); | 80 | rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info.ulBootUpMemoryClock)); |
| 81 | rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); | 81 | rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); |
| 82 | if (info->info.usK8MemoryClock) | 82 | if (le16_to_cpu(info->info.usK8MemoryClock)) |
| 83 | rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); | 83 | rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); |
| 84 | else if (rdev->clock.default_mclk) { | 84 | else if (rdev->clock.default_mclk) { |
| 85 | rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); | 85 | rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); |
| @@ -91,16 +91,16 @@ void rs690_pm_info(struct radeon_device *rdev) | |||
| 91 | break; | 91 | break; |
| 92 | case 2: | 92 | case 2: |
| 93 | tmp.full = dfixed_const(100); | 93 | tmp.full = dfixed_const(100); |
| 94 | rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock); | 94 | rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpSidePortClock)); |
| 95 | rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); | 95 | rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); |
| 96 | if (info->info_v2.ulBootUpUMAClock) | 96 | if (le32_to_cpu(info->info_v2.ulBootUpUMAClock)) |
| 97 | rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); | 97 | rdev->pm.igp_system_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpUMAClock)); |
| 98 | else if (rdev->clock.default_mclk) | 98 | else if (rdev->clock.default_mclk) |
| 99 | rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); | 99 | rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); |
| 100 | else | 100 | else |
| 101 | rdev->pm.igp_system_mclk.full = dfixed_const(66700); | 101 | rdev->pm.igp_system_mclk.full = dfixed_const(66700); |
| 102 | rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); | 102 | rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); |
| 103 | rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq); | 103 | rdev->pm.igp_ht_link_clk.full = dfixed_const(le32_to_cpu(info->info_v2.ulHTLinkFreq)); |
| 104 | rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); | 104 | rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); |
| 105 | rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); | 105 | rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); |
| 106 | break; | 106 | break; |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 491dc900065..d8ba6769065 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -78,18 +78,23 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | /* get temperature in millidegrees */ | 80 | /* get temperature in millidegrees */ |
| 81 | u32 rv770_get_temp(struct radeon_device *rdev) | 81 | int rv770_get_temp(struct radeon_device *rdev) |
| 82 | { | 82 | { |
| 83 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | 83 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> |
| 84 | ASIC_T_SHIFT; | 84 | ASIC_T_SHIFT; |
| 85 | u32 actual_temp = 0; | 85 | int actual_temp; |
| 86 | 86 | ||
| 87 | if ((temp >> 9) & 1) | 87 | if (temp & 0x400) |
| 88 | actual_temp = 0; | 88 | actual_temp = -256; |
| 89 | else | 89 | else if (temp & 0x200) |
| 90 | actual_temp = (temp >> 1) & 0xff; | 90 | actual_temp = 255; |
| 91 | 91 | else if (temp & 0x100) { | |
| 92 | return actual_temp * 1000; | 92 | actual_temp = temp & 0x1ff; |
| 93 | actual_temp |= ~0x1ff; | ||
| 94 | } else | ||
| 95 | actual_temp = temp & 0xff; | ||
| 96 | |||
| 97 | return (actual_temp * 1000) / 2; | ||
| 93 | } | 98 | } |
| 94 | 99 | ||
| 95 | void rv770_pm_misc(struct radeon_device *rdev) | 100 | void rv770_pm_misc(struct radeon_device *rdev) |
| @@ -316,7 +321,11 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) | |||
| 316 | return -EINVAL; | 321 | return -EINVAL; |
| 317 | 322 | ||
| 318 | r700_cp_stop(rdev); | 323 | r700_cp_stop(rdev); |
| 319 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); | 324 | WREG32(CP_RB_CNTL, |
| 325 | #ifdef __BIG_ENDIAN | ||
| 326 | BUF_SWAP_32BIT | | ||
| 327 | #endif | ||
| 328 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
| 320 | 329 | ||
| 321 | /* Reset cp */ | 330 | /* Reset cp */ |
| 322 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | 331 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index abc8cf5a367..79fa588e9ed 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
| @@ -76,10 +76,10 @@ | |||
| 76 | #define ROQ_IB1_START(x) ((x) << 0) | 76 | #define ROQ_IB1_START(x) ((x) << 0) |
| 77 | #define ROQ_IB2_START(x) ((x) << 8) | 77 | #define ROQ_IB2_START(x) ((x) << 8) |
| 78 | #define CP_RB_CNTL 0xC104 | 78 | #define CP_RB_CNTL 0xC104 |
| 79 | #define RB_BUFSZ(x) ((x)<<0) | 79 | #define RB_BUFSZ(x) ((x) << 0) |
| 80 | #define RB_BLKSZ(x) ((x)<<8) | 80 | #define RB_BLKSZ(x) ((x) << 8) |
| 81 | #define RB_NO_UPDATE (1<<27) | 81 | #define RB_NO_UPDATE (1 << 27) |
| 82 | #define RB_RPTR_WR_ENA (1<<31) | 82 | #define RB_RPTR_WR_ENA (1 << 31) |
| 83 | #define BUF_SWAP_32BIT (2 << 16) | 83 | #define BUF_SWAP_32BIT (2 << 16) |
| 84 | #define CP_RB_RPTR 0x8700 | 84 | #define CP_RB_RPTR 0x8700 |
| 85 | #define CP_RB_RPTR_ADDR 0xC10C | 85 | #define CP_RB_RPTR_ADDR 0xC10C |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 5dea9faa165..cd2a6e437ae 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
| @@ -344,7 +344,7 @@ static int emc1403_remove(struct i2c_client *client) | |||
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | static const unsigned short emc1403_address_list[] = { | 346 | static const unsigned short emc1403_address_list[] = { |
| 347 | 0x18, 0x2a, 0x4c, 0x4d, I2C_CLIENT_END | 347 | 0x18, 0x29, 0x4c, 0x4d, I2C_CLIENT_END |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static const struct i2c_device_id emc1403_idtable[] = { | 350 | static const struct i2c_device_id emc1403_idtable[] = { |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 776aeb3019d..508cb291f71 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
| @@ -98,6 +98,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
| 98 | * value, it uses signed 8-bit values with LSB = 1 degree Celsius. | 98 | * value, it uses signed 8-bit values with LSB = 1 degree Celsius. |
| 99 | * For remote temperature, low and high limits, it uses signed 11-bit values | 99 | * For remote temperature, low and high limits, it uses signed 11-bit values |
| 100 | * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers. | 100 | * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers. |
| 101 | * For LM64 the actual remote diode temperature is 16 degree Celsius higher | ||
| 102 | * than the register reading. Remote temperature setpoints have to be | ||
| 103 | * adapted accordingly. | ||
| 101 | */ | 104 | */ |
| 102 | 105 | ||
| 103 | #define FAN_FROM_REG(reg) ((reg) == 0xFFFC || (reg) == 0 ? 0 : \ | 106 | #define FAN_FROM_REG(reg) ((reg) == 0xFFFC || (reg) == 0 ? 0 : \ |
| @@ -165,6 +168,8 @@ struct lm63_data { | |||
| 165 | struct mutex update_lock; | 168 | struct mutex update_lock; |
| 166 | char valid; /* zero until following fields are valid */ | 169 | char valid; /* zero until following fields are valid */ |
| 167 | unsigned long last_updated; /* in jiffies */ | 170 | unsigned long last_updated; /* in jiffies */ |
| 171 | int kind; | ||
| 172 | int temp2_offset; | ||
| 168 | 173 | ||
| 169 | /* registers values */ | 174 | /* registers values */ |
| 170 | u8 config, config_fan; | 175 | u8 config, config_fan; |
| @@ -247,16 +252,34 @@ static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dum | |||
| 247 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); | 252 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); |
| 248 | } | 253 | } |
| 249 | 254 | ||
| 250 | static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, | 255 | /* |
| 251 | char *buf) | 256 | * There are 8bit registers for both local(temp1) and remote(temp2) sensor. |
| 257 | * For remote sensor registers temp2_offset has to be considered, | ||
| 258 | * for local sensor it must not. | ||
| 259 | * So we need separate 8bit accessors for local and remote sensor. | ||
| 260 | */ | ||
| 261 | static ssize_t show_local_temp8(struct device *dev, | ||
| 262 | struct device_attribute *devattr, | ||
| 263 | char *buf) | ||
| 252 | { | 264 | { |
| 253 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 265 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 254 | struct lm63_data *data = lm63_update_device(dev); | 266 | struct lm63_data *data = lm63_update_device(dev); |
| 255 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])); | 267 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])); |
| 256 | } | 268 | } |
| 257 | 269 | ||
| 258 | static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy, | 270 | static ssize_t show_remote_temp8(struct device *dev, |
| 259 | const char *buf, size_t count) | 271 | struct device_attribute *devattr, |
| 272 | char *buf) | ||
| 273 | { | ||
| 274 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 275 | struct lm63_data *data = lm63_update_device(dev); | ||
| 276 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]) | ||
| 277 | + data->temp2_offset); | ||
| 278 | } | ||
| 279 | |||
| 280 | static ssize_t set_local_temp8(struct device *dev, | ||
| 281 | struct device_attribute *dummy, | ||
| 282 | const char *buf, size_t count) | ||
| 260 | { | 283 | { |
| 261 | struct i2c_client *client = to_i2c_client(dev); | 284 | struct i2c_client *client = to_i2c_client(dev); |
| 262 | struct lm63_data *data = i2c_get_clientdata(client); | 285 | struct lm63_data *data = i2c_get_clientdata(client); |
| @@ -274,7 +297,8 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
| 274 | { | 297 | { |
| 275 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 298 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 276 | struct lm63_data *data = lm63_update_device(dev); | 299 | struct lm63_data *data = lm63_update_device(dev); |
| 277 | return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index])); | 300 | return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]) |
| 301 | + data->temp2_offset); | ||
| 278 | } | 302 | } |
| 279 | 303 | ||
| 280 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 304 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
| @@ -294,7 +318,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
| 294 | int nr = attr->index; | 318 | int nr = attr->index; |
| 295 | 319 | ||
| 296 | mutex_lock(&data->update_lock); | 320 | mutex_lock(&data->update_lock); |
| 297 | data->temp11[nr] = TEMP11_TO_REG(val); | 321 | data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); |
| 298 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], | 322 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], |
| 299 | data->temp11[nr] >> 8); | 323 | data->temp11[nr] >> 8); |
| 300 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], | 324 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], |
| @@ -310,6 +334,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute | |||
| 310 | { | 334 | { |
| 311 | struct lm63_data *data = lm63_update_device(dev); | 335 | struct lm63_data *data = lm63_update_device(dev); |
| 312 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2]) | 336 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2]) |
| 337 | + data->temp2_offset | ||
| 313 | - TEMP8_FROM_REG(data->temp2_crit_hyst)); | 338 | - TEMP8_FROM_REG(data->temp2_crit_hyst)); |
| 314 | } | 339 | } |
| 315 | 340 | ||
| @@ -324,7 +349,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute * | |||
| 324 | long hyst; | 349 | long hyst; |
| 325 | 350 | ||
| 326 | mutex_lock(&data->update_lock); | 351 | mutex_lock(&data->update_lock); |
| 327 | hyst = TEMP8_FROM_REG(data->temp8[2]) - val; | 352 | hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val; |
| 328 | i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, | 353 | i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, |
| 329 | HYST_TO_REG(hyst)); | 354 | HYST_TO_REG(hyst)); |
| 330 | mutex_unlock(&data->update_lock); | 355 | mutex_unlock(&data->update_lock); |
| @@ -355,16 +380,21 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, | |||
| 355 | static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); | 380 | static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); |
| 356 | static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); | 381 | static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); |
| 357 | 382 | ||
| 358 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); | 383 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); |
| 359 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, | 384 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, |
| 360 | set_temp8, 1); | 385 | set_local_temp8, 1); |
| 361 | 386 | ||
| 362 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); | 387 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); |
| 363 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, | 388 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, |
| 364 | set_temp11, 1); | 389 | set_temp11, 1); |
| 365 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, | 390 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, |
| 366 | set_temp11, 2); | 391 | set_temp11, 2); |
| 367 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2); | 392 | /* |
| 393 | * On LM63, temp2_crit can be set only once, which should be job | ||
| 394 | * of the bootloader. | ||
| 395 | */ | ||
| 396 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8, | ||
| 397 | NULL, 2); | ||
| 368 | static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, | 398 | static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, |
| 369 | set_temp2_crit_hyst); | 399 | set_temp2_crit_hyst); |
| 370 | 400 | ||
| @@ -479,7 +509,12 @@ static int lm63_probe(struct i2c_client *new_client, | |||
| 479 | data->valid = 0; | 509 | data->valid = 0; |
| 480 | mutex_init(&data->update_lock); | 510 | mutex_init(&data->update_lock); |
| 481 | 511 | ||
| 482 | /* Initialize the LM63 chip */ | 512 | /* Set the device type */ |
| 513 | data->kind = id->driver_data; | ||
| 514 | if (data->kind == lm64) | ||
| 515 | data->temp2_offset = 16000; | ||
| 516 | |||
| 517 | /* Initialize chip */ | ||
| 483 | lm63_init_client(new_client); | 518 | lm63_init_client(new_client); |
| 484 | 519 | ||
| 485 | /* Register sysfs hooks */ | 520 | /* Register sysfs hooks */ |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 8b606fd6402..08c194861af 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
| @@ -2610,9 +2610,11 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2610 | netif_carrier_on(nesvnic->netdev); | 2610 | netif_carrier_on(nesvnic->netdev); |
| 2611 | 2611 | ||
| 2612 | spin_lock(&nesvnic->port_ibevent_lock); | 2612 | spin_lock(&nesvnic->port_ibevent_lock); |
| 2613 | if (nesdev->iw_status == 0) { | 2613 | if (nesvnic->of_device_registered) { |
| 2614 | nesdev->iw_status = 1; | 2614 | if (nesdev->iw_status == 0) { |
| 2615 | nes_port_ibevent(nesvnic); | 2615 | nesdev->iw_status = 1; |
| 2616 | nes_port_ibevent(nesvnic); | ||
| 2617 | } | ||
| 2616 | } | 2618 | } |
| 2617 | spin_unlock(&nesvnic->port_ibevent_lock); | 2619 | spin_unlock(&nesvnic->port_ibevent_lock); |
| 2618 | } | 2620 | } |
| @@ -2642,9 +2644,11 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2642 | netif_carrier_off(nesvnic->netdev); | 2644 | netif_carrier_off(nesvnic->netdev); |
| 2643 | 2645 | ||
| 2644 | spin_lock(&nesvnic->port_ibevent_lock); | 2646 | spin_lock(&nesvnic->port_ibevent_lock); |
| 2645 | if (nesdev->iw_status == 1) { | 2647 | if (nesvnic->of_device_registered) { |
| 2646 | nesdev->iw_status = 0; | 2648 | if (nesdev->iw_status == 1) { |
| 2647 | nes_port_ibevent(nesvnic); | 2649 | nesdev->iw_status = 0; |
| 2650 | nes_port_ibevent(nesvnic); | ||
| 2651 | } | ||
| 2648 | } | 2652 | } |
| 2649 | spin_unlock(&nesvnic->port_ibevent_lock); | 2653 | spin_unlock(&nesvnic->port_ibevent_lock); |
| 2650 | } | 2654 | } |
| @@ -2703,9 +2707,11 @@ void nes_recheck_link_status(struct work_struct *work) | |||
| 2703 | netif_carrier_on(nesvnic->netdev); | 2707 | netif_carrier_on(nesvnic->netdev); |
| 2704 | 2708 | ||
| 2705 | spin_lock(&nesvnic->port_ibevent_lock); | 2709 | spin_lock(&nesvnic->port_ibevent_lock); |
| 2706 | if (nesdev->iw_status == 0) { | 2710 | if (nesvnic->of_device_registered) { |
| 2707 | nesdev->iw_status = 1; | 2711 | if (nesdev->iw_status == 0) { |
| 2708 | nes_port_ibevent(nesvnic); | 2712 | nesdev->iw_status = 1; |
| 2713 | nes_port_ibevent(nesvnic); | ||
| 2714 | } | ||
| 2709 | } | 2715 | } |
| 2710 | spin_unlock(&nesvnic->port_ibevent_lock); | 2716 | spin_unlock(&nesvnic->port_ibevent_lock); |
| 2711 | } | 2717 | } |
| @@ -2723,9 +2729,11 @@ void nes_recheck_link_status(struct work_struct *work) | |||
| 2723 | netif_carrier_off(nesvnic->netdev); | 2729 | netif_carrier_off(nesvnic->netdev); |
| 2724 | 2730 | ||
| 2725 | spin_lock(&nesvnic->port_ibevent_lock); | 2731 | spin_lock(&nesvnic->port_ibevent_lock); |
| 2726 | if (nesdev->iw_status == 1) { | 2732 | if (nesvnic->of_device_registered) { |
| 2727 | nesdev->iw_status = 0; | 2733 | if (nesdev->iw_status == 1) { |
| 2728 | nes_port_ibevent(nesvnic); | 2734 | nesdev->iw_status = 0; |
| 2735 | nes_port_ibevent(nesvnic); | ||
| 2736 | } | ||
| 2729 | } | 2737 | } |
| 2730 | spin_unlock(&nesvnic->port_ibevent_lock); | 2738 | spin_unlock(&nesvnic->port_ibevent_lock); |
| 2731 | } | 2739 | } |
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c index 8245237b67c..eca0c41f122 100644 --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c | |||
| @@ -1005,7 +1005,8 @@ void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr) | |||
| 1005 | * there are still requests that haven't been acked. | 1005 | * there are still requests that haven't been acked. |
| 1006 | */ | 1006 | */ |
| 1007 | if ((psn & IB_BTH_REQ_ACK) && qp->s_acked != qp->s_tail && | 1007 | if ((psn & IB_BTH_REQ_ACK) && qp->s_acked != qp->s_tail && |
| 1008 | !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN))) | 1008 | !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN)) && |
| 1009 | (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) | ||
| 1009 | start_timer(qp); | 1010 | start_timer(qp); |
| 1010 | 1011 | ||
| 1011 | while (qp->s_last != qp->s_acked) { | 1012 | while (qp->s_last != qp->s_acked) { |
| @@ -1439,6 +1440,8 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp, | |||
| 1439 | } | 1440 | } |
| 1440 | 1441 | ||
| 1441 | spin_lock_irqsave(&qp->s_lock, flags); | 1442 | spin_lock_irqsave(&qp->s_lock, flags); |
| 1443 | if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) | ||
| 1444 | goto ack_done; | ||
| 1442 | 1445 | ||
| 1443 | /* Ignore invalid responses. */ | 1446 | /* Ignore invalid responses. */ |
| 1444 | if (qib_cmp24(psn, qp->s_next_psn) >= 0) | 1447 | if (qib_cmp24(psn, qp->s_next_psn) >= 0) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 7985114beac..11905b6a302 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -75,7 +75,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
| 75 | * dev->event_lock held and interrupts disabled. | 75 | * dev->event_lock held and interrupts disabled. |
| 76 | */ | 76 | */ |
| 77 | static void input_pass_event(struct input_dev *dev, | 77 | static void input_pass_event(struct input_dev *dev, |
| 78 | struct input_handler *src_handler, | ||
| 79 | unsigned int type, unsigned int code, int value) | 78 | unsigned int type, unsigned int code, int value) |
| 80 | { | 79 | { |
| 81 | struct input_handler *handler; | 80 | struct input_handler *handler; |
| @@ -94,15 +93,6 @@ static void input_pass_event(struct input_dev *dev, | |||
| 94 | continue; | 93 | continue; |
| 95 | 94 | ||
| 96 | handler = handle->handler; | 95 | handler = handle->handler; |
| 97 | |||
| 98 | /* | ||
| 99 | * If this is the handler that injected this | ||
| 100 | * particular event we want to skip it to avoid | ||
| 101 | * filters firing again and again. | ||
| 102 | */ | ||
| 103 | if (handler == src_handler) | ||
| 104 | continue; | ||
| 105 | |||
| 106 | if (!handler->filter) { | 96 | if (!handler->filter) { |
| 107 | if (filtered) | 97 | if (filtered) |
| 108 | break; | 98 | break; |
| @@ -132,7 +122,7 @@ static void input_repeat_key(unsigned long data) | |||
| 132 | if (test_bit(dev->repeat_key, dev->key) && | 122 | if (test_bit(dev->repeat_key, dev->key) && |
| 133 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { | 123 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { |
| 134 | 124 | ||
| 135 | input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); | 125 | input_pass_event(dev, EV_KEY, dev->repeat_key, 2); |
| 136 | 126 | ||
| 137 | if (dev->sync) { | 127 | if (dev->sync) { |
| 138 | /* | 128 | /* |
| @@ -141,7 +131,7 @@ static void input_repeat_key(unsigned long data) | |||
| 141 | * Otherwise assume that the driver will send | 131 | * Otherwise assume that the driver will send |
| 142 | * SYN_REPORT once it's done. | 132 | * SYN_REPORT once it's done. |
| 143 | */ | 133 | */ |
| 144 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | 134 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); |
| 145 | } | 135 | } |
| 146 | 136 | ||
| 147 | if (dev->rep[REP_PERIOD]) | 137 | if (dev->rep[REP_PERIOD]) |
| @@ -174,7 +164,6 @@ static void input_stop_autorepeat(struct input_dev *dev) | |||
| 174 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) | 164 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
| 175 | 165 | ||
| 176 | static int input_handle_abs_event(struct input_dev *dev, | 166 | static int input_handle_abs_event(struct input_dev *dev, |
| 177 | struct input_handler *src_handler, | ||
| 178 | unsigned int code, int *pval) | 167 | unsigned int code, int *pval) |
| 179 | { | 168 | { |
| 180 | bool is_mt_event; | 169 | bool is_mt_event; |
| @@ -218,15 +207,13 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 218 | /* Flush pending "slot" event */ | 207 | /* Flush pending "slot" event */ |
| 219 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | 208 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
| 220 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); | 209 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); |
| 221 | input_pass_event(dev, src_handler, | 210 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); |
| 222 | EV_ABS, ABS_MT_SLOT, dev->slot); | ||
| 223 | } | 211 | } |
| 224 | 212 | ||
| 225 | return INPUT_PASS_TO_HANDLERS; | 213 | return INPUT_PASS_TO_HANDLERS; |
| 226 | } | 214 | } |
| 227 | 215 | ||
| 228 | static void input_handle_event(struct input_dev *dev, | 216 | static void input_handle_event(struct input_dev *dev, |
| 229 | struct input_handler *src_handler, | ||
| 230 | unsigned int type, unsigned int code, int value) | 217 | unsigned int type, unsigned int code, int value) |
| 231 | { | 218 | { |
| 232 | int disposition = INPUT_IGNORE_EVENT; | 219 | int disposition = INPUT_IGNORE_EVENT; |
| @@ -279,8 +266,7 @@ static void input_handle_event(struct input_dev *dev, | |||
| 279 | 266 | ||
| 280 | case EV_ABS: | 267 | case EV_ABS: |
| 281 | if (is_event_supported(code, dev->absbit, ABS_MAX)) | 268 | if (is_event_supported(code, dev->absbit, ABS_MAX)) |
| 282 | disposition = input_handle_abs_event(dev, src_handler, | 269 | disposition = input_handle_abs_event(dev, code, &value); |
| 283 | code, &value); | ||
| 284 | 270 | ||
| 285 | break; | 271 | break; |
| 286 | 272 | ||
| @@ -338,7 +324,7 @@ static void input_handle_event(struct input_dev *dev, | |||
| 338 | dev->event(dev, type, code, value); | 324 | dev->event(dev, type, code, value); |
| 339 | 325 | ||
| 340 | if (disposition & INPUT_PASS_TO_HANDLERS) | 326 | if (disposition & INPUT_PASS_TO_HANDLERS) |
| 341 | input_pass_event(dev, src_handler, type, code, value); | 327 | input_pass_event(dev, type, code, value); |
| 342 | } | 328 | } |
| 343 | 329 | ||
| 344 | /** | 330 | /** |
| @@ -367,7 +353,7 @@ void input_event(struct input_dev *dev, | |||
| 367 | 353 | ||
| 368 | spin_lock_irqsave(&dev->event_lock, flags); | 354 | spin_lock_irqsave(&dev->event_lock, flags); |
| 369 | add_input_randomness(type, code, value); | 355 | add_input_randomness(type, code, value); |
| 370 | input_handle_event(dev, NULL, type, code, value); | 356 | input_handle_event(dev, type, code, value); |
| 371 | spin_unlock_irqrestore(&dev->event_lock, flags); | 357 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 372 | } | 358 | } |
| 373 | } | 359 | } |
| @@ -397,8 +383,7 @@ void input_inject_event(struct input_handle *handle, | |||
| 397 | rcu_read_lock(); | 383 | rcu_read_lock(); |
| 398 | grab = rcu_dereference(dev->grab); | 384 | grab = rcu_dereference(dev->grab); |
| 399 | if (!grab || grab == handle) | 385 | if (!grab || grab == handle) |
| 400 | input_handle_event(dev, handle->handler, | 386 | input_handle_event(dev, type, code, value); |
| 401 | type, code, value); | ||
| 402 | rcu_read_unlock(); | 387 | rcu_read_unlock(); |
| 403 | 388 | ||
| 404 | spin_unlock_irqrestore(&dev->event_lock, flags); | 389 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| @@ -611,10 +596,10 @@ static void input_dev_release_keys(struct input_dev *dev) | |||
| 611 | for (code = 0; code <= KEY_MAX; code++) { | 596 | for (code = 0; code <= KEY_MAX; code++) { |
| 612 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | 597 | if (is_event_supported(code, dev->keybit, KEY_MAX) && |
| 613 | __test_and_clear_bit(code, dev->key)) { | 598 | __test_and_clear_bit(code, dev->key)) { |
| 614 | input_pass_event(dev, NULL, EV_KEY, code, 0); | 599 | input_pass_event(dev, EV_KEY, code, 0); |
| 615 | } | 600 | } |
| 616 | } | 601 | } |
| 617 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | 602 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); |
| 618 | } | 603 | } |
| 619 | } | 604 | } |
| 620 | 605 | ||
| @@ -889,9 +874,9 @@ int input_set_keycode(struct input_dev *dev, | |||
| 889 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | 874 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && |
| 890 | __test_and_clear_bit(old_keycode, dev->key)) { | 875 | __test_and_clear_bit(old_keycode, dev->key)) { |
| 891 | 876 | ||
| 892 | input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); | 877 | input_pass_event(dev, EV_KEY, old_keycode, 0); |
| 893 | if (dev->sync) | 878 | if (dev->sync) |
| 894 | input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | 879 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); |
| 895 | } | 880 | } |
| 896 | 881 | ||
| 897 | out: | 882 | out: |
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 9dfd6e5f786..1f38302a595 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c | |||
| @@ -69,11 +69,7 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | if (value > 20 && value < 32767) | 71 | if (value > 20 && value < 32767) |
| 72 | #ifndef FREQ | 72 | count = (IXP4XX_TIMER_FREQ / (value * 4)) - 1; |
| 73 | count = (ixp4xx_get_board_tick_rate() / (value * 4)) - 1; | ||
| 74 | #else | ||
| 75 | count = (FREQ / (value * 4)) - 1; | ||
| 76 | #endif | ||
| 77 | 73 | ||
| 78 | ixp4xx_spkr_control(pin, count); | 74 | ixp4xx_spkr_control(pin, count); |
| 79 | 75 | ||
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1f8e0108962..7e64d01da2b 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
| @@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 176 | 176 | ||
| 177 | /* request the IRQs */ | 177 | /* request the IRQs */ |
| 178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | 178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, |
| 179 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 179 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 180 | DRV_NAME, encoder); | 180 | DRV_NAME, encoder); |
| 181 | if (err) { | 181 | if (err) { |
| 182 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 182 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
| @@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, | 187 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, |
| 188 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 188 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 189 | DRV_NAME, encoder); | 189 | DRV_NAME, encoder); |
| 190 | if (err) { | 190 | if (err) { |
| 191 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 191 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index db5b0bca1a1..7c38d1fbabf 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -188,7 +188,8 @@ static void serio_free_event(struct serio_event *event) | |||
| 188 | kfree(event); | 188 | kfree(event); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | static void serio_remove_duplicate_events(struct serio_event *event) | 191 | static void serio_remove_duplicate_events(void *object, |
| 192 | enum serio_event_type type) | ||
| 192 | { | 193 | { |
| 193 | struct serio_event *e, *next; | 194 | struct serio_event *e, *next; |
| 194 | unsigned long flags; | 195 | unsigned long flags; |
| @@ -196,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
| 196 | spin_lock_irqsave(&serio_event_lock, flags); | 197 | spin_lock_irqsave(&serio_event_lock, flags); |
| 197 | 198 | ||
| 198 | list_for_each_entry_safe(e, next, &serio_event_list, node) { | 199 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
| 199 | if (event->object == e->object) { | 200 | if (object == e->object) { |
| 200 | /* | 201 | /* |
| 201 | * If this event is of different type we should not | 202 | * If this event is of different type we should not |
| 202 | * look further - we only suppress duplicate events | 203 | * look further - we only suppress duplicate events |
| 203 | * that were sent back-to-back. | 204 | * that were sent back-to-back. |
| 204 | */ | 205 | */ |
| 205 | if (event->type != e->type) | 206 | if (type != e->type) |
| 206 | break; | 207 | break; |
| 207 | 208 | ||
| 208 | list_del_init(&e->node); | 209 | list_del_init(&e->node); |
| @@ -245,7 +246,7 @@ static void serio_handle_event(struct work_struct *work) | |||
| 245 | break; | 246 | break; |
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | serio_remove_duplicate_events(event); | 249 | serio_remove_duplicate_events(event->object, event->type); |
| 249 | serio_free_event(event); | 250 | serio_free_event(event); |
| 250 | } | 251 | } |
| 251 | 252 | ||
| @@ -436,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
| 436 | } else if (!strncmp(buf, "rescan", count)) { | 437 | } else if (!strncmp(buf, "rescan", count)) { |
| 437 | serio_disconnect_port(serio); | 438 | serio_disconnect_port(serio); |
| 438 | serio_find_driver(serio); | 439 | serio_find_driver(serio); |
| 440 | serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | ||
| 439 | } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { | 441 | } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { |
| 440 | serio_disconnect_port(serio); | 442 | serio_disconnect_port(serio); |
| 441 | error = serio_bind_driver(serio, to_serio_driver(drv)); | 443 | error = serio_bind_driver(serio, to_serio_driver(drv)); |
| 442 | put_driver(drv); | 444 | put_driver(drv); |
| 445 | serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | ||
| 443 | } else { | 446 | } else { |
| 444 | error = -EINVAL; | 447 | error = -EINVAL; |
| 445 | } | 448 | } |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index fc381498b79..cf8fb9f5d4a 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
| @@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 519 | /* Retrieve the physical and logical size for OEM devices */ | 519 | /* Retrieve the physical and logical size for OEM devices */ |
| 520 | error = wacom_retrieve_hid_descriptor(intf, features); | 520 | error = wacom_retrieve_hid_descriptor(intf, features); |
| 521 | if (error) | 521 | if (error) |
| 522 | goto fail2; | 522 | goto fail3; |
| 523 | 523 | ||
| 524 | wacom_setup_device_quirks(features); | 524 | wacom_setup_device_quirks(features); |
| 525 | 525 | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 14ea54b78e4..4bf2316e328 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -941,28 +941,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 | |||
| 941 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 941 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
| 942 | int err; | 942 | int err; |
| 943 | 943 | ||
| 944 | /* REVISIT when the irq can be triggered active-low, or if for some | 944 | /* |
| 945 | * REVISIT when the irq can be triggered active-low, or if for some | ||
| 945 | * reason the touchscreen isn't hooked up, we don't need to access | 946 | * reason the touchscreen isn't hooked up, we don't need to access |
| 946 | * the pendown state. | 947 | * the pendown state. |
| 947 | */ | 948 | */ |
| 948 | if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { | ||
| 949 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | ||
| 950 | return -EINVAL; | ||
| 951 | } | ||
| 952 | 949 | ||
| 953 | if (pdata->get_pendown_state) { | 950 | if (pdata->get_pendown_state) { |
| 954 | ts->get_pendown_state = pdata->get_pendown_state; | 951 | ts->get_pendown_state = pdata->get_pendown_state; |
| 955 | return 0; | 952 | } else if (gpio_is_valid(pdata->gpio_pendown)) { |
| 956 | } | ||
| 957 | 953 | ||
| 958 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 954 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); |
| 959 | if (err) { | 955 | if (err) { |
| 960 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 956 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", |
| 961 | pdata->gpio_pendown); | 957 | pdata->gpio_pendown); |
| 962 | return err; | 958 | return err; |
| 963 | } | 959 | } |
| 964 | 960 | ||
| 965 | ts->gpio_pendown = pdata->gpio_pendown; | 961 | ts->gpio_pendown = pdata->gpio_pendown; |
| 962 | |||
| 963 | } else { | ||
| 964 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | ||
| 965 | return -EINVAL; | ||
| 966 | } | ||
| 966 | 967 | ||
| 967 | return 0; | 968 | return 0; |
| 968 | } | 969 | } |
| @@ -1353,7 +1354,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 1353 | err_put_regulator: | 1354 | err_put_regulator: |
| 1354 | regulator_put(ts->reg); | 1355 | regulator_put(ts->reg); |
| 1355 | err_free_gpio: | 1356 | err_free_gpio: |
| 1356 | if (ts->gpio_pendown != -1) | 1357 | if (!ts->get_pendown_state) |
| 1357 | gpio_free(ts->gpio_pendown); | 1358 | gpio_free(ts->gpio_pendown); |
| 1358 | err_cleanup_filter: | 1359 | err_cleanup_filter: |
| 1359 | if (ts->filter_cleanup) | 1360 | if (ts->filter_cleanup) |
| @@ -1383,8 +1384,13 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
| 1383 | regulator_disable(ts->reg); | 1384 | regulator_disable(ts->reg); |
| 1384 | regulator_put(ts->reg); | 1385 | regulator_put(ts->reg); |
| 1385 | 1386 | ||
| 1386 | if (ts->gpio_pendown != -1) | 1387 | if (!ts->get_pendown_state) { |
| 1388 | /* | ||
| 1389 | * If we are not using specialized pendown method we must | ||
| 1390 | * have been relying on gpio we set up ourselves. | ||
| 1391 | */ | ||
| 1387 | gpio_free(ts->gpio_pendown); | 1392 | gpio_free(ts->gpio_pendown); |
| 1393 | } | ||
| 1388 | 1394 | ||
| 1389 | if (ts->filter_cleanup) | 1395 | if (ts->filter_cleanup) |
| 1390 | ts->filter_cleanup(ts->filter_data); | 1396 | ts->filter_cleanup(ts->filter_data); |
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 5cb8449c909..c14412ef464 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
| @@ -51,6 +51,10 @@ MODULE_LICENSE("GPL"); | |||
| 51 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | 51 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ |
| 52 | #define W8001_PKTLEN_TOUCH2FG 13 | 52 | #define W8001_PKTLEN_TOUCH2FG 13 |
| 53 | 53 | ||
| 54 | /* resolution in points/mm */ | ||
| 55 | #define W8001_PEN_RESOLUTION 100 | ||
| 56 | #define W8001_TOUCH_RESOLUTION 10 | ||
| 57 | |||
| 54 | struct w8001_coord { | 58 | struct w8001_coord { |
| 55 | u8 rdy; | 59 | u8 rdy; |
| 56 | u8 tsw; | 60 | u8 tsw; |
| @@ -198,7 +202,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | |||
| 198 | query->y = 1024; | 202 | query->y = 1024; |
| 199 | if (query->panel_res) | 203 | if (query->panel_res) |
| 200 | query->x = query->y = (1 << query->panel_res); | 204 | query->x = query->y = (1 << query->panel_res); |
| 201 | query->panel_res = 10; | 205 | query->panel_res = W8001_TOUCH_RESOLUTION; |
| 202 | } | 206 | } |
| 203 | } | 207 | } |
| 204 | 208 | ||
| @@ -394,6 +398,8 @@ static int w8001_setup(struct w8001 *w8001) | |||
| 394 | 398 | ||
| 395 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | 399 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); |
| 396 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | 400 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); |
| 401 | input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); | ||
| 402 | input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); | ||
| 397 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | 403 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); |
| 398 | if (coord.tilt_x && coord.tilt_y) { | 404 | if (coord.tilt_x && coord.tilt_y) { |
| 399 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 405 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); |
| @@ -418,14 +424,17 @@ static int w8001_setup(struct w8001 *w8001) | |||
| 418 | w8001->max_touch_x = touch.x; | 424 | w8001->max_touch_x = touch.x; |
| 419 | w8001->max_touch_y = touch.y; | 425 | w8001->max_touch_y = touch.y; |
| 420 | 426 | ||
| 421 | /* scale to pen maximum */ | ||
| 422 | if (w8001->max_pen_x && w8001->max_pen_y) { | 427 | if (w8001->max_pen_x && w8001->max_pen_y) { |
| 428 | /* if pen is supported scale to pen maximum */ | ||
| 423 | touch.x = w8001->max_pen_x; | 429 | touch.x = w8001->max_pen_x; |
| 424 | touch.y = w8001->max_pen_y; | 430 | touch.y = w8001->max_pen_y; |
| 431 | touch.panel_res = W8001_PEN_RESOLUTION; | ||
| 425 | } | 432 | } |
| 426 | 433 | ||
| 427 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); | 434 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); |
| 428 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); | 435 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); |
| 436 | input_abs_set_res(dev, ABS_X, touch.panel_res); | ||
| 437 | input_abs_set_res(dev, ABS_Y, touch.panel_res); | ||
| 429 | 438 | ||
| 430 | switch (touch.sensor_id) { | 439 | switch (touch.sensor_id) { |
| 431 | case 0: | 440 | case 0: |
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 0858791978d..cfff0c41d29 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c | |||
| @@ -1247,10 +1247,10 @@ static void | |||
| 1247 | l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) | 1247 | l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) |
| 1248 | { | 1248 | { |
| 1249 | struct PStack *st = fi->userdata; | 1249 | struct PStack *st = fi->userdata; |
| 1250 | struct sk_buff *skb, *oskb; | 1250 | struct sk_buff *skb; |
| 1251 | struct Layer2 *l2 = &st->l2; | 1251 | struct Layer2 *l2 = &st->l2; |
| 1252 | u_char header[MAX_HEADER_LEN]; | 1252 | u_char header[MAX_HEADER_LEN]; |
| 1253 | int i; | 1253 | int i, hdr_space_needed; |
| 1254 | int unsigned p1; | 1254 | int unsigned p1; |
| 1255 | u_long flags; | 1255 | u_long flags; |
| 1256 | 1256 | ||
| @@ -1261,6 +1261,16 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) | |||
| 1261 | if (!skb) | 1261 | if (!skb) |
| 1262 | return; | 1262 | return; |
| 1263 | 1263 | ||
| 1264 | hdr_space_needed = l2headersize(l2, 0); | ||
| 1265 | if (hdr_space_needed > skb_headroom(skb)) { | ||
| 1266 | struct sk_buff *orig_skb = skb; | ||
| 1267 | |||
| 1268 | skb = skb_realloc_headroom(skb, hdr_space_needed); | ||
| 1269 | if (!skb) { | ||
| 1270 | dev_kfree_skb(orig_skb); | ||
| 1271 | return; | ||
| 1272 | } | ||
| 1273 | } | ||
| 1264 | spin_lock_irqsave(&l2->lock, flags); | 1274 | spin_lock_irqsave(&l2->lock, flags); |
| 1265 | if(test_bit(FLG_MOD128, &l2->flag)) | 1275 | if(test_bit(FLG_MOD128, &l2->flag)) |
| 1266 | p1 = (l2->vs - l2->va) % 128; | 1276 | p1 = (l2->vs - l2->va) % 128; |
| @@ -1285,19 +1295,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) | |||
| 1285 | l2->vs = (l2->vs + 1) % 8; | 1295 | l2->vs = (l2->vs + 1) % 8; |
| 1286 | } | 1296 | } |
| 1287 | spin_unlock_irqrestore(&l2->lock, flags); | 1297 | spin_unlock_irqrestore(&l2->lock, flags); |
| 1288 | p1 = skb->data - skb->head; | 1298 | memcpy(skb_push(skb, i), header, i); |
| 1289 | if (p1 >= i) | ||
| 1290 | memcpy(skb_push(skb, i), header, i); | ||
| 1291 | else { | ||
| 1292 | printk(KERN_WARNING | ||
| 1293 | "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); | ||
| 1294 | oskb = skb; | ||
| 1295 | skb = alloc_skb(oskb->len + i, GFP_ATOMIC); | ||
| 1296 | memcpy(skb_put(skb, i), header, i); | ||
| 1297 | skb_copy_from_linear_data(oskb, | ||
| 1298 | skb_put(skb, oskb->len), oskb->len); | ||
| 1299 | dev_kfree_skb(oskb); | ||
| 1300 | } | ||
| 1301 | st->l2.l2l1(st, PH_PULL | INDICATION, skb); | 1299 | st->l2.l2l1(st, PH_PULL | INDICATION, skb); |
| 1302 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); | 1300 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); |
| 1303 | if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { | 1301 | if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { |
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 729df408938..18b801ad97a 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h | |||
| @@ -227,7 +227,6 @@ extern hysdn_card *card_root; /* pointer to first card */ | |||
| 227 | /*************************/ | 227 | /*************************/ |
| 228 | /* im/exported functions */ | 228 | /* im/exported functions */ |
| 229 | /*************************/ | 229 | /*************************/ |
| 230 | extern char *hysdn_getrev(const char *); | ||
| 231 | 230 | ||
| 232 | /* hysdn_procconf.c */ | 231 | /* hysdn_procconf.c */ |
| 233 | extern int hysdn_procconf_init(void); /* init proc config filesys */ | 232 | extern int hysdn_procconf_init(void); /* init proc config filesys */ |
| @@ -259,7 +258,6 @@ extern int hysdn_tx_cfgline(hysdn_card *, unsigned char *, | |||
| 259 | 258 | ||
| 260 | /* hysdn_net.c */ | 259 | /* hysdn_net.c */ |
| 261 | extern unsigned int hynet_enable; | 260 | extern unsigned int hynet_enable; |
| 262 | extern char *hysdn_net_revision; | ||
| 263 | extern int hysdn_net_create(hysdn_card *); /* create a new net device */ | 261 | extern int hysdn_net_create(hysdn_card *); /* create a new net device */ |
| 264 | extern int hysdn_net_release(hysdn_card *); /* delete the device */ | 262 | extern int hysdn_net_release(hysdn_card *); /* delete the device */ |
| 265 | extern char *hysdn_net_getname(hysdn_card *); /* get name of net interface */ | 263 | extern char *hysdn_net_getname(hysdn_card *); /* get name of net interface */ |
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index b7cc5c2f08c..0ab42ace169 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c | |||
| @@ -36,7 +36,6 @@ MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards"); | |||
| 36 | MODULE_AUTHOR("Werner Cornelius"); | 36 | MODULE_AUTHOR("Werner Cornelius"); |
| 37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
| 38 | 38 | ||
| 39 | static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; | ||
| 40 | static int cardmax; /* number of found cards */ | 39 | static int cardmax; /* number of found cards */ |
| 41 | hysdn_card *card_root = NULL; /* pointer to first card */ | 40 | hysdn_card *card_root = NULL; /* pointer to first card */ |
| 42 | static hysdn_card *card_last = NULL; /* pointer to first card */ | 41 | static hysdn_card *card_last = NULL; /* pointer to first card */ |
| @@ -49,25 +48,6 @@ static hysdn_card *card_last = NULL; /* pointer to first card */ | |||
| 49 | /* Additionally newer versions may be activated without rebooting. */ | 48 | /* Additionally newer versions may be activated without rebooting. */ |
| 50 | /****************************************************************************/ | 49 | /****************************************************************************/ |
| 51 | 50 | ||
| 52 | /******************************************************/ | ||
| 53 | /* extract revision number from string for log output */ | ||
| 54 | /******************************************************/ | ||
| 55 | char * | ||
| 56 | hysdn_getrev(const char *revision) | ||
| 57 | { | ||
| 58 | char *rev; | ||
| 59 | char *p; | ||
| 60 | |||
| 61 | if ((p = strchr(revision, ':'))) { | ||
| 62 | rev = p + 2; | ||
| 63 | p = strchr(rev, '$'); | ||
| 64 | *--p = 0; | ||
| 65 | } else | ||
| 66 | rev = "???"; | ||
| 67 | return rev; | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | /****************************************************************************/ | 51 | /****************************************************************************/ |
| 72 | /* init_module is called once when the module is loaded to do all necessary */ | 52 | /* init_module is called once when the module is loaded to do all necessary */ |
| 73 | /* things like autodetect... */ | 53 | /* things like autodetect... */ |
| @@ -175,13 +155,9 @@ static int hysdn_have_procfs; | |||
| 175 | static int __init | 155 | static int __init |
| 176 | hysdn_init(void) | 156 | hysdn_init(void) |
| 177 | { | 157 | { |
| 178 | char tmp[50]; | ||
| 179 | int rc; | 158 | int rc; |
| 180 | 159 | ||
| 181 | strcpy(tmp, hysdn_init_revision); | 160 | printk(KERN_NOTICE "HYSDN: module loaded\n"); |
| 182 | printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp)); | ||
| 183 | strcpy(tmp, hysdn_net_revision); | ||
| 184 | printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp)); | ||
| 185 | 161 | ||
| 186 | rc = pci_register_driver(&hysdn_pci_driver); | 162 | rc = pci_register_driver(&hysdn_pci_driver); |
| 187 | if (rc) | 163 | if (rc) |
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c index feec8d89d71..11f2cce2600 100644 --- a/drivers/isdn/hysdn/hysdn_net.c +++ b/drivers/isdn/hysdn/hysdn_net.c | |||
| @@ -26,9 +26,6 @@ | |||
| 26 | unsigned int hynet_enable = 0xffffffff; | 26 | unsigned int hynet_enable = 0xffffffff; |
| 27 | module_param(hynet_enable, uint, 0); | 27 | module_param(hynet_enable, uint, 0); |
| 28 | 28 | ||
| 29 | /* store the actual version for log reporting */ | ||
| 30 | char *hysdn_net_revision = "$Revision: 1.8.6.4 $"; | ||
| 31 | |||
| 32 | #define MAX_SKB_BUFFERS 20 /* number of buffers for keeping TX-data */ | 29 | #define MAX_SKB_BUFFERS 20 /* number of buffers for keeping TX-data */ |
| 33 | 30 | ||
| 34 | /****************************************************************************/ | 31 | /****************************************************************************/ |
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 96b3e39c335..5fe83bd4206 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "hysdn_defs.h" | 23 | #include "hysdn_defs.h" |
| 24 | 24 | ||
| 25 | static DEFINE_MUTEX(hysdn_conf_mutex); | 25 | static DEFINE_MUTEX(hysdn_conf_mutex); |
| 26 | static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $"; | ||
| 27 | 26 | ||
| 28 | #define INFO_OUT_LEN 80 /* length of info line including lf */ | 27 | #define INFO_OUT_LEN 80 /* length of info line including lf */ |
| 29 | 28 | ||
| @@ -404,7 +403,7 @@ hysdn_procconf_init(void) | |||
| 404 | card = card->next; /* next entry */ | 403 | card = card->next; /* next entry */ |
| 405 | } | 404 | } |
| 406 | 405 | ||
| 407 | printk(KERN_NOTICE "HYSDN: procfs Rev. %s initialised\n", hysdn_getrev(hysdn_procconf_revision)); | 406 | printk(KERN_NOTICE "HYSDN: procfs initialised\n"); |
| 408 | return (0); | 407 | return (0); |
| 409 | } /* hysdn_procconf_init */ | 408 | } /* hysdn_procconf_init */ |
| 410 | 409 | ||
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index f2b5bab5e6a..1f355bb85e5 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
| @@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup); | |||
| 1627 | static int __init icn_init(void) | 1627 | static int __init icn_init(void) |
| 1628 | { | 1628 | { |
| 1629 | char *p; | 1629 | char *p; |
| 1630 | char rev[20]; | 1630 | char rev[21]; |
| 1631 | 1631 | ||
| 1632 | memset(&dev, 0, sizeof(icn_dev)); | 1632 | memset(&dev, 0, sizeof(icn_dev)); |
| 1633 | dev.memaddr = (membase & 0x0ffc000); | 1633 | dev.memaddr = (membase & 0x0ffc000); |
| @@ -1638,6 +1638,7 @@ static int __init icn_init(void) | |||
| 1638 | 1638 | ||
| 1639 | if ((p = strchr(revision, ':'))) { | 1639 | if ((p = strchr(revision, ':'))) { |
| 1640 | strncpy(rev, p + 1, 20); | 1640 | strncpy(rev, p + 1, 20); |
| 1641 | rev[20] = '\0'; | ||
| 1641 | p = strchr(rev, '$'); | 1642 | p = strchr(rev, '$'); |
| 1642 | if (p) | 1643 | if (p) |
| 1643 | *p = 0; | 1644 | *p = 0; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index b76cfc89e1b..0cc30ecda4c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -287,6 +287,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio) | |||
| 287 | mddev_t *mddev = q->queuedata; | 287 | mddev_t *mddev = q->queuedata; |
| 288 | int rv; | 288 | int rv; |
| 289 | int cpu; | 289 | int cpu; |
| 290 | unsigned int sectors; | ||
| 290 | 291 | ||
| 291 | if (mddev == NULL || mddev->pers == NULL | 292 | if (mddev == NULL || mddev->pers == NULL |
| 292 | || !mddev->ready) { | 293 | || !mddev->ready) { |
| @@ -311,12 +312,16 @@ static int md_make_request(struct request_queue *q, struct bio *bio) | |||
| 311 | atomic_inc(&mddev->active_io); | 312 | atomic_inc(&mddev->active_io); |
| 312 | rcu_read_unlock(); | 313 | rcu_read_unlock(); |
| 313 | 314 | ||
| 315 | /* | ||
| 316 | * save the sectors now since our bio can | ||
| 317 | * go away inside make_request | ||
| 318 | */ | ||
| 319 | sectors = bio_sectors(bio); | ||
| 314 | rv = mddev->pers->make_request(mddev, bio); | 320 | rv = mddev->pers->make_request(mddev, bio); |
| 315 | 321 | ||
| 316 | cpu = part_stat_lock(); | 322 | cpu = part_stat_lock(); |
| 317 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); | 323 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
| 318 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], | 324 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors); |
| 319 | bio_sectors(bio)); | ||
| 320 | part_stat_unlock(); | 325 | part_stat_unlock(); |
| 321 | 326 | ||
| 322 | if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) | 327 | if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) |
| @@ -1947,8 +1952,6 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) | |||
| 1947 | __bdevname(dev, b)); | 1952 | __bdevname(dev, b)); |
| 1948 | return PTR_ERR(bdev); | 1953 | return PTR_ERR(bdev); |
| 1949 | } | 1954 | } |
| 1950 | if (!shared) | ||
| 1951 | set_bit(AllReserved, &rdev->flags); | ||
| 1952 | rdev->bdev = bdev; | 1955 | rdev->bdev = bdev; |
| 1953 | return err; | 1956 | return err; |
| 1954 | } | 1957 | } |
| @@ -2465,6 +2468,9 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2465 | if (rdev->raid_disk != -1) | 2468 | if (rdev->raid_disk != -1) |
| 2466 | return -EBUSY; | 2469 | return -EBUSY; |
| 2467 | 2470 | ||
| 2471 | if (test_bit(MD_RECOVERY_RUNNING, &rdev->mddev->recovery)) | ||
| 2472 | return -EBUSY; | ||
| 2473 | |||
| 2468 | if (rdev->mddev->pers->hot_add_disk == NULL) | 2474 | if (rdev->mddev->pers->hot_add_disk == NULL) |
| 2469 | return -EINVAL; | 2475 | return -EINVAL; |
| 2470 | 2476 | ||
| @@ -2610,12 +2616,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2610 | 2616 | ||
| 2611 | mddev_lock(mddev); | 2617 | mddev_lock(mddev); |
| 2612 | list_for_each_entry(rdev2, &mddev->disks, same_set) | 2618 | list_for_each_entry(rdev2, &mddev->disks, same_set) |
| 2613 | if (test_bit(AllReserved, &rdev2->flags) || | 2619 | if (rdev->bdev == rdev2->bdev && |
| 2614 | (rdev->bdev == rdev2->bdev && | 2620 | rdev != rdev2 && |
| 2615 | rdev != rdev2 && | 2621 | overlaps(rdev->data_offset, rdev->sectors, |
| 2616 | overlaps(rdev->data_offset, rdev->sectors, | 2622 | rdev2->data_offset, |
| 2617 | rdev2->data_offset, | 2623 | rdev2->sectors)) { |
| 2618 | rdev2->sectors))) { | ||
| 2619 | overlap = 1; | 2624 | overlap = 1; |
| 2620 | break; | 2625 | break; |
| 2621 | } | 2626 | } |
| @@ -5578,6 +5583,8 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 5578 | mddev->delta_disks = raid_disks - mddev->raid_disks; | 5583 | mddev->delta_disks = raid_disks - mddev->raid_disks; |
| 5579 | 5584 | ||
| 5580 | rv = mddev->pers->check_reshape(mddev); | 5585 | rv = mddev->pers->check_reshape(mddev); |
| 5586 | if (rv < 0) | ||
| 5587 | mddev->delta_disks = 0; | ||
| 5581 | return rv; | 5588 | return rv; |
| 5582 | } | 5589 | } |
| 5583 | 5590 | ||
| @@ -6985,9 +6992,6 @@ void md_do_sync(mddev_t *mddev) | |||
| 6985 | } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | 6992 | } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) |
| 6986 | mddev->resync_min = mddev->curr_resync_completed; | 6993 | mddev->resync_min = mddev->curr_resync_completed; |
| 6987 | mddev->curr_resync = 0; | 6994 | mddev->curr_resync = 0; |
| 6988 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | ||
| 6989 | mddev->curr_resync_completed = 0; | ||
| 6990 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 6991 | wake_up(&resync_wait); | 6995 | wake_up(&resync_wait); |
| 6992 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); | 6996 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); |
| 6993 | md_wakeup_thread(mddev->thread); | 6997 | md_wakeup_thread(mddev->thread); |
| @@ -7028,7 +7032,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 7028 | } | 7032 | } |
| 7029 | } | 7033 | } |
| 7030 | 7034 | ||
| 7031 | if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) { | 7035 | if (mddev->degraded && !mddev->recovery_disabled) { |
| 7032 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 7036 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 7033 | if (rdev->raid_disk >= 0 && | 7037 | if (rdev->raid_disk >= 0 && |
| 7034 | !test_bit(In_sync, &rdev->flags) && | 7038 | !test_bit(In_sync, &rdev->flags) && |
| @@ -7151,7 +7155,20 @@ void md_check_recovery(mddev_t *mddev) | |||
| 7151 | /* Only thing we do on a ro array is remove | 7155 | /* Only thing we do on a ro array is remove |
| 7152 | * failed devices. | 7156 | * failed devices. |
| 7153 | */ | 7157 | */ |
| 7154 | remove_and_add_spares(mddev); | 7158 | mdk_rdev_t *rdev; |
| 7159 | list_for_each_entry(rdev, &mddev->disks, same_set) | ||
| 7160 | if (rdev->raid_disk >= 0 && | ||
| 7161 | !test_bit(Blocked, &rdev->flags) && | ||
| 7162 | test_bit(Faulty, &rdev->flags) && | ||
| 7163 | atomic_read(&rdev->nr_pending)==0) { | ||
| 7164 | if (mddev->pers->hot_remove_disk( | ||
| 7165 | mddev, rdev->raid_disk)==0) { | ||
| 7166 | char nm[20]; | ||
| 7167 | sprintf(nm,"rd%d", rdev->raid_disk); | ||
| 7168 | sysfs_remove_link(&mddev->kobj, nm); | ||
| 7169 | rdev->raid_disk = -1; | ||
| 7170 | } | ||
| 7171 | } | ||
| 7155 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 7172 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 7156 | goto unlock; | 7173 | goto unlock; |
| 7157 | } | 7174 | } |
diff --git a/drivers/md/md.h b/drivers/md/md.h index eec517ced31..7e90b8593b2 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
| @@ -93,8 +93,6 @@ struct mdk_rdev_s | |||
| 93 | #define Faulty 1 /* device is known to have a fault */ | 93 | #define Faulty 1 /* device is known to have a fault */ |
| 94 | #define In_sync 2 /* device is in_sync with rest of array */ | 94 | #define In_sync 2 /* device is in_sync with rest of array */ |
| 95 | #define WriteMostly 4 /* Avoid reading if at all possible */ | 95 | #define WriteMostly 4 /* Avoid reading if at all possible */ |
| 96 | #define AllReserved 6 /* If whole device is reserved for | ||
| 97 | * one array */ | ||
| 98 | #define AutoDetected 7 /* added by auto-detect */ | 96 | #define AutoDetected 7 /* added by auto-detect */ |
| 99 | #define Blocked 8 /* An error occured on an externally | 97 | #define Blocked 8 /* An error occured on an externally |
| 100 | * managed array, don't allow writes | 98 | * managed array, don't allow writes |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index a39f4c355e5..637a96855ed 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
| @@ -179,6 +179,14 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) | |||
| 179 | rdev1->new_raid_disk = j; | 179 | rdev1->new_raid_disk = j; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | if (mddev->level == 1) { | ||
| 183 | /* taiking over a raid1 array- | ||
| 184 | * we have only one active disk | ||
| 185 | */ | ||
| 186 | j = 0; | ||
| 187 | rdev1->new_raid_disk = j; | ||
| 188 | } | ||
| 189 | |||
| 182 | if (j < 0 || j >= mddev->raid_disks) { | 190 | if (j < 0 || j >= mddev->raid_disks) { |
| 183 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " | 191 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " |
| 184 | "aborting!\n", mdname(mddev), j); | 192 | "aborting!\n", mdname(mddev), j); |
| @@ -644,12 +652,38 @@ static void *raid0_takeover_raid10(mddev_t *mddev) | |||
| 644 | return priv_conf; | 652 | return priv_conf; |
| 645 | } | 653 | } |
| 646 | 654 | ||
| 655 | static void *raid0_takeover_raid1(mddev_t *mddev) | ||
| 656 | { | ||
| 657 | raid0_conf_t *priv_conf; | ||
| 658 | |||
| 659 | /* Check layout: | ||
| 660 | * - (N - 1) mirror drives must be already faulty | ||
| 661 | */ | ||
| 662 | if ((mddev->raid_disks - 1) != mddev->degraded) { | ||
| 663 | printk(KERN_ERR "md/raid0:%s: (N - 1) mirrors drives must be already faulty!\n", | ||
| 664 | mdname(mddev)); | ||
| 665 | return ERR_PTR(-EINVAL); | ||
| 666 | } | ||
| 667 | |||
| 668 | /* Set new parameters */ | ||
| 669 | mddev->new_level = 0; | ||
| 670 | mddev->new_layout = 0; | ||
| 671 | mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ | ||
| 672 | mddev->delta_disks = 1 - mddev->raid_disks; | ||
| 673 | /* make sure it will be not marked as dirty */ | ||
| 674 | mddev->recovery_cp = MaxSector; | ||
| 675 | |||
| 676 | create_strip_zones(mddev, &priv_conf); | ||
| 677 | return priv_conf; | ||
| 678 | } | ||
| 679 | |||
| 647 | static void *raid0_takeover(mddev_t *mddev) | 680 | static void *raid0_takeover(mddev_t *mddev) |
| 648 | { | 681 | { |
| 649 | /* raid0 can take over: | 682 | /* raid0 can take over: |
| 650 | * raid4 - if all data disks are active. | 683 | * raid4 - if all data disks are active. |
| 651 | * raid5 - providing it is Raid4 layout and one disk is faulty | 684 | * raid5 - providing it is Raid4 layout and one disk is faulty |
| 652 | * raid10 - assuming we have all necessary active disks | 685 | * raid10 - assuming we have all necessary active disks |
| 686 | * raid1 - with (N -1) mirror drives faulty | ||
| 653 | */ | 687 | */ |
| 654 | if (mddev->level == 4) | 688 | if (mddev->level == 4) |
| 655 | return raid0_takeover_raid45(mddev); | 689 | return raid0_takeover_raid45(mddev); |
| @@ -665,6 +699,12 @@ static void *raid0_takeover(mddev_t *mddev) | |||
| 665 | if (mddev->level == 10) | 699 | if (mddev->level == 10) |
| 666 | return raid0_takeover_raid10(mddev); | 700 | return raid0_takeover_raid10(mddev); |
| 667 | 701 | ||
| 702 | if (mddev->level == 1) | ||
| 703 | return raid0_takeover_raid1(mddev); | ||
| 704 | |||
| 705 | printk(KERN_ERR "Takeover from raid%i to raid0 not supported\n", | ||
| 706 | mddev->level); | ||
| 707 | |||
| 668 | return ERR_PTR(-EINVAL); | 708 | return ERR_PTR(-EINVAL); |
| 669 | } | 709 | } |
| 670 | 710 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 69b65954439..3b607b28741 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2463,11 +2463,13 @@ static void *raid10_takeover_raid0(mddev_t *mddev) | |||
| 2463 | mddev->recovery_cp = MaxSector; | 2463 | mddev->recovery_cp = MaxSector; |
| 2464 | 2464 | ||
| 2465 | conf = setup_conf(mddev); | 2465 | conf = setup_conf(mddev); |
| 2466 | if (!IS_ERR(conf)) | 2466 | if (!IS_ERR(conf)) { |
| 2467 | list_for_each_entry(rdev, &mddev->disks, same_set) | 2467 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 2468 | if (rdev->raid_disk >= 0) | 2468 | if (rdev->raid_disk >= 0) |
| 2469 | rdev->new_raid_disk = rdev->raid_disk * 2; | 2469 | rdev->new_raid_disk = rdev->raid_disk * 2; |
| 2470 | 2470 | conf->barrier = 1; | |
| 2471 | } | ||
| 2472 | |||
| 2471 | return conf; | 2473 | return conf; |
| 2472 | } | 2474 | } |
| 2473 | 2475 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5044babfcda..70281282419 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -5517,7 +5517,6 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5517 | raid5_conf_t *conf = mddev->private; | 5517 | raid5_conf_t *conf = mddev->private; |
| 5518 | mdk_rdev_t *rdev; | 5518 | mdk_rdev_t *rdev; |
| 5519 | int spares = 0; | 5519 | int spares = 0; |
| 5520 | int added_devices = 0; | ||
| 5521 | unsigned long flags; | 5520 | unsigned long flags; |
| 5522 | 5521 | ||
| 5523 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 5522 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
| @@ -5527,8 +5526,8 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5527 | return -ENOSPC; | 5526 | return -ENOSPC; |
| 5528 | 5527 | ||
| 5529 | list_for_each_entry(rdev, &mddev->disks, same_set) | 5528 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5530 | if ((rdev->raid_disk < 0 || rdev->raid_disk >= conf->raid_disks) | 5529 | if (!test_bit(In_sync, &rdev->flags) |
| 5531 | && !test_bit(Faulty, &rdev->flags)) | 5530 | && !test_bit(Faulty, &rdev->flags)) |
| 5532 | spares++; | 5531 | spares++; |
| 5533 | 5532 | ||
| 5534 | if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded) | 5533 | if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded) |
| @@ -5571,34 +5570,35 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5571 | * to correctly record the "partially reconstructed" state of | 5570 | * to correctly record the "partially reconstructed" state of |
| 5572 | * such devices during the reshape and confusion could result. | 5571 | * such devices during the reshape and confusion could result. |
| 5573 | */ | 5572 | */ |
| 5574 | if (mddev->delta_disks >= 0) | 5573 | if (mddev->delta_disks >= 0) { |
| 5575 | list_for_each_entry(rdev, &mddev->disks, same_set) | 5574 | int added_devices = 0; |
| 5576 | if (rdev->raid_disk < 0 && | 5575 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5577 | !test_bit(Faulty, &rdev->flags)) { | 5576 | if (rdev->raid_disk < 0 && |
| 5578 | if (raid5_add_disk(mddev, rdev) == 0) { | 5577 | !test_bit(Faulty, &rdev->flags)) { |
| 5579 | char nm[20]; | 5578 | if (raid5_add_disk(mddev, rdev) == 0) { |
| 5580 | if (rdev->raid_disk >= conf->previous_raid_disks) { | 5579 | char nm[20]; |
| 5581 | set_bit(In_sync, &rdev->flags); | 5580 | if (rdev->raid_disk |
| 5582 | added_devices++; | 5581 | >= conf->previous_raid_disks) { |
| 5583 | } else | 5582 | set_bit(In_sync, &rdev->flags); |
| 5584 | rdev->recovery_offset = 0; | 5583 | added_devices++; |
| 5585 | sprintf(nm, "rd%d", rdev->raid_disk); | 5584 | } else |
| 5586 | if (sysfs_create_link(&mddev->kobj, | 5585 | rdev->recovery_offset = 0; |
| 5587 | &rdev->kobj, nm)) | 5586 | sprintf(nm, "rd%d", rdev->raid_disk); |
| 5588 | /* Failure here is OK */; | 5587 | if (sysfs_create_link(&mddev->kobj, |
| 5589 | } else | 5588 | &rdev->kobj, nm)) |
| 5590 | break; | 5589 | /* Failure here is OK */; |
| 5591 | } else if (rdev->raid_disk >= conf->previous_raid_disks | 5590 | } |
| 5592 | && !test_bit(Faulty, &rdev->flags)) { | 5591 | } else if (rdev->raid_disk >= conf->previous_raid_disks |
| 5593 | /* This is a spare that was manually added */ | 5592 | && !test_bit(Faulty, &rdev->flags)) { |
| 5594 | set_bit(In_sync, &rdev->flags); | 5593 | /* This is a spare that was manually added */ |
| 5595 | added_devices++; | 5594 | set_bit(In_sync, &rdev->flags); |
| 5596 | } | 5595 | added_devices++; |
| 5596 | } | ||
| 5597 | 5597 | ||
| 5598 | /* When a reshape changes the number of devices, ->degraded | 5598 | /* When a reshape changes the number of devices, |
| 5599 | * is measured against the larger of the pre and post number of | 5599 | * ->degraded is measured against the larger of the |
| 5600 | * devices.*/ | 5600 | * pre and post number of devices. |
| 5601 | if (mddev->delta_disks > 0) { | 5601 | */ |
| 5602 | spin_lock_irqsave(&conf->device_lock, flags); | 5602 | spin_lock_irqsave(&conf->device_lock, flags); |
| 5603 | mddev->degraded += (conf->raid_disks - conf->previous_raid_disks) | 5603 | mddev->degraded += (conf->raid_disks - conf->previous_raid_disks) |
| 5604 | - added_devices; | 5604 | - added_devices; |
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index e9a3eab7b0c..8c1d85e27be 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c | |||
| @@ -621,7 +621,7 @@ static int __init memstick_init(void) | |||
| 621 | { | 621 | { |
| 622 | int rc; | 622 | int rc; |
| 623 | 623 | ||
| 624 | workqueue = create_freezeable_workqueue("kmemstick"); | 624 | workqueue = create_freezable_workqueue("kmemstick"); |
| 625 | if (!workqueue) | 625 | if (!workqueue) |
| 626 | return -ENOMEM; | 626 | return -ENOMEM; |
| 627 | 627 | ||
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index f71f2294847..1735c84ff75 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
| @@ -76,8 +76,8 @@ | |||
| 76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR | 76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
| 79 | #define MPT_LINUX_VERSION_COMMON "3.04.17" | 79 | #define MPT_LINUX_VERSION_COMMON "3.04.18" |
| 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17" | 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.18" |
| 81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
| 82 | 82 | ||
| 83 | #define show_mptmod_ver(s,ver) \ | 83 | #define show_mptmod_ver(s,ver) \ |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index a3856ed90ae..e8deb8ed049 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
| @@ -597,6 +597,13 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | static int | 599 | static int |
| 600 | mptctl_release(struct inode *inode, struct file *filep) | ||
| 601 | { | ||
| 602 | fasync_helper(-1, filep, 0, &async_queue); | ||
| 603 | return 0; | ||
| 604 | } | ||
| 605 | |||
| 606 | static int | ||
| 600 | mptctl_fasync(int fd, struct file *filep, int mode) | 607 | mptctl_fasync(int fd, struct file *filep, int mode) |
| 601 | { | 608 | { |
| 602 | MPT_ADAPTER *ioc; | 609 | MPT_ADAPTER *ioc; |
| @@ -2815,6 +2822,7 @@ static const struct file_operations mptctl_fops = { | |||
| 2815 | .llseek = no_llseek, | 2822 | .llseek = no_llseek, |
| 2816 | .fasync = mptctl_fasync, | 2823 | .fasync = mptctl_fasync, |
| 2817 | .unlocked_ioctl = mptctl_ioctl, | 2824 | .unlocked_ioctl = mptctl_ioctl, |
| 2825 | .release = mptctl_release, | ||
| 2818 | #ifdef CONFIG_COMPAT | 2826 | #ifdef CONFIG_COMPAT |
| 2819 | .compat_ioctl = compat_mpctl_ioctl, | 2827 | .compat_ioctl = compat_mpctl_ioctl, |
| 2820 | #endif | 2828 | #endif |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 59b8f53d1ec..0d9b82a4454 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
| @@ -1873,8 +1873,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
| 1873 | } | 1873 | } |
| 1874 | 1874 | ||
| 1875 | out: | 1875 | out: |
| 1876 | printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", | 1876 | printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p) (sn=%ld)\n", |
| 1877 | ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt); | 1877 | ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval, |
| 1878 | SCpnt, SCpnt->serial_number); | ||
| 1878 | 1879 | ||
| 1879 | return retval; | 1880 | return retval; |
| 1880 | } | 1881 | } |
| @@ -1911,7 +1912,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
| 1911 | 1912 | ||
| 1912 | vdevice = SCpnt->device->hostdata; | 1913 | vdevice = SCpnt->device->hostdata; |
| 1913 | if (!vdevice || !vdevice->vtarget) { | 1914 | if (!vdevice || !vdevice->vtarget) { |
| 1914 | retval = SUCCESS; | 1915 | retval = 0; |
| 1915 | goto out; | 1916 | goto out; |
| 1916 | } | 1917 | } |
| 1917 | 1918 | ||
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 5f6852dff40..44d4475a09d 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c | |||
| @@ -329,7 +329,7 @@ static int __init tifm_init(void) | |||
| 329 | { | 329 | { |
| 330 | int rc; | 330 | int rc; |
| 331 | 331 | ||
| 332 | workqueue = create_freezeable_workqueue("tifm"); | 332 | workqueue = create_freezable_workqueue("tifm"); |
| 333 | if (!workqueue) | 333 | if (!workqueue) |
| 334 | return -ENOMEM; | 334 | return -ENOMEM; |
| 335 | 335 | ||
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 4d2ea8e8014..6df5a55da11 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
| @@ -785,7 +785,7 @@ static int __init vmballoon_init(void) | |||
| 785 | if (x86_hyper != &x86_hyper_vmware) | 785 | if (x86_hyper != &x86_hyper_vmware) |
| 786 | return -ENODEV; | 786 | return -ENODEV; |
| 787 | 787 | ||
| 788 | vmballoon_wq = create_freezeable_workqueue("vmmemctl"); | 788 | vmballoon_wq = create_freezable_workqueue("vmmemctl"); |
| 789 | if (!vmballoon_wq) { | 789 | if (!vmballoon_wq) { |
| 790 | pr_err("failed to create workqueue\n"); | 790 | pr_err("failed to create workqueue\n"); |
| 791 | return -ENOMEM; | 791 | return -ENOMEM; |
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index d9d7efbc77c..6322d1fb5d6 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c | |||
| @@ -930,7 +930,7 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
| 930 | 930 | ||
| 931 | init_completion(&dev->dma_done); | 931 | init_completion(&dev->dma_done); |
| 932 | 932 | ||
| 933 | dev->card_workqueue = create_freezeable_workqueue(DRV_NAME); | 933 | dev->card_workqueue = create_freezable_workqueue(DRV_NAME); |
| 934 | 934 | ||
| 935 | if (!dev->card_workqueue) | 935 | if (!dev->card_workqueue) |
| 936 | goto error9; | 936 | goto error9; |
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 67822cf6c02..ac0d6a8613b 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c | |||
| @@ -1258,7 +1258,7 @@ static struct mtd_blktrans_ops sm_ftl_ops = { | |||
| 1258 | static __init int sm_module_init(void) | 1258 | static __init int sm_module_init(void) |
| 1259 | { | 1259 | { |
| 1260 | int error = 0; | 1260 | int error = 0; |
| 1261 | cache_flush_workqueue = create_freezeable_workqueue("smflush"); | 1261 | cache_flush_workqueue = create_freezable_workqueue("smflush"); |
| 1262 | 1262 | ||
| 1263 | if (IS_ERR(cache_flush_workqueue)) | 1263 | if (IS_ERR(cache_flush_workqueue)) |
| 1264 | return PTR_ERR(cache_flush_workqueue); | 1264 | return PTR_ERR(cache_flush_workqueue); |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index a699bbf20eb..3824382faec 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
| @@ -48,6 +48,7 @@ static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = { | |||
| 48 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)}, | 48 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)}, |
| 49 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)}, | 49 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)}, |
| 50 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, | 50 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, |
| 51 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)}, | ||
| 51 | /* required last entry */ | 52 | /* required last entry */ |
| 52 | { 0 } | 53 | { 0 } |
| 53 | }; | 54 | }; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 0c7811faf72..a179cc6d79f 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
| @@ -1786,6 +1786,10 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
| 1786 | spin_lock_bh(&adapter->mcc_lock); | 1786 | spin_lock_bh(&adapter->mcc_lock); |
| 1787 | 1787 | ||
| 1788 | wrb = wrb_from_mccq(adapter); | 1788 | wrb = wrb_from_mccq(adapter); |
| 1789 | if (!wrb) { | ||
| 1790 | status = -EBUSY; | ||
| 1791 | goto err; | ||
| 1792 | } | ||
| 1789 | req = nonemb_cmd->va; | 1793 | req = nonemb_cmd->va; |
| 1790 | sge = nonembedded_sgl(wrb); | 1794 | sge = nonembedded_sgl(wrb); |
| 1791 | 1795 | ||
| @@ -1801,6 +1805,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
| 1801 | 1805 | ||
| 1802 | status = be_mcc_notify_wait(adapter); | 1806 | status = be_mcc_notify_wait(adapter); |
| 1803 | 1807 | ||
| 1808 | err: | ||
| 1804 | spin_unlock_bh(&adapter->mcc_lock); | 1809 | spin_unlock_bh(&adapter->mcc_lock); |
| 1805 | return status; | 1810 | return status; |
| 1806 | } | 1811 | } |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index de40d3b7152..28a32a6c8bf 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
| @@ -312,11 +312,9 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) | |||
| 312 | if (adapter->link_up != link_up) { | 312 | if (adapter->link_up != link_up) { |
| 313 | adapter->link_speed = -1; | 313 | adapter->link_speed = -1; |
| 314 | if (link_up) { | 314 | if (link_up) { |
| 315 | netif_start_queue(netdev); | ||
| 316 | netif_carrier_on(netdev); | 315 | netif_carrier_on(netdev); |
| 317 | printk(KERN_INFO "%s: Link up\n", netdev->name); | 316 | printk(KERN_INFO "%s: Link up\n", netdev->name); |
| 318 | } else { | 317 | } else { |
| 319 | netif_stop_queue(netdev); | ||
| 320 | netif_carrier_off(netdev); | 318 | netif_carrier_off(netdev); |
| 321 | printk(KERN_INFO "%s: Link down\n", netdev->name); | 319 | printk(KERN_INFO "%s: Link down\n", netdev->name); |
| 322 | } | 320 | } |
| @@ -2628,8 +2626,6 @@ static void be_netdev_init(struct net_device *netdev) | |||
| 2628 | 2626 | ||
| 2629 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, | 2627 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, |
| 2630 | BE_NAPI_WEIGHT); | 2628 | BE_NAPI_WEIGHT); |
| 2631 | |||
| 2632 | netif_stop_queue(netdev); | ||
| 2633 | } | 2629 | } |
| 2634 | 2630 | ||
| 2635 | static void be_unmap_pci_bars(struct be_adapter *adapter) | 2631 | static void be_unmap_pci_bars(struct be_adapter *adapter) |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8e4183717d9..653c62475cb 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | * (you will need to reboot afterwards) */ | 22 | * (you will need to reboot afterwards) */ |
| 23 | /* #define BNX2X_STOP_ON_ERROR */ | 23 | /* #define BNX2X_STOP_ON_ERROR */ |
| 24 | 24 | ||
| 25 | #define DRV_MODULE_VERSION "1.62.00-4" | 25 | #define DRV_MODULE_VERSION "1.62.00-5" |
| 26 | #define DRV_MODULE_RELDATE "2011/01/18" | 26 | #define DRV_MODULE_RELDATE "2011/01/30" |
| 27 | #define BNX2X_BC_VER 0x040200 | 27 | #define BNX2X_BC_VER 0x040200 |
| 28 | 28 | ||
| 29 | #define BNX2X_MULTI_QUEUE | 29 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7160ec51093..dd1210fddff 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
| @@ -3948,48 +3948,6 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | |||
| 3948 | return rc; | 3948 | return rc; |
| 3949 | } | 3949 | } |
| 3950 | 3950 | ||
| 3951 | static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, | ||
| 3952 | struct bnx2x_phy *phy) | ||
| 3953 | { | ||
| 3954 | u16 val; | ||
| 3955 | bnx2x_cl45_read(bp, phy, | ||
| 3956 | MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); | ||
| 3957 | |||
| 3958 | if (val == 0) { | ||
| 3959 | /* Mustn't set low power mode in 8073 A0 */ | ||
| 3960 | return; | ||
| 3961 | } | ||
| 3962 | |||
| 3963 | /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ | ||
| 3964 | bnx2x_cl45_read(bp, phy, | ||
| 3965 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); | ||
| 3966 | val &= ~(1<<13); | ||
| 3967 | bnx2x_cl45_write(bp, phy, | ||
| 3968 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | ||
| 3969 | |||
| 3970 | /* PLL controls */ | ||
| 3971 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); | ||
| 3972 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); | ||
| 3973 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); | ||
| 3974 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); | ||
| 3975 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); | ||
| 3976 | |||
| 3977 | /* Tx Controls */ | ||
| 3978 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); | ||
| 3979 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); | ||
| 3980 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); | ||
| 3981 | |||
| 3982 | /* Rx Controls */ | ||
| 3983 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); | ||
| 3984 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); | ||
| 3985 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); | ||
| 3986 | |||
| 3987 | /* Enable PLL sequencer (use read-modify-write to set bit 13) */ | ||
| 3988 | bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); | ||
| 3989 | val |= (1<<13); | ||
| 3990 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | ||
| 3991 | } | ||
| 3992 | |||
| 3993 | /******************************************************************/ | 3951 | /******************************************************************/ |
| 3994 | /* BCM8073 PHY SECTION */ | 3952 | /* BCM8073 PHY SECTION */ |
| 3995 | /******************************************************************/ | 3953 | /******************************************************************/ |
| @@ -4148,8 +4106,6 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
| 4148 | 4106 | ||
| 4149 | bnx2x_8073_set_pause_cl37(params, phy, vars); | 4107 | bnx2x_8073_set_pause_cl37(params, phy, vars); |
| 4150 | 4108 | ||
| 4151 | bnx2x_8073_set_xaui_low_power_mode(bp, phy); | ||
| 4152 | |||
| 4153 | bnx2x_cl45_read(bp, phy, | 4109 | bnx2x_cl45_read(bp, phy, |
| 4154 | MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); | 4110 | MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); |
| 4155 | 4111 | ||
| @@ -6519,6 +6475,18 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, | |||
| 6519 | MDIO_PMA_DEVAD, | 6475 | MDIO_PMA_DEVAD, |
| 6520 | MDIO_PMA_REG_8481_LED1_MASK, | 6476 | MDIO_PMA_REG_8481_LED1_MASK, |
| 6521 | 0x80); | 6477 | 0x80); |
| 6478 | |||
| 6479 | /* Tell LED3 to blink on source */ | ||
| 6480 | bnx2x_cl45_read(bp, phy, | ||
| 6481 | MDIO_PMA_DEVAD, | ||
| 6482 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
| 6483 | &val); | ||
| 6484 | val &= ~(7<<6); | ||
| 6485 | val |= (1<<6); /* A83B[8:6]= 1 */ | ||
| 6486 | bnx2x_cl45_write(bp, phy, | ||
| 6487 | MDIO_PMA_DEVAD, | ||
| 6488 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
| 6489 | val); | ||
| 6522 | } | 6490 | } |
| 6523 | break; | 6491 | break; |
| 6524 | } | 6492 | } |
| @@ -7720,10 +7688,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
| 7720 | struct bnx2x_phy phy[PORT_MAX]; | 7688 | struct bnx2x_phy phy[PORT_MAX]; |
| 7721 | struct bnx2x_phy *phy_blk[PORT_MAX]; | 7689 | struct bnx2x_phy *phy_blk[PORT_MAX]; |
| 7722 | u16 val; | 7690 | u16 val; |
| 7723 | s8 port; | 7691 | s8 port = 0; |
| 7724 | s8 port_of_path = 0; | 7692 | s8 port_of_path = 0; |
| 7725 | 7693 | u32 swap_val, swap_override; | |
| 7726 | bnx2x_ext_phy_hw_reset(bp, 0); | 7694 | swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); |
| 7695 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); | ||
| 7696 | port ^= (swap_val && swap_override); | ||
| 7697 | bnx2x_ext_phy_hw_reset(bp, port); | ||
| 7727 | /* PART1 - Reset both phys */ | 7698 | /* PART1 - Reset both phys */ |
| 7728 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7699 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
| 7729 | u32 shmem_base, shmem2_base; | 7700 | u32 shmem_base, shmem2_base; |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8cdcf5b39d1..d584d32c747 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
| @@ -2301,15 +2301,10 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) | |||
| 2301 | /* accept matched ucast */ | 2301 | /* accept matched ucast */ |
| 2302 | drop_all_ucast = 0; | 2302 | drop_all_ucast = 0; |
| 2303 | } | 2303 | } |
| 2304 | if (filters & BNX2X_ACCEPT_MULTICAST) { | 2304 | if (filters & BNX2X_ACCEPT_MULTICAST) |
| 2305 | /* accept matched mcast */ | 2305 | /* accept matched mcast */ |
| 2306 | drop_all_mcast = 0; | 2306 | drop_all_mcast = 0; |
| 2307 | if (IS_MF_SI(bp)) | 2307 | |
| 2308 | /* since mcast addresses won't arrive with ovlan, | ||
| 2309 | * fw needs to accept all of them in | ||
| 2310 | * switch-independent mode */ | ||
| 2311 | accp_all_mcast = 1; | ||
| 2312 | } | ||
| 2313 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { | 2308 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { |
| 2314 | /* accept all mcast */ | 2309 | /* accept all mcast */ |
| 2315 | drop_all_ucast = 0; | 2310 | drop_all_ucast = 0; |
| @@ -4281,9 +4276,12 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | |||
| 4281 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | | 4276 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | |
| 4282 | BNX2X_ACCEPT_MULTICAST; | 4277 | BNX2X_ACCEPT_MULTICAST; |
| 4283 | #ifdef BCM_CNIC | 4278 | #ifdef BCM_CNIC |
| 4284 | cl_id = bnx2x_fcoe(bp, cl_id); | 4279 | if (!NO_FCOE(bp)) { |
| 4285 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4280 | cl_id = bnx2x_fcoe(bp, cl_id); |
| 4286 | BNX2X_ACCEPT_MULTICAST); | 4281 | bnx2x_rxq_set_mac_filters(bp, cl_id, |
| 4282 | BNX2X_ACCEPT_UNICAST | | ||
| 4283 | BNX2X_ACCEPT_MULTICAST); | ||
| 4284 | } | ||
| 4287 | #endif | 4285 | #endif |
| 4288 | break; | 4286 | break; |
| 4289 | 4287 | ||
| @@ -4291,18 +4289,29 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | |||
| 4291 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | | 4289 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | |
| 4292 | BNX2X_ACCEPT_ALL_MULTICAST; | 4290 | BNX2X_ACCEPT_ALL_MULTICAST; |
| 4293 | #ifdef BCM_CNIC | 4291 | #ifdef BCM_CNIC |
| 4294 | cl_id = bnx2x_fcoe(bp, cl_id); | 4292 | /* |
| 4295 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4293 | * Prevent duplication of multicast packets by configuring FCoE |
| 4296 | BNX2X_ACCEPT_MULTICAST); | 4294 | * L2 Client to receive only matched unicast frames. |
| 4295 | */ | ||
| 4296 | if (!NO_FCOE(bp)) { | ||
| 4297 | cl_id = bnx2x_fcoe(bp, cl_id); | ||
| 4298 | bnx2x_rxq_set_mac_filters(bp, cl_id, | ||
| 4299 | BNX2X_ACCEPT_UNICAST); | ||
| 4300 | } | ||
| 4297 | #endif | 4301 | #endif |
| 4298 | break; | 4302 | break; |
| 4299 | 4303 | ||
| 4300 | case BNX2X_RX_MODE_PROMISC: | 4304 | case BNX2X_RX_MODE_PROMISC: |
| 4301 | def_q_filters |= BNX2X_PROMISCUOUS_MODE; | 4305 | def_q_filters |= BNX2X_PROMISCUOUS_MODE; |
| 4302 | #ifdef BCM_CNIC | 4306 | #ifdef BCM_CNIC |
| 4303 | cl_id = bnx2x_fcoe(bp, cl_id); | 4307 | /* |
| 4304 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4308 | * Prevent packets duplication by configuring DROP_ALL for FCoE |
| 4305 | BNX2X_ACCEPT_MULTICAST); | 4309 | * L2 Client. |
| 4310 | */ | ||
| 4311 | if (!NO_FCOE(bp)) { | ||
| 4312 | cl_id = bnx2x_fcoe(bp, cl_id); | ||
| 4313 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); | ||
| 4314 | } | ||
| 4306 | #endif | 4315 | #endif |
| 4307 | /* pass management unicast packets as well */ | 4316 | /* pass management unicast packets as well */ |
| 4308 | llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; | 4317 | llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; |
| @@ -5296,10 +5305,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
| 5296 | } | 5305 | } |
| 5297 | } | 5306 | } |
| 5298 | 5307 | ||
| 5299 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 5300 | bp->common.shmem_base, | ||
| 5301 | bp->common.shmem2_base); | ||
| 5302 | |||
| 5303 | bnx2x_setup_fan_failure_detection(bp); | 5308 | bnx2x_setup_fan_failure_detection(bp); |
| 5304 | 5309 | ||
| 5305 | /* clear PXP2 attentions */ | 5310 | /* clear PXP2 attentions */ |
| @@ -5503,9 +5508,6 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
| 5503 | 5508 | ||
| 5504 | bnx2x_init_block(bp, MCP_BLOCK, init_stage); | 5509 | bnx2x_init_block(bp, MCP_BLOCK, init_stage); |
| 5505 | bnx2x_init_block(bp, DMAE_BLOCK, init_stage); | 5510 | bnx2x_init_block(bp, DMAE_BLOCK, init_stage); |
| 5506 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 5507 | bp->common.shmem_base, | ||
| 5508 | bp->common.shmem2_base); | ||
| 5509 | if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, | 5511 | if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, |
| 5510 | bp->common.shmem2_base, port)) { | 5512 | bp->common.shmem2_base, port)) { |
| 5511 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : | 5513 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : |
| @@ -8379,6 +8381,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
| 8379 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) | 8381 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) |
| 8380 | bp->mdio.prtad = | 8382 | bp->mdio.prtad = |
| 8381 | XGXS_EXT_PHY_ADDR(ext_phy_config); | 8383 | XGXS_EXT_PHY_ADDR(ext_phy_config); |
| 8384 | |||
| 8385 | /* | ||
| 8386 | * Check if hw lock is required to access MDC/MDIO bus to the PHY(s) | ||
| 8387 | * In MF mode, it is set to cover self test cases | ||
| 8388 | */ | ||
| 8389 | if (IS_MF(bp)) | ||
| 8390 | bp->port.need_hw_lock = 1; | ||
| 8391 | else | ||
| 8392 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 8393 | bp->common.shmem_base, | ||
| 8394 | bp->common.shmem2_base); | ||
| 8382 | } | 8395 | } |
| 8383 | 8396 | ||
| 8384 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) | 8397 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 986195eaa57..5dec456fd4a 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
| @@ -23,7 +23,7 @@ config CAN_SLCAN | |||
| 23 | 23 | ||
| 24 | As only the sending and receiving of CAN frames is implemented, this | 24 | As only the sending and receiving of CAN frames is implemented, this |
| 25 | driver should work with the (serial/USB) CAN hardware from: | 25 | driver should work with the (serial/USB) CAN hardware from: |
| 26 | www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de | 26 | www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de |
| 27 | 27 | ||
| 28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, | 28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, |
| 29 | slcand) can be found in the can-utils at the SocketCAN SVN, see | 29 | slcand) can be found in the can-utils at the SocketCAN SVN, see |
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 2532b963153..57d2ffbbb43 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
| @@ -1109,7 +1109,7 @@ static ssize_t at91_sysfs_set_mb0_id(struct device *dev, | |||
| 1109 | return ret; | 1109 | return ret; |
| 1110 | } | 1110 | } |
| 1111 | 1111 | ||
| 1112 | static DEVICE_ATTR(mb0_id, S_IWUGO | S_IRUGO, | 1112 | static DEVICE_ATTR(mb0_id, S_IWUSR | S_IRUGO, |
| 1113 | at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id); | 1113 | at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id); |
| 1114 | 1114 | ||
| 1115 | static struct attribute *at91_sysfs_attrs[] = { | 1115 | static struct attribute *at91_sysfs_attrs[] = { |
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index b9a6d7a5a73..366f5cc050a 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
| @@ -1618,7 +1618,7 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, | |||
| 1618 | return count; | 1618 | return count; |
| 1619 | } | 1619 | } |
| 1620 | 1620 | ||
| 1621 | static DEVICE_ATTR(termination, S_IWUGO | S_IRUGO, ican3_sysfs_show_term, | 1621 | static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, |
| 1622 | ican3_sysfs_set_term); | 1622 | ican3_sysfs_set_term); |
| 1623 | 1623 | ||
| 1624 | static struct attribute *ican3_sysfs_attrs[] = { | 1624 | static struct attribute *ican3_sysfs_attrs[] = { |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7ab534aee45..7513c4523ac 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
| @@ -940,7 +940,7 @@ static int mcp251x_open(struct net_device *net) | |||
| 940 | goto open_unlock; | 940 | goto open_unlock; |
| 941 | } | 941 | } |
| 942 | 942 | ||
| 943 | priv->wq = create_freezeable_workqueue("mcp251x_wq"); | 943 | priv->wq = create_freezable_workqueue("mcp251x_wq"); |
| 944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); | 944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); |
| 945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); | 945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); |
| 946 | 946 | ||
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig index 27d1d398e25..d38706958af 100644 --- a/drivers/net/can/mscan/Kconfig +++ b/drivers/net/can/mscan/Kconfig | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | config CAN_MSCAN | 1 | config CAN_MSCAN |
| 2 | depends on CAN_DEV && (PPC || M68K || M68KNOMMU) | 2 | depends on CAN_DEV && (PPC || M68K) |
| 3 | tristate "Support for Freescale MSCAN based chips" | 3 | tristate "Support for Freescale MSCAN based chips" |
| 4 | ---help--- | 4 | ---help--- |
| 5 | The Motorola Scalable Controller Area Network (MSCAN) definition | 5 | The Motorola Scalable Controller Area Network (MSCAN) definition |
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c42e9726824..e54712b22c2 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
| @@ -185,7 +185,7 @@ struct pch_can_priv { | |||
| 185 | 185 | ||
| 186 | static struct can_bittiming_const pch_can_bittiming_const = { | 186 | static struct can_bittiming_const pch_can_bittiming_const = { |
| 187 | .name = KBUILD_MODNAME, | 187 | .name = KBUILD_MODNAME, |
| 188 | .tseg1_min = 1, | 188 | .tseg1_min = 2, |
| 189 | .tseg1_max = 16, | 189 | .tseg1_max = 16, |
| 190 | .tseg2_min = 1, | 190 | .tseg2_min = 1, |
| 191 | .tseg2_max = 8, | 191 | .tseg2_max = 8, |
| @@ -959,13 +959,13 @@ static void __devexit pch_can_remove(struct pci_dev *pdev) | |||
| 959 | struct pch_can_priv *priv = netdev_priv(ndev); | 959 | struct pch_can_priv *priv = netdev_priv(ndev); |
| 960 | 960 | ||
| 961 | unregister_candev(priv->ndev); | 961 | unregister_candev(priv->ndev); |
| 962 | pci_iounmap(pdev, priv->regs); | ||
| 963 | if (priv->use_msi) | 962 | if (priv->use_msi) |
| 964 | pci_disable_msi(priv->dev); | 963 | pci_disable_msi(priv->dev); |
| 965 | pci_release_regions(pdev); | 964 | pci_release_regions(pdev); |
| 966 | pci_disable_device(pdev); | 965 | pci_disable_device(pdev); |
| 967 | pci_set_drvdata(pdev, NULL); | 966 | pci_set_drvdata(pdev, NULL); |
| 968 | pch_can_reset(priv); | 967 | pch_can_reset(priv); |
| 968 | pci_iounmap(pdev, priv->regs); | ||
| 969 | free_candev(priv->ndev); | 969 | free_candev(priv->ndev); |
| 970 | } | 970 | } |
| 971 | 971 | ||
| @@ -1238,6 +1238,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, | |||
| 1238 | priv->use_msi = 0; | 1238 | priv->use_msi = 0; |
| 1239 | } else { | 1239 | } else { |
| 1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); | 1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); |
| 1241 | pci_set_master(pdev); | ||
| 1241 | priv->use_msi = 1; | 1242 | priv->use_msi = 1; |
| 1242 | } | 1243 | } |
| 1243 | 1244 | ||
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig index 92bd6bdde5e..5de46a9a77b 100644 --- a/drivers/net/can/softing/Kconfig +++ b/drivers/net/can/softing/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config CAN_SOFTING | 1 | config CAN_SOFTING |
| 2 | tristate "Softing Gmbh CAN generic support" | 2 | tristate "Softing Gmbh CAN generic support" |
| 3 | depends on CAN_DEV | 3 | depends on CAN_DEV && HAS_IOMEM |
| 4 | ---help--- | 4 | ---help--- |
| 5 | Support for CAN cards from Softing Gmbh & some cards | 5 | Support for CAN cards from Softing Gmbh & some cards |
| 6 | from Vector Gmbh. | 6 | from Vector Gmbh. |
| @@ -18,7 +18,7 @@ config CAN_SOFTING | |||
| 18 | config CAN_SOFTING_CS | 18 | config CAN_SOFTING_CS |
| 19 | tristate "Softing Gmbh CAN pcmcia cards" | 19 | tristate "Softing Gmbh CAN pcmcia cards" |
| 20 | depends on PCMCIA | 20 | depends on PCMCIA |
| 21 | select CAN_SOFTING | 21 | depends on CAN_SOFTING |
| 22 | ---help--- | 22 | ---help--- |
| 23 | Support for PCMCIA cards from Softing Gmbh & some cards | 23 | Support for PCMCIA cards from Softing Gmbh & some cards |
| 24 | from Vector Gmbh. | 24 | from Vector Gmbh. |
diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c index 300fe75dd1a..c11bb4de863 100644 --- a/drivers/net/can/softing/softing_cs.c +++ b/drivers/net/can/softing/softing_cs.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/slab.h> | ||
| 22 | 23 | ||
| 23 | #include <pcmcia/cistpl.h> | 24 | #include <pcmcia/cistpl.h> |
| 24 | #include <pcmcia/ds.h> | 25 | #include <pcmcia/ds.h> |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 56166ae2059..6aad64df4dc 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -2040,7 +2040,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) | |||
| 2040 | { | 2040 | { |
| 2041 | int i; | 2041 | int i; |
| 2042 | 2042 | ||
| 2043 | BUG_ON(adapter->debugfs_root == NULL); | 2043 | BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); |
| 2044 | 2044 | ||
| 2045 | /* | 2045 | /* |
| 2046 | * Debugfs support is best effort. | 2046 | * Debugfs support is best effort. |
| @@ -2061,7 +2061,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) | |||
| 2061 | */ | 2061 | */ |
| 2062 | static void cleanup_debugfs(struct adapter *adapter) | 2062 | static void cleanup_debugfs(struct adapter *adapter) |
| 2063 | { | 2063 | { |
| 2064 | BUG_ON(adapter->debugfs_root == NULL); | 2064 | BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); |
| 2065 | 2065 | ||
| 2066 | /* | 2066 | /* |
| 2067 | * Unlike our sister routine cleanup_proc(), we don't need to remove | 2067 | * Unlike our sister routine cleanup_proc(), we don't need to remove |
| @@ -2489,17 +2489,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2489 | struct net_device *netdev; | 2489 | struct net_device *netdev; |
| 2490 | 2490 | ||
| 2491 | /* | 2491 | /* |
| 2492 | * Vet our module parameters. | ||
| 2493 | */ | ||
| 2494 | if (msi != MSI_MSIX && msi != MSI_MSI) { | ||
| 2495 | dev_err(&pdev->dev, "bad module parameter msi=%d; must be %d" | ||
| 2496 | " (MSI-X or MSI) or %d (MSI)\n", msi, MSI_MSIX, | ||
| 2497 | MSI_MSI); | ||
| 2498 | err = -EINVAL; | ||
| 2499 | goto err_out; | ||
| 2500 | } | ||
| 2501 | |||
| 2502 | /* | ||
| 2503 | * Print our driver banner the first time we're called to initialize a | 2492 | * Print our driver banner the first time we're called to initialize a |
| 2504 | * device. | 2493 | * device. |
| 2505 | */ | 2494 | */ |
| @@ -2711,11 +2700,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2711 | /* | 2700 | /* |
| 2712 | * Set up our debugfs entries. | 2701 | * Set up our debugfs entries. |
| 2713 | */ | 2702 | */ |
| 2714 | if (cxgb4vf_debugfs_root) { | 2703 | if (!IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) { |
| 2715 | adapter->debugfs_root = | 2704 | adapter->debugfs_root = |
| 2716 | debugfs_create_dir(pci_name(pdev), | 2705 | debugfs_create_dir(pci_name(pdev), |
| 2717 | cxgb4vf_debugfs_root); | 2706 | cxgb4vf_debugfs_root); |
| 2718 | if (adapter->debugfs_root == NULL) | 2707 | if (IS_ERR_OR_NULL(adapter->debugfs_root)) |
| 2719 | dev_warn(&pdev->dev, "could not create debugfs" | 2708 | dev_warn(&pdev->dev, "could not create debugfs" |
| 2720 | " directory"); | 2709 | " directory"); |
| 2721 | else | 2710 | else |
| @@ -2770,7 +2759,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2770 | */ | 2759 | */ |
| 2771 | 2760 | ||
| 2772 | err_free_debugfs: | 2761 | err_free_debugfs: |
| 2773 | if (adapter->debugfs_root) { | 2762 | if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { |
| 2774 | cleanup_debugfs(adapter); | 2763 | cleanup_debugfs(adapter); |
| 2775 | debugfs_remove_recursive(adapter->debugfs_root); | 2764 | debugfs_remove_recursive(adapter->debugfs_root); |
| 2776 | } | 2765 | } |
| @@ -2802,7 +2791,6 @@ err_release_regions: | |||
| 2802 | err_disable_device: | 2791 | err_disable_device: |
| 2803 | pci_disable_device(pdev); | 2792 | pci_disable_device(pdev); |
| 2804 | 2793 | ||
| 2805 | err_out: | ||
| 2806 | return err; | 2794 | return err; |
| 2807 | } | 2795 | } |
| 2808 | 2796 | ||
| @@ -2840,7 +2828,7 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) | |||
| 2840 | /* | 2828 | /* |
| 2841 | * Tear down our debugfs entries. | 2829 | * Tear down our debugfs entries. |
| 2842 | */ | 2830 | */ |
| 2843 | if (adapter->debugfs_root) { | 2831 | if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { |
| 2844 | cleanup_debugfs(adapter); | 2832 | cleanup_debugfs(adapter); |
| 2845 | debugfs_remove_recursive(adapter->debugfs_root); | 2833 | debugfs_remove_recursive(adapter->debugfs_root); |
| 2846 | } | 2834 | } |
| @@ -2874,6 +2862,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) | |||
| 2874 | } | 2862 | } |
| 2875 | 2863 | ||
| 2876 | /* | 2864 | /* |
| 2865 | * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt | ||
| 2866 | * delivery. | ||
| 2867 | */ | ||
| 2868 | static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev) | ||
| 2869 | { | ||
| 2870 | struct adapter *adapter; | ||
| 2871 | int pidx; | ||
| 2872 | |||
| 2873 | adapter = pci_get_drvdata(pdev); | ||
| 2874 | if (!adapter) | ||
| 2875 | return; | ||
| 2876 | |||
| 2877 | /* | ||
| 2878 | * Disable all Virtual Interfaces. This will shut down the | ||
| 2879 | * delivery of all ingress packets into the chip for these | ||
| 2880 | * Virtual Interfaces. | ||
| 2881 | */ | ||
| 2882 | for_each_port(adapter, pidx) { | ||
| 2883 | struct net_device *netdev; | ||
| 2884 | struct port_info *pi; | ||
| 2885 | |||
| 2886 | if (!test_bit(pidx, &adapter->registered_device_map)) | ||
| 2887 | continue; | ||
| 2888 | |||
| 2889 | netdev = adapter->port[pidx]; | ||
| 2890 | if (!netdev) | ||
| 2891 | continue; | ||
| 2892 | |||
| 2893 | pi = netdev_priv(netdev); | ||
| 2894 | t4vf_enable_vi(adapter, pi->viid, false, false); | ||
| 2895 | } | ||
| 2896 | |||
| 2897 | /* | ||
| 2898 | * Free up all Queues which will prevent further DMA and | ||
| 2899 | * Interrupts allowing various internal pathways to drain. | ||
| 2900 | */ | ||
| 2901 | t4vf_free_sge_resources(adapter); | ||
| 2902 | } | ||
| 2903 | |||
| 2904 | /* | ||
| 2877 | * PCI Device registration data structures. | 2905 | * PCI Device registration data structures. |
| 2878 | */ | 2906 | */ |
| 2879 | #define CH_DEVICE(devid, idx) \ | 2907 | #define CH_DEVICE(devid, idx) \ |
| @@ -2906,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = { | |||
| 2906 | .id_table = cxgb4vf_pci_tbl, | 2934 | .id_table = cxgb4vf_pci_tbl, |
| 2907 | .probe = cxgb4vf_pci_probe, | 2935 | .probe = cxgb4vf_pci_probe, |
| 2908 | .remove = __devexit_p(cxgb4vf_pci_remove), | 2936 | .remove = __devexit_p(cxgb4vf_pci_remove), |
| 2937 | .shutdown = __devexit_p(cxgb4vf_pci_shutdown), | ||
| 2909 | }; | 2938 | }; |
| 2910 | 2939 | ||
| 2911 | /* | 2940 | /* |
| @@ -2915,14 +2944,25 @@ static int __init cxgb4vf_module_init(void) | |||
| 2915 | { | 2944 | { |
| 2916 | int ret; | 2945 | int ret; |
| 2917 | 2946 | ||
| 2947 | /* | ||
| 2948 | * Vet our module parameters. | ||
| 2949 | */ | ||
| 2950 | if (msi != MSI_MSIX && msi != MSI_MSI) { | ||
| 2951 | printk(KERN_WARNING KBUILD_MODNAME | ||
| 2952 | ": bad module parameter msi=%d; must be %d" | ||
| 2953 | " (MSI-X or MSI) or %d (MSI)\n", | ||
| 2954 | msi, MSI_MSIX, MSI_MSI); | ||
| 2955 | return -EINVAL; | ||
| 2956 | } | ||
| 2957 | |||
| 2918 | /* Debugfs support is optional, just warn if this fails */ | 2958 | /* Debugfs support is optional, just warn if this fails */ |
| 2919 | cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | 2959 | cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); |
| 2920 | if (!cxgb4vf_debugfs_root) | 2960 | if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) |
| 2921 | printk(KERN_WARNING KBUILD_MODNAME ": could not create" | 2961 | printk(KERN_WARNING KBUILD_MODNAME ": could not create" |
| 2922 | " debugfs entry, continuing\n"); | 2962 | " debugfs entry, continuing\n"); |
| 2923 | 2963 | ||
| 2924 | ret = pci_register_driver(&cxgb4vf_driver); | 2964 | ret = pci_register_driver(&cxgb4vf_driver); |
| 2925 | if (ret < 0) | 2965 | if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) |
| 2926 | debugfs_remove(cxgb4vf_debugfs_root); | 2966 | debugfs_remove(cxgb4vf_debugfs_root); |
| 2927 | return ret; | 2967 | return ret; |
| 2928 | } | 2968 | } |
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 0f51c80475c..192db226ec7 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c | |||
| @@ -171,7 +171,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, | |||
| 171 | delay_idx = 0; | 171 | delay_idx = 0; |
| 172 | ms = delay[0]; | 172 | ms = delay[0]; |
| 173 | 173 | ||
| 174 | for (i = 0; i < 500; i += ms) { | 174 | for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) { |
| 175 | if (sleep_ok) { | 175 | if (sleep_ok) { |
| 176 | ms = delay[delay_idx]; | 176 | ms = delay[delay_idx]; |
| 177 | if (delay_idx < ARRAY_SIZE(delay) - 1) | 177 | if (delay_idx < ARRAY_SIZE(delay) - 1) |
diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 1b48b68ad4f..8b0084d17c8 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c | |||
| @@ -1094,7 +1094,7 @@ static int depca_rx(struct net_device *dev) | |||
| 1094 | } | 1094 | } |
| 1095 | } | 1095 | } |
| 1096 | /* Change buffer ownership for this last frame, back to the adapter */ | 1096 | /* Change buffer ownership for this last frame, back to the adapter */ |
| 1097 | for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) & lp->rxRingMask) { | 1097 | for (; lp->rx_old != entry; lp->rx_old = (lp->rx_old + 1) & lp->rxRingMask) { |
| 1098 | writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base); | 1098 | writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base); |
| 1099 | } | 1099 | } |
| 1100 | writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base); | 1100 | writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base); |
| @@ -1103,7 +1103,7 @@ static int depca_rx(struct net_device *dev) | |||
| 1103 | /* | 1103 | /* |
| 1104 | ** Update entry information | 1104 | ** Update entry information |
| 1105 | */ | 1105 | */ |
| 1106 | lp->rx_new = (++lp->rx_new) & lp->rxRingMask; | 1106 | lp->rx_new = (lp->rx_new + 1) & lp->rxRingMask; |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | return 0; | 1109 | return 0; |
| @@ -1148,7 +1148,7 @@ static int depca_tx(struct net_device *dev) | |||
| 1148 | } | 1148 | } |
| 1149 | 1149 | ||
| 1150 | /* Update all the pointers */ | 1150 | /* Update all the pointers */ |
| 1151 | lp->tx_old = (++lp->tx_old) & lp->txRingMask; | 1151 | lp->tx_old = (lp->tx_old + 1) & lp->txRingMask; |
| 1152 | } | 1152 | } |
| 1153 | 1153 | ||
| 1154 | return 0; | 1154 | return 0; |
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index e1a8216ff69..c05db604605 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c | |||
| @@ -1753,8 +1753,6 @@ rio_close (struct net_device *dev) | |||
| 1753 | 1753 | ||
| 1754 | /* Free all the skbuffs in the queue. */ | 1754 | /* Free all the skbuffs in the queue. */ |
| 1755 | for (i = 0; i < RX_RING_SIZE; i++) { | 1755 | for (i = 0; i < RX_RING_SIZE; i++) { |
| 1756 | np->rx_ring[i].status = 0; | ||
| 1757 | np->rx_ring[i].fraginfo = 0; | ||
| 1758 | skb = np->rx_skbuff[i]; | 1756 | skb = np->rx_skbuff[i]; |
| 1759 | if (skb) { | 1757 | if (skb) { |
| 1760 | pci_unmap_single(np->pdev, | 1758 | pci_unmap_single(np->pdev, |
| @@ -1763,6 +1761,8 @@ rio_close (struct net_device *dev) | |||
| 1763 | dev_kfree_skb (skb); | 1761 | dev_kfree_skb (skb); |
| 1764 | np->rx_skbuff[i] = NULL; | 1762 | np->rx_skbuff[i] = NULL; |
| 1765 | } | 1763 | } |
| 1764 | np->rx_ring[i].status = 0; | ||
| 1765 | np->rx_ring[i].fraginfo = 0; | ||
| 1766 | } | 1766 | } |
| 1767 | for (i = 0; i < TX_RING_SIZE; i++) { | 1767 | for (i = 0; i < TX_RING_SIZE; i++) { |
| 1768 | skb = np->tx_skbuff[i]; | 1768 | skb = np->tx_skbuff[i]; |
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index aed223b1b89..7501d977d99 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c | |||
| @@ -124,6 +124,7 @@ static s32 e1000_set_phy_type(struct e1000_hw *hw) | |||
| 124 | case M88E1000_I_PHY_ID: | 124 | case M88E1000_I_PHY_ID: |
| 125 | case M88E1011_I_PHY_ID: | 125 | case M88E1011_I_PHY_ID: |
| 126 | case M88E1111_I_PHY_ID: | 126 | case M88E1111_I_PHY_ID: |
| 127 | case M88E1118_E_PHY_ID: | ||
| 127 | hw->phy_type = e1000_phy_m88; | 128 | hw->phy_type = e1000_phy_m88; |
| 128 | break; | 129 | break; |
| 129 | case IGP01E1000_I_PHY_ID: | 130 | case IGP01E1000_I_PHY_ID: |
| @@ -3222,7 +3223,8 @@ static s32 e1000_detect_gig_phy(struct e1000_hw *hw) | |||
| 3222 | break; | 3223 | break; |
| 3223 | case e1000_ce4100: | 3224 | case e1000_ce4100: |
| 3224 | if ((hw->phy_id == RTL8211B_PHY_ID) || | 3225 | if ((hw->phy_id == RTL8211B_PHY_ID) || |
| 3225 | (hw->phy_id == RTL8201N_PHY_ID)) | 3226 | (hw->phy_id == RTL8201N_PHY_ID) || |
| 3227 | (hw->phy_id == M88E1118_E_PHY_ID)) | ||
| 3226 | match = true; | 3228 | match = true; |
| 3227 | break; | 3229 | break; |
| 3228 | case e1000_82541: | 3230 | case e1000_82541: |
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 196eeda2dd6..c70b23d5228 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
| @@ -2917,6 +2917,7 @@ struct e1000_host_command_info { | |||
| 2917 | #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID | 2917 | #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID |
| 2918 | #define M88E1011_I_REV_4 0x04 | 2918 | #define M88E1011_I_REV_4 0x04 |
| 2919 | #define M88E1111_I_PHY_ID 0x01410CC0 | 2919 | #define M88E1111_I_PHY_ID 0x01410CC0 |
| 2920 | #define M88E1118_E_PHY_ID 0x01410E40 | ||
| 2920 | #define L1LXT971A_PHY_ID 0x001378E0 | 2921 | #define L1LXT971A_PHY_ID 0x001378E0 |
| 2921 | 2922 | ||
| 2922 | #define RTL8211B_PHY_ID 0x001CC910 | 2923 | #define RTL8211B_PHY_ID 0x001CC910 |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1c18f26b081..3fa110ddb04 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -937,6 +937,9 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
| 937 | u16 phy_status, phy_1000t_status, phy_ext_status; | 937 | u16 phy_status, phy_1000t_status, phy_ext_status; |
| 938 | u16 pci_status; | 938 | u16 pci_status; |
| 939 | 939 | ||
| 940 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 941 | return; | ||
| 942 | |||
| 940 | e1e_rphy(hw, PHY_STATUS, &phy_status); | 943 | e1e_rphy(hw, PHY_STATUS, &phy_status); |
| 941 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); | 944 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); |
| 942 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); | 945 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); |
| @@ -1506,6 +1509,9 @@ static void e1000e_downshift_workaround(struct work_struct *work) | |||
| 1506 | struct e1000_adapter *adapter = container_of(work, | 1509 | struct e1000_adapter *adapter = container_of(work, |
| 1507 | struct e1000_adapter, downshift_task); | 1510 | struct e1000_adapter, downshift_task); |
| 1508 | 1511 | ||
| 1512 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 1513 | return; | ||
| 1514 | |||
| 1509 | e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); | 1515 | e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); |
| 1510 | } | 1516 | } |
| 1511 | 1517 | ||
| @@ -3338,6 +3344,21 @@ int e1000e_up(struct e1000_adapter *adapter) | |||
| 3338 | return 0; | 3344 | return 0; |
| 3339 | } | 3345 | } |
| 3340 | 3346 | ||
| 3347 | static void e1000e_flush_descriptors(struct e1000_adapter *adapter) | ||
| 3348 | { | ||
| 3349 | struct e1000_hw *hw = &adapter->hw; | ||
| 3350 | |||
| 3351 | if (!(adapter->flags2 & FLAG2_DMA_BURST)) | ||
| 3352 | return; | ||
| 3353 | |||
| 3354 | /* flush pending descriptor writebacks to memory */ | ||
| 3355 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
| 3356 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
| 3357 | |||
| 3358 | /* execute the writes immediately */ | ||
| 3359 | e1e_flush(); | ||
| 3360 | } | ||
| 3361 | |||
| 3341 | void e1000e_down(struct e1000_adapter *adapter) | 3362 | void e1000e_down(struct e1000_adapter *adapter) |
| 3342 | { | 3363 | { |
| 3343 | struct net_device *netdev = adapter->netdev; | 3364 | struct net_device *netdev = adapter->netdev; |
| @@ -3377,6 +3398,9 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
| 3377 | 3398 | ||
| 3378 | if (!pci_channel_offline(adapter->pdev)) | 3399 | if (!pci_channel_offline(adapter->pdev)) |
| 3379 | e1000e_reset(adapter); | 3400 | e1000e_reset(adapter); |
| 3401 | |||
| 3402 | e1000e_flush_descriptors(adapter); | ||
| 3403 | |||
| 3380 | e1000_clean_tx_ring(adapter); | 3404 | e1000_clean_tx_ring(adapter); |
| 3381 | e1000_clean_rx_ring(adapter); | 3405 | e1000_clean_rx_ring(adapter); |
| 3382 | 3406 | ||
| @@ -3765,6 +3789,10 @@ static void e1000e_update_phy_task(struct work_struct *work) | |||
| 3765 | { | 3789 | { |
| 3766 | struct e1000_adapter *adapter = container_of(work, | 3790 | struct e1000_adapter *adapter = container_of(work, |
| 3767 | struct e1000_adapter, update_phy_task); | 3791 | struct e1000_adapter, update_phy_task); |
| 3792 | |||
| 3793 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 3794 | return; | ||
| 3795 | |||
| 3768 | e1000_get_phy_info(&adapter->hw); | 3796 | e1000_get_phy_info(&adapter->hw); |
| 3769 | } | 3797 | } |
| 3770 | 3798 | ||
| @@ -3775,6 +3803,10 @@ static void e1000e_update_phy_task(struct work_struct *work) | |||
| 3775 | static void e1000_update_phy_info(unsigned long data) | 3803 | static void e1000_update_phy_info(unsigned long data) |
| 3776 | { | 3804 | { |
| 3777 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; | 3805 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; |
| 3806 | |||
| 3807 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 3808 | return; | ||
| 3809 | |||
| 3778 | schedule_work(&adapter->update_phy_task); | 3810 | schedule_work(&adapter->update_phy_task); |
| 3779 | } | 3811 | } |
| 3780 | 3812 | ||
| @@ -4149,6 +4181,9 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
| 4149 | u32 link, tctl; | 4181 | u32 link, tctl; |
| 4150 | int tx_pending = 0; | 4182 | int tx_pending = 0; |
| 4151 | 4183 | ||
| 4184 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 4185 | return; | ||
| 4186 | |||
| 4152 | link = e1000e_has_link(adapter); | 4187 | link = e1000e_has_link(adapter); |
| 4153 | if ((netif_carrier_ok(netdev)) && link) { | 4188 | if ((netif_carrier_ok(netdev)) && link) { |
| 4154 | /* Cancel scheduled suspend requests. */ | 4189 | /* Cancel scheduled suspend requests. */ |
| @@ -4309,7 +4344,6 @@ link_up: | |||
| 4309 | * to get done, so reset controller to flush Tx. | 4344 | * to get done, so reset controller to flush Tx. |
| 4310 | * (Do the reset outside of interrupt context). | 4345 | * (Do the reset outside of interrupt context). |
| 4311 | */ | 4346 | */ |
| 4312 | adapter->tx_timeout_count++; | ||
| 4313 | schedule_work(&adapter->reset_task); | 4347 | schedule_work(&adapter->reset_task); |
| 4314 | /* return immediately since reset is imminent */ | 4348 | /* return immediately since reset is imminent */ |
| 4315 | return; | 4349 | return; |
| @@ -4338,19 +4372,12 @@ link_up: | |||
| 4338 | else | 4372 | else |
| 4339 | ew32(ICS, E1000_ICS_RXDMT0); | 4373 | ew32(ICS, E1000_ICS_RXDMT0); |
| 4340 | 4374 | ||
| 4375 | /* flush pending descriptors to memory before detecting Tx hang */ | ||
| 4376 | e1000e_flush_descriptors(adapter); | ||
| 4377 | |||
| 4341 | /* Force detection of hung controller every watchdog period */ | 4378 | /* Force detection of hung controller every watchdog period */ |
| 4342 | adapter->detect_tx_hung = 1; | 4379 | adapter->detect_tx_hung = 1; |
| 4343 | 4380 | ||
| 4344 | /* flush partial descriptors to memory before detecting Tx hang */ | ||
| 4345 | if (adapter->flags2 & FLAG2_DMA_BURST) { | ||
| 4346 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
| 4347 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
| 4348 | /* | ||
| 4349 | * no need to flush the writes because the timeout code does | ||
| 4350 | * an er32 first thing | ||
| 4351 | */ | ||
| 4352 | } | ||
| 4353 | |||
| 4354 | /* | 4381 | /* |
| 4355 | * With 82571 controllers, LAA may be overwritten due to controller | 4382 | * With 82571 controllers, LAA may be overwritten due to controller |
| 4356 | * reset from the other port. Set the appropriate LAA in RAR[0] | 4383 | * reset from the other port. Set the appropriate LAA in RAR[0] |
| @@ -4888,6 +4915,10 @@ static void e1000_reset_task(struct work_struct *work) | |||
| 4888 | struct e1000_adapter *adapter; | 4915 | struct e1000_adapter *adapter; |
| 4889 | adapter = container_of(work, struct e1000_adapter, reset_task); | 4916 | adapter = container_of(work, struct e1000_adapter, reset_task); |
| 4890 | 4917 | ||
| 4918 | /* don't run the task if already down */ | ||
| 4919 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 4920 | return; | ||
| 4921 | |||
| 4891 | if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && | 4922 | if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && |
| 4892 | (adapter->flags & FLAG_RX_RESTART_NOW))) { | 4923 | (adapter->flags & FLAG_RX_RESTART_NOW))) { |
| 4893 | e1000e_dump(adapter); | 4924 | e1000e_dump(adapter); |
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 112c5aa9af7..907b05a1c65 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c | |||
| @@ -812,7 +812,7 @@ static void enc28j60_read_tsv(struct enc28j60_net *priv, u8 tsv[TSV_SIZE]) | |||
| 812 | if (netif_msg_hw(priv)) | 812 | if (netif_msg_hw(priv)) |
| 813 | printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n", | 813 | printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n", |
| 814 | endptr + 1); | 814 | endptr + 1); |
| 815 | enc28j60_mem_read(priv, endptr + 1, sizeof(tsv), tsv); | 815 | enc28j60_mem_read(priv, endptr + 1, TSV_SIZE, tsv); |
| 816 | } | 816 | } |
| 817 | 817 | ||
| 818 | static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg, | 818 | static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg, |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index af09296ef0d..9c0b1bac6af 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -5645,6 +5645,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 5645 | goto out_error; | 5645 | goto out_error; |
| 5646 | } | 5646 | } |
| 5647 | 5647 | ||
| 5648 | netif_carrier_off(dev); | ||
| 5649 | |||
| 5648 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", | 5650 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", |
| 5649 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); | 5651 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); |
| 5650 | 5652 | ||
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index d5ede2df3e4..ebbda7d1525 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
| @@ -1370,6 +1370,9 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) | |||
| 1370 | hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); | 1370 | hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); |
| 1371 | 1371 | ||
| 1372 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | 1372 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); |
| 1373 | |||
| 1374 | /* clear VMDq pool/queue selection for RAR 0 */ | ||
| 1375 | hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); | ||
| 1373 | } | 1376 | } |
| 1374 | hw->addr_ctrl.overflow_promisc = 0; | 1377 | hw->addr_ctrl.overflow_promisc = 0; |
| 1375 | 1378 | ||
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 6342d485979..c54a88274d5 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
| @@ -159,13 +159,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
| 159 | struct scatterlist *sg; | 159 | struct scatterlist *sg; |
| 160 | unsigned int i, j, dmacount; | 160 | unsigned int i, j, dmacount; |
| 161 | unsigned int len; | 161 | unsigned int len; |
| 162 | static const unsigned int bufflen = 4096; | 162 | static const unsigned int bufflen = IXGBE_FCBUFF_MIN; |
| 163 | unsigned int firstoff = 0; | 163 | unsigned int firstoff = 0; |
| 164 | unsigned int lastsize; | 164 | unsigned int lastsize; |
| 165 | unsigned int thisoff = 0; | 165 | unsigned int thisoff = 0; |
| 166 | unsigned int thislen = 0; | 166 | unsigned int thislen = 0; |
| 167 | u32 fcbuff, fcdmarw, fcfltrw; | 167 | u32 fcbuff, fcdmarw, fcfltrw; |
| 168 | dma_addr_t addr; | 168 | dma_addr_t addr = 0; |
| 169 | 169 | ||
| 170 | if (!netdev || !sgl) | 170 | if (!netdev || !sgl) |
| 171 | return 0; | 171 | return 0; |
| @@ -254,6 +254,24 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
| 254 | /* only the last buffer may have non-full bufflen */ | 254 | /* only the last buffer may have non-full bufflen */ |
| 255 | lastsize = thisoff + thislen; | 255 | lastsize = thisoff + thislen; |
| 256 | 256 | ||
| 257 | /* | ||
| 258 | * lastsize can not be buffer len. | ||
| 259 | * If it is then adding another buffer with lastsize = 1. | ||
| 260 | */ | ||
| 261 | if (lastsize == bufflen) { | ||
| 262 | if (j >= IXGBE_BUFFCNT_MAX) { | ||
| 263 | e_err(drv, "xid=%x:%d,%d,%d:addr=%llx " | ||
| 264 | "not enough user buffers. We need an extra " | ||
| 265 | "buffer because lastsize is bufflen.\n", | ||
| 266 | xid, i, j, dmacount, (u64)addr); | ||
| 267 | goto out_noddp_free; | ||
| 268 | } | ||
| 269 | |||
| 270 | ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma); | ||
| 271 | j++; | ||
| 272 | lastsize = 1; | ||
| 273 | } | ||
| 274 | |||
| 257 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); | 275 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); |
| 258 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); | 276 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); |
| 259 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); | 277 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); |
| @@ -532,6 +550,24 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
| 532 | e_err(drv, "failed to allocated FCoE DDP pool\n"); | 550 | e_err(drv, "failed to allocated FCoE DDP pool\n"); |
| 533 | 551 | ||
| 534 | spin_lock_init(&fcoe->lock); | 552 | spin_lock_init(&fcoe->lock); |
| 553 | |||
| 554 | /* Extra buffer to be shared by all DDPs for HW work around */ | ||
| 555 | fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); | ||
| 556 | if (fcoe->extra_ddp_buffer == NULL) { | ||
| 557 | e_err(drv, "failed to allocated extra DDP buffer\n"); | ||
| 558 | goto out_extra_ddp_buffer_alloc; | ||
| 559 | } | ||
| 560 | |||
| 561 | fcoe->extra_ddp_buffer_dma = | ||
| 562 | dma_map_single(&adapter->pdev->dev, | ||
| 563 | fcoe->extra_ddp_buffer, | ||
| 564 | IXGBE_FCBUFF_MIN, | ||
| 565 | DMA_FROM_DEVICE); | ||
| 566 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 567 | fcoe->extra_ddp_buffer_dma)) { | ||
| 568 | e_err(drv, "failed to map extra DDP buffer\n"); | ||
| 569 | goto out_extra_ddp_buffer_dma; | ||
| 570 | } | ||
| 535 | } | 571 | } |
| 536 | 572 | ||
| 537 | /* Enable L2 eth type filter for FCoE */ | 573 | /* Enable L2 eth type filter for FCoE */ |
| @@ -581,6 +617,14 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
| 581 | } | 617 | } |
| 582 | } | 618 | } |
| 583 | #endif | 619 | #endif |
| 620 | |||
| 621 | return; | ||
| 622 | |||
| 623 | out_extra_ddp_buffer_dma: | ||
| 624 | kfree(fcoe->extra_ddp_buffer); | ||
| 625 | out_extra_ddp_buffer_alloc: | ||
| 626 | pci_pool_destroy(fcoe->pool); | ||
| 627 | fcoe->pool = NULL; | ||
| 584 | } | 628 | } |
| 585 | 629 | ||
| 586 | /** | 630 | /** |
| @@ -600,6 +644,11 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter) | |||
| 600 | if (fcoe->pool) { | 644 | if (fcoe->pool) { |
| 601 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) | 645 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) |
| 602 | ixgbe_fcoe_ddp_put(adapter->netdev, i); | 646 | ixgbe_fcoe_ddp_put(adapter->netdev, i); |
| 647 | dma_unmap_single(&adapter->pdev->dev, | ||
| 648 | fcoe->extra_ddp_buffer_dma, | ||
| 649 | IXGBE_FCBUFF_MIN, | ||
| 650 | DMA_FROM_DEVICE); | ||
| 651 | kfree(fcoe->extra_ddp_buffer); | ||
| 603 | pci_pool_destroy(fcoe->pool); | 652 | pci_pool_destroy(fcoe->pool); |
| 604 | fcoe->pool = NULL; | 653 | fcoe->pool = NULL; |
| 605 | } | 654 | } |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 4bc2c551c8d..65cc8fb14fe 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h | |||
| @@ -70,6 +70,8 @@ struct ixgbe_fcoe { | |||
| 70 | spinlock_t lock; | 70 | spinlock_t lock; |
| 71 | struct pci_pool *pool; | 71 | struct pci_pool *pool; |
| 72 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; | 72 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; |
| 73 | unsigned char *extra_ddp_buffer; | ||
| 74 | dma_addr_t extra_ddp_buffer_dma; | ||
| 73 | }; | 75 | }; |
| 74 | 76 | ||
| 75 | #endif /* _IXGBE_FCOE_H */ | 77 | #endif /* _IXGBE_FCOE_H */ |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 602078b8489..30f9ccfb4f8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -52,7 +52,7 @@ char ixgbe_driver_name[] = "ixgbe"; | |||
| 52 | static const char ixgbe_driver_string[] = | 52 | static const char ixgbe_driver_string[] = |
| 53 | "Intel(R) 10 Gigabit PCI Express Network Driver"; | 53 | "Intel(R) 10 Gigabit PCI Express Network Driver"; |
| 54 | 54 | ||
| 55 | #define DRV_VERSION "3.0.12-k2" | 55 | #define DRV_VERSION "3.2.9-k2" |
| 56 | const char ixgbe_driver_version[] = DRV_VERSION; | 56 | const char ixgbe_driver_version[] = DRV_VERSION; |
| 57 | static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; | 57 | static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; |
| 58 | 58 | ||
| @@ -3176,9 +3176,16 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) | |||
| 3176 | u32 mhadd, hlreg0; | 3176 | u32 mhadd, hlreg0; |
| 3177 | 3177 | ||
| 3178 | /* Decide whether to use packet split mode or not */ | 3178 | /* Decide whether to use packet split mode or not */ |
| 3179 | /* On by default */ | ||
| 3180 | adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; | ||
| 3181 | |||
| 3179 | /* Do not use packet split if we're in SR-IOV Mode */ | 3182 | /* Do not use packet split if we're in SR-IOV Mode */ |
| 3180 | if (!adapter->num_vfs) | 3183 | if (adapter->num_vfs) |
| 3181 | adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; | 3184 | adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; |
| 3185 | |||
| 3186 | /* Disable packet split due to 82599 erratum #45 */ | ||
| 3187 | if (hw->mac.type == ixgbe_mac_82599EB) | ||
| 3188 | adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; | ||
| 3182 | 3189 | ||
| 3183 | /* Set the RX buffer length according to the mode */ | 3190 | /* Set the RX buffer length according to the mode */ |
| 3184 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { | 3191 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { |
| @@ -3721,7 +3728,8 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) | |||
| 3721 | * We need to try and force an autonegotiation | 3728 | * We need to try and force an autonegotiation |
| 3722 | * session, then bring up link. | 3729 | * session, then bring up link. |
| 3723 | */ | 3730 | */ |
| 3724 | hw->mac.ops.setup_sfp(hw); | 3731 | if (hw->mac.ops.setup_sfp) |
| 3732 | hw->mac.ops.setup_sfp(hw); | ||
| 3725 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | 3733 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) |
| 3726 | schedule_work(&adapter->multispeed_fiber_task); | 3734 | schedule_work(&adapter->multispeed_fiber_task); |
| 3727 | } else { | 3735 | } else { |
| @@ -4863,16 +4871,13 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) | |||
| 4863 | { | 4871 | { |
| 4864 | int q_idx, num_q_vectors; | 4872 | int q_idx, num_q_vectors; |
| 4865 | struct ixgbe_q_vector *q_vector; | 4873 | struct ixgbe_q_vector *q_vector; |
| 4866 | int napi_vectors; | ||
| 4867 | int (*poll)(struct napi_struct *, int); | 4874 | int (*poll)(struct napi_struct *, int); |
| 4868 | 4875 | ||
| 4869 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | 4876 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { |
| 4870 | num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; | 4877 | num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; |
| 4871 | napi_vectors = adapter->num_rx_queues; | ||
| 4872 | poll = &ixgbe_clean_rxtx_many; | 4878 | poll = &ixgbe_clean_rxtx_many; |
| 4873 | } else { | 4879 | } else { |
| 4874 | num_q_vectors = 1; | 4880 | num_q_vectors = 1; |
| 4875 | napi_vectors = 1; | ||
| 4876 | poll = &ixgbe_poll; | 4881 | poll = &ixgbe_poll; |
| 4877 | } | 4882 | } |
| 4878 | 4883 | ||
| @@ -5964,7 +5969,8 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) | |||
| 5964 | unregister_netdev(adapter->netdev); | 5969 | unregister_netdev(adapter->netdev); |
| 5965 | return; | 5970 | return; |
| 5966 | } | 5971 | } |
| 5967 | hw->mac.ops.setup_sfp(hw); | 5972 | if (hw->mac.ops.setup_sfp) |
| 5973 | hw->mac.ops.setup_sfp(hw); | ||
| 5968 | 5974 | ||
| 5969 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | 5975 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) |
| 5970 | /* This will also work for DA Twinax connections */ | 5976 | /* This will also work for DA Twinax connections */ |
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 47b15738b00..187b3a16ec1 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c | |||
| @@ -110,12 +110,10 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, | |||
| 110 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); | 110 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | |||
| 114 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | 113 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) |
| 115 | { | 114 | { |
| 116 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); | 115 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); |
| 117 | vmolr |= (IXGBE_VMOLR_ROMPE | | 116 | vmolr |= (IXGBE_VMOLR_ROMPE | |
| 118 | IXGBE_VMOLR_ROPE | | ||
| 119 | IXGBE_VMOLR_BAM); | 117 | IXGBE_VMOLR_BAM); |
| 120 | if (aupe) | 118 | if (aupe) |
| 121 | vmolr |= IXGBE_VMOLR_AUPE; | 119 | vmolr |= IXGBE_VMOLR_AUPE; |
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 3a8923993ce..f2518b01067 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c | |||
| @@ -133,17 +133,17 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) | |||
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 135 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); |
| 136 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); | 136 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | reset_bit)); |
| 137 | IXGBE_WRITE_FLUSH(hw); | 137 | IXGBE_WRITE_FLUSH(hw); |
| 138 | 138 | ||
| 139 | /* Poll for reset bit to self-clear indicating reset is complete */ | 139 | /* Poll for reset bit to self-clear indicating reset is complete */ |
| 140 | for (i = 0; i < 10; i++) { | 140 | for (i = 0; i < 10; i++) { |
| 141 | udelay(1); | 141 | udelay(1); |
| 142 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 142 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); |
| 143 | if (!(ctrl & IXGBE_CTRL_RST)) | 143 | if (!(ctrl & reset_bit)) |
| 144 | break; | 144 | break; |
| 145 | } | 145 | } |
| 146 | if (ctrl & IXGBE_CTRL_RST) { | 146 | if (ctrl & reset_bit) { |
| 147 | status = IXGBE_ERR_RESET_FAILED; | 147 | status = IXGBE_ERR_RESET_FAILED; |
| 148 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 148 | hw_dbg(hw, "Reset polling failed to complete.\n"); |
| 149 | } | 149 | } |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2541321bad8..9fb59d3f9c9 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
| @@ -4489,6 +4489,9 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4489 | { | 4489 | { |
| 4490 | struct niu_parent *parent = np->parent; | 4490 | struct niu_parent *parent = np->parent; |
| 4491 | int first_rx_channel, first_tx_channel; | 4491 | int first_rx_channel, first_tx_channel; |
| 4492 | int num_rx_rings, num_tx_rings; | ||
| 4493 | struct rx_ring_info *rx_rings; | ||
| 4494 | struct tx_ring_info *tx_rings; | ||
| 4492 | int i, port, err; | 4495 | int i, port, err; |
| 4493 | 4496 | ||
| 4494 | port = np->port; | 4497 | port = np->port; |
| @@ -4498,18 +4501,21 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4498 | first_tx_channel += parent->txchan_per_port[i]; | 4501 | first_tx_channel += parent->txchan_per_port[i]; |
| 4499 | } | 4502 | } |
| 4500 | 4503 | ||
| 4501 | np->num_rx_rings = parent->rxchan_per_port[port]; | 4504 | num_rx_rings = parent->rxchan_per_port[port]; |
| 4502 | np->num_tx_rings = parent->txchan_per_port[port]; | 4505 | num_tx_rings = parent->txchan_per_port[port]; |
| 4503 | 4506 | ||
| 4504 | netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); | 4507 | rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), |
| 4505 | netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); | 4508 | GFP_KERNEL); |
| 4506 | |||
| 4507 | np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), | ||
| 4508 | GFP_KERNEL); | ||
| 4509 | err = -ENOMEM; | 4509 | err = -ENOMEM; |
| 4510 | if (!np->rx_rings) | 4510 | if (!rx_rings) |
| 4511 | goto out_err; | 4511 | goto out_err; |
| 4512 | 4512 | ||
| 4513 | np->num_rx_rings = num_rx_rings; | ||
| 4514 | smp_wmb(); | ||
| 4515 | np->rx_rings = rx_rings; | ||
| 4516 | |||
| 4517 | netif_set_real_num_rx_queues(np->dev, num_rx_rings); | ||
| 4518 | |||
| 4513 | for (i = 0; i < np->num_rx_rings; i++) { | 4519 | for (i = 0; i < np->num_rx_rings; i++) { |
| 4514 | struct rx_ring_info *rp = &np->rx_rings[i]; | 4520 | struct rx_ring_info *rp = &np->rx_rings[i]; |
| 4515 | 4521 | ||
| @@ -4538,12 +4544,18 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4538 | return err; | 4544 | return err; |
| 4539 | } | 4545 | } |
| 4540 | 4546 | ||
| 4541 | np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), | 4547 | tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), |
| 4542 | GFP_KERNEL); | 4548 | GFP_KERNEL); |
| 4543 | err = -ENOMEM; | 4549 | err = -ENOMEM; |
| 4544 | if (!np->tx_rings) | 4550 | if (!tx_rings) |
| 4545 | goto out_err; | 4551 | goto out_err; |
| 4546 | 4552 | ||
| 4553 | np->num_tx_rings = num_tx_rings; | ||
| 4554 | smp_wmb(); | ||
| 4555 | np->tx_rings = tx_rings; | ||
| 4556 | |||
| 4557 | netif_set_real_num_tx_queues(np->dev, num_tx_rings); | ||
| 4558 | |||
| 4547 | for (i = 0; i < np->num_tx_rings; i++) { | 4559 | for (i = 0; i < np->num_tx_rings; i++) { |
| 4548 | struct tx_ring_info *rp = &np->tx_rings[i]; | 4560 | struct tx_ring_info *rp = &np->tx_rings[i]; |
| 4549 | 4561 | ||
| @@ -6246,11 +6258,17 @@ static void niu_sync_mac_stats(struct niu *np) | |||
| 6246 | static void niu_get_rx_stats(struct niu *np) | 6258 | static void niu_get_rx_stats(struct niu *np) |
| 6247 | { | 6259 | { |
| 6248 | unsigned long pkts, dropped, errors, bytes; | 6260 | unsigned long pkts, dropped, errors, bytes; |
| 6261 | struct rx_ring_info *rx_rings; | ||
| 6249 | int i; | 6262 | int i; |
| 6250 | 6263 | ||
| 6251 | pkts = dropped = errors = bytes = 0; | 6264 | pkts = dropped = errors = bytes = 0; |
| 6265 | |||
| 6266 | rx_rings = ACCESS_ONCE(np->rx_rings); | ||
| 6267 | if (!rx_rings) | ||
| 6268 | goto no_rings; | ||
| 6269 | |||
| 6252 | for (i = 0; i < np->num_rx_rings; i++) { | 6270 | for (i = 0; i < np->num_rx_rings; i++) { |
| 6253 | struct rx_ring_info *rp = &np->rx_rings[i]; | 6271 | struct rx_ring_info *rp = &rx_rings[i]; |
| 6254 | 6272 | ||
| 6255 | niu_sync_rx_discard_stats(np, rp, 0); | 6273 | niu_sync_rx_discard_stats(np, rp, 0); |
| 6256 | 6274 | ||
| @@ -6259,6 +6277,8 @@ static void niu_get_rx_stats(struct niu *np) | |||
| 6259 | dropped += rp->rx_dropped; | 6277 | dropped += rp->rx_dropped; |
| 6260 | errors += rp->rx_errors; | 6278 | errors += rp->rx_errors; |
| 6261 | } | 6279 | } |
| 6280 | |||
| 6281 | no_rings: | ||
| 6262 | np->dev->stats.rx_packets = pkts; | 6282 | np->dev->stats.rx_packets = pkts; |
| 6263 | np->dev->stats.rx_bytes = bytes; | 6283 | np->dev->stats.rx_bytes = bytes; |
| 6264 | np->dev->stats.rx_dropped = dropped; | 6284 | np->dev->stats.rx_dropped = dropped; |
| @@ -6268,16 +6288,24 @@ static void niu_get_rx_stats(struct niu *np) | |||
| 6268 | static void niu_get_tx_stats(struct niu *np) | 6288 | static void niu_get_tx_stats(struct niu *np) |
| 6269 | { | 6289 | { |
| 6270 | unsigned long pkts, errors, bytes; | 6290 | unsigned long pkts, errors, bytes; |
| 6291 | struct tx_ring_info *tx_rings; | ||
| 6271 | int i; | 6292 | int i; |
| 6272 | 6293 | ||
| 6273 | pkts = errors = bytes = 0; | 6294 | pkts = errors = bytes = 0; |
| 6295 | |||
| 6296 | tx_rings = ACCESS_ONCE(np->tx_rings); | ||
| 6297 | if (!tx_rings) | ||
| 6298 | goto no_rings; | ||
| 6299 | |||
| 6274 | for (i = 0; i < np->num_tx_rings; i++) { | 6300 | for (i = 0; i < np->num_tx_rings; i++) { |
| 6275 | struct tx_ring_info *rp = &np->tx_rings[i]; | 6301 | struct tx_ring_info *rp = &tx_rings[i]; |
| 6276 | 6302 | ||
| 6277 | pkts += rp->tx_packets; | 6303 | pkts += rp->tx_packets; |
| 6278 | bytes += rp->tx_bytes; | 6304 | bytes += rp->tx_bytes; |
| 6279 | errors += rp->tx_errors; | 6305 | errors += rp->tx_errors; |
| 6280 | } | 6306 | } |
| 6307 | |||
| 6308 | no_rings: | ||
| 6281 | np->dev->stats.tx_packets = pkts; | 6309 | np->dev->stats.tx_packets = pkts; |
| 6282 | np->dev->stats.tx_bytes = bytes; | 6310 | np->dev->stats.tx_bytes = bytes; |
| 6283 | np->dev->stats.tx_errors = errors; | 6311 | np->dev->stats.tx_errors = errors; |
| @@ -6287,9 +6315,10 @@ static struct net_device_stats *niu_get_stats(struct net_device *dev) | |||
| 6287 | { | 6315 | { |
| 6288 | struct niu *np = netdev_priv(dev); | 6316 | struct niu *np = netdev_priv(dev); |
| 6289 | 6317 | ||
| 6290 | niu_get_rx_stats(np); | 6318 | if (netif_running(dev)) { |
| 6291 | niu_get_tx_stats(np); | 6319 | niu_get_rx_stats(np); |
| 6292 | 6320 | niu_get_tx_stats(np); | |
| 6321 | } | ||
| 6293 | return &dev->stats; | 6322 | return &dev->stats; |
| 6294 | } | 6323 | } |
| 6295 | 6324 | ||
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index a0c26a99520..e1e33c80fb2 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h | |||
| @@ -73,7 +73,7 @@ struct pch_gbe_regs { | |||
| 73 | struct pch_gbe_regs_mac_adr mac_adr[16]; | 73 | struct pch_gbe_regs_mac_adr mac_adr[16]; |
| 74 | u32 ADDR_MASK; | 74 | u32 ADDR_MASK; |
| 75 | u32 MIIM; | 75 | u32 MIIM; |
| 76 | u32 reserve2; | 76 | u32 MAC_ADDR_LOAD; |
| 77 | u32 RGMII_ST; | 77 | u32 RGMII_ST; |
| 78 | u32 RGMII_CTRL; | 78 | u32 RGMII_CTRL; |
| 79 | u32 reserve3[3]; | 79 | u32 reserve3[3]; |
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 1bf12339441..b99e90aca37 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c | |||
| @@ -29,6 +29,7 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 29 | #define PCH_GBE_SHORT_PKT 64 | 29 | #define PCH_GBE_SHORT_PKT 64 |
| 30 | #define DSC_INIT16 0xC000 | 30 | #define DSC_INIT16 0xC000 |
| 31 | #define PCH_GBE_DMA_ALIGN 0 | 31 | #define PCH_GBE_DMA_ALIGN 0 |
| 32 | #define PCH_GBE_DMA_PADDING 2 | ||
| 32 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ | 33 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ |
| 33 | #define PCH_GBE_COPYBREAK_DEFAULT 256 | 34 | #define PCH_GBE_COPYBREAK_DEFAULT 256 |
| 34 | #define PCH_GBE_PCI_BAR 1 | 35 | #define PCH_GBE_PCI_BAR 1 |
| @@ -88,6 +89,12 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; | |||
| 88 | static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); | 89 | static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); |
| 89 | static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, | 90 | static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, |
| 90 | int data); | 91 | int data); |
| 92 | |||
| 93 | inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) | ||
| 94 | { | ||
| 95 | iowrite32(0x01, &hw->reg->MAC_ADDR_LOAD); | ||
| 96 | } | ||
| 97 | |||
| 91 | /** | 98 | /** |
| 92 | * pch_gbe_mac_read_mac_addr - Read MAC address | 99 | * pch_gbe_mac_read_mac_addr - Read MAC address |
| 93 | * @hw: Pointer to the HW structure | 100 | * @hw: Pointer to the HW structure |
| @@ -519,7 +526,9 @@ static void pch_gbe_reset_task(struct work_struct *work) | |||
| 519 | struct pch_gbe_adapter *adapter; | 526 | struct pch_gbe_adapter *adapter; |
| 520 | adapter = container_of(work, struct pch_gbe_adapter, reset_task); | 527 | adapter = container_of(work, struct pch_gbe_adapter, reset_task); |
| 521 | 528 | ||
| 529 | rtnl_lock(); | ||
| 522 | pch_gbe_reinit_locked(adapter); | 530 | pch_gbe_reinit_locked(adapter); |
| 531 | rtnl_unlock(); | ||
| 523 | } | 532 | } |
| 524 | 533 | ||
| 525 | /** | 534 | /** |
| @@ -528,14 +537,8 @@ static void pch_gbe_reset_task(struct work_struct *work) | |||
| 528 | */ | 537 | */ |
| 529 | void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) | 538 | void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) |
| 530 | { | 539 | { |
| 531 | struct net_device *netdev = adapter->netdev; | 540 | pch_gbe_down(adapter); |
| 532 | 541 | pch_gbe_up(adapter); | |
| 533 | rtnl_lock(); | ||
| 534 | if (netif_running(netdev)) { | ||
| 535 | pch_gbe_down(adapter); | ||
| 536 | pch_gbe_up(adapter); | ||
| 537 | } | ||
| 538 | rtnl_unlock(); | ||
| 539 | } | 542 | } |
| 540 | 543 | ||
| 541 | /** | 544 | /** |
| @@ -1369,16 +1372,13 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1369 | struct pch_gbe_buffer *buffer_info; | 1372 | struct pch_gbe_buffer *buffer_info; |
| 1370 | struct pch_gbe_rx_desc *rx_desc; | 1373 | struct pch_gbe_rx_desc *rx_desc; |
| 1371 | u32 length; | 1374 | u32 length; |
| 1372 | unsigned char tmp_packet[ETH_HLEN]; | ||
| 1373 | unsigned int i; | 1375 | unsigned int i; |
| 1374 | unsigned int cleaned_count = 0; | 1376 | unsigned int cleaned_count = 0; |
| 1375 | bool cleaned = false; | 1377 | bool cleaned = false; |
| 1376 | struct sk_buff *skb; | 1378 | struct sk_buff *skb, *new_skb; |
| 1377 | u8 dma_status; | 1379 | u8 dma_status; |
| 1378 | u16 gbec_status; | 1380 | u16 gbec_status; |
| 1379 | u32 tcp_ip_status; | 1381 | u32 tcp_ip_status; |
| 1380 | u8 skb_copy_flag = 0; | ||
| 1381 | u8 skb_padding_flag = 0; | ||
| 1382 | 1382 | ||
| 1383 | i = rx_ring->next_to_clean; | 1383 | i = rx_ring->next_to_clean; |
| 1384 | 1384 | ||
| @@ -1422,55 +1422,70 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1422 | pr_err("Receive CRC Error\n"); | 1422 | pr_err("Receive CRC Error\n"); |
| 1423 | } else { | 1423 | } else { |
| 1424 | /* get receive length */ | 1424 | /* get receive length */ |
| 1425 | /* length convert[-3], padding[-2] */ | 1425 | /* length convert[-3] */ |
| 1426 | length = (rx_desc->rx_words_eob) - 3 - 2; | 1426 | length = (rx_desc->rx_words_eob) - 3; |
| 1427 | 1427 | ||
| 1428 | /* Decide the data conversion method */ | 1428 | /* Decide the data conversion method */ |
| 1429 | if (!adapter->rx_csum) { | 1429 | if (!adapter->rx_csum) { |
| 1430 | /* [Header:14][payload] */ | 1430 | /* [Header:14][payload] */ |
| 1431 | skb_padding_flag = 0; | 1431 | if (NET_IP_ALIGN) { |
| 1432 | skb_copy_flag = 1; | 1432 | /* Because alignment differs, |
| 1433 | * the new_skb is newly allocated, | ||
| 1434 | * and data is copied to new_skb.*/ | ||
| 1435 | new_skb = netdev_alloc_skb(netdev, | ||
| 1436 | length + NET_IP_ALIGN); | ||
| 1437 | if (!new_skb) { | ||
| 1438 | /* dorrop error */ | ||
| 1439 | pr_err("New skb allocation " | ||
| 1440 | "Error\n"); | ||
| 1441 | goto dorrop; | ||
| 1442 | } | ||
| 1443 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1444 | memcpy(new_skb->data, skb->data, | ||
| 1445 | length); | ||
| 1446 | skb = new_skb; | ||
| 1447 | } else { | ||
| 1448 | /* DMA buffer is used as SKB as it is.*/ | ||
| 1449 | buffer_info->skb = NULL; | ||
| 1450 | } | ||
| 1433 | } else { | 1451 | } else { |
| 1434 | /* [Header:14][padding:2][payload] */ | 1452 | /* [Header:14][padding:2][payload] */ |
| 1435 | skb_padding_flag = 1; | 1453 | /* The length includes padding length */ |
| 1436 | if (length < copybreak) | 1454 | length = length - PCH_GBE_DMA_PADDING; |
| 1437 | skb_copy_flag = 1; | 1455 | if ((length < copybreak) || |
| 1438 | else | 1456 | (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) { |
| 1439 | skb_copy_flag = 0; | 1457 | /* Because alignment differs, |
| 1440 | } | 1458 | * the new_skb is newly allocated, |
| 1441 | 1459 | * and data is copied to new_skb. | |
| 1442 | /* Data conversion */ | 1460 | * Padding data is deleted |
| 1443 | if (skb_copy_flag) { /* recycle skb */ | 1461 | * at the time of a copy.*/ |
| 1444 | struct sk_buff *new_skb; | 1462 | new_skb = netdev_alloc_skb(netdev, |
| 1445 | new_skb = | 1463 | length + NET_IP_ALIGN); |
| 1446 | netdev_alloc_skb(netdev, | 1464 | if (!new_skb) { |
| 1447 | length + NET_IP_ALIGN); | 1465 | /* dorrop error */ |
| 1448 | if (new_skb) { | 1466 | pr_err("New skb allocation " |
| 1449 | if (!skb_padding_flag) { | 1467 | "Error\n"); |
| 1450 | skb_reserve(new_skb, | 1468 | goto dorrop; |
| 1451 | NET_IP_ALIGN); | ||
| 1452 | } | 1469 | } |
| 1470 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1453 | memcpy(new_skb->data, skb->data, | 1471 | memcpy(new_skb->data, skb->data, |
| 1454 | length); | 1472 | ETH_HLEN); |
| 1455 | /* save the skb | 1473 | memcpy(&new_skb->data[ETH_HLEN], |
| 1456 | * in buffer_info as good */ | 1474 | &skb->data[ETH_HLEN + |
| 1475 | PCH_GBE_DMA_PADDING], | ||
| 1476 | length - ETH_HLEN); | ||
| 1457 | skb = new_skb; | 1477 | skb = new_skb; |
| 1458 | } else if (!skb_padding_flag) { | 1478 | } else { |
| 1459 | /* dorrop error */ | 1479 | /* Padding data is deleted |
| 1460 | pr_err("New skb allocation Error\n"); | 1480 | * by moving header data.*/ |
| 1461 | goto dorrop; | 1481 | memmove(&skb->data[PCH_GBE_DMA_PADDING], |
| 1482 | &skb->data[0], ETH_HLEN); | ||
| 1483 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1484 | buffer_info->skb = NULL; | ||
| 1462 | } | 1485 | } |
| 1463 | } else { | ||
| 1464 | buffer_info->skb = NULL; | ||
| 1465 | } | 1486 | } |
| 1466 | if (skb_padding_flag) { | 1487 | /* The length includes FCS length */ |
| 1467 | memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); | 1488 | length = length - ETH_FCS_LEN; |
| 1468 | memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], | ||
| 1469 | ETH_HLEN); | ||
| 1470 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1471 | |||
| 1472 | } | ||
| 1473 | |||
| 1474 | /* update status of driver */ | 1489 | /* update status of driver */ |
| 1475 | adapter->stats.rx_bytes += length; | 1490 | adapter->stats.rx_bytes += length; |
| 1476 | adapter->stats.rx_packets++; | 1491 | adapter->stats.rx_packets++; |
| @@ -2322,6 +2337,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, | |||
| 2322 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; | 2337 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; |
| 2323 | pch_gbe_set_ethtool_ops(netdev); | 2338 | pch_gbe_set_ethtool_ops(netdev); |
| 2324 | 2339 | ||
| 2340 | pch_gbe_mac_load_mac_addr(&adapter->hw); | ||
| 2325 | pch_gbe_mac_reset_hw(&adapter->hw); | 2341 | pch_gbe_mac_reset_hw(&adapter->hw); |
| 2326 | 2342 | ||
| 2327 | /* setup the private structure */ | 2343 | /* setup the private structure */ |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 1f42f6ac855..d3cb7720586 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
| @@ -1488,12 +1488,10 @@ static void ei_rx_overrun(struct net_device *dev) | |||
| 1488 | 1488 | ||
| 1489 | /* | 1489 | /* |
| 1490 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. | 1490 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. |
| 1491 | * Early datasheets said to poll the reset bit, but now they say that | 1491 | * We wait at least 2ms. |
| 1492 | * it "is not a reliable indicator and subsequently should be ignored." | ||
| 1493 | * We wait at least 10ms. | ||
| 1494 | */ | 1492 | */ |
| 1495 | 1493 | ||
| 1496 | mdelay(10); | 1494 | mdelay(2); |
| 1497 | 1495 | ||
| 1498 | /* | 1496 | /* |
| 1499 | * Reset RBCR[01] back to zero as per magic incantation. | 1497 | * Reset RBCR[01] back to zero as per magic incantation. |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bde7d61f193..469ab0b7ce3 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -973,7 +973,8 @@ static void __rtl8169_check_link_status(struct net_device *dev, | |||
| 973 | if (pm) | 973 | if (pm) |
| 974 | pm_request_resume(&tp->pci_dev->dev); | 974 | pm_request_resume(&tp->pci_dev->dev); |
| 975 | netif_carrier_on(dev); | 975 | netif_carrier_on(dev); |
| 976 | netif_info(tp, ifup, dev, "link up\n"); | 976 | if (net_ratelimit()) |
| 977 | netif_info(tp, ifup, dev, "link up\n"); | ||
| 977 | } else { | 978 | } else { |
| 978 | netif_carrier_off(dev); | 979 | netif_carrier_off(dev); |
| 979 | netif_info(tp, ifdown, dev, "link down\n"); | 980 | netif_info(tp, ifdown, dev, "link down\n"); |
| @@ -3189,6 +3190,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3189 | if (pci_dev_run_wake(pdev)) | 3190 | if (pci_dev_run_wake(pdev)) |
| 3190 | pm_runtime_put_noidle(&pdev->dev); | 3191 | pm_runtime_put_noidle(&pdev->dev); |
| 3191 | 3192 | ||
| 3193 | netif_carrier_off(dev); | ||
| 3194 | |||
| 3192 | out: | 3195 | out: |
| 3193 | return rc; | 3196 | return rc; |
| 3194 | 3197 | ||
| @@ -3757,7 +3760,8 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
| 3757 | RTL_W16(IntrMitigate, 0x5151); | 3760 | RTL_W16(IntrMitigate, 0x5151); |
| 3758 | 3761 | ||
| 3759 | /* Work around for RxFIFO overflow. */ | 3762 | /* Work around for RxFIFO overflow. */ |
| 3760 | if (tp->mac_version == RTL_GIGA_MAC_VER_11) { | 3763 | if (tp->mac_version == RTL_GIGA_MAC_VER_11 || |
| 3764 | tp->mac_version == RTL_GIGA_MAC_VER_22) { | ||
| 3761 | tp->intr_event |= RxFIFOOver | PCSTimeout; | 3765 | tp->intr_event |= RxFIFOOver | PCSTimeout; |
| 3762 | tp->intr_event &= ~RxOverflow; | 3766 | tp->intr_event &= ~RxOverflow; |
| 3763 | } | 3767 | } |
| @@ -4639,12 +4643,33 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 4639 | break; | 4643 | break; |
| 4640 | } | 4644 | } |
| 4641 | 4645 | ||
| 4642 | /* Work around for rx fifo overflow */ | 4646 | if (unlikely(status & RxFIFOOver)) { |
| 4643 | if (unlikely(status & RxFIFOOver) && | 4647 | switch (tp->mac_version) { |
| 4644 | (tp->mac_version == RTL_GIGA_MAC_VER_11)) { | 4648 | /* Work around for rx fifo overflow */ |
| 4645 | netif_stop_queue(dev); | 4649 | case RTL_GIGA_MAC_VER_11: |
| 4646 | rtl8169_tx_timeout(dev); | 4650 | case RTL_GIGA_MAC_VER_22: |
| 4647 | break; | 4651 | case RTL_GIGA_MAC_VER_26: |
| 4652 | netif_stop_queue(dev); | ||
| 4653 | rtl8169_tx_timeout(dev); | ||
| 4654 | goto done; | ||
| 4655 | /* Testers needed. */ | ||
| 4656 | case RTL_GIGA_MAC_VER_17: | ||
| 4657 | case RTL_GIGA_MAC_VER_19: | ||
| 4658 | case RTL_GIGA_MAC_VER_20: | ||
| 4659 | case RTL_GIGA_MAC_VER_21: | ||
| 4660 | case RTL_GIGA_MAC_VER_23: | ||
| 4661 | case RTL_GIGA_MAC_VER_24: | ||
| 4662 | case RTL_GIGA_MAC_VER_27: | ||
| 4663 | case RTL_GIGA_MAC_VER_28: | ||
| 4664 | /* Experimental science. Pktgen proof. */ | ||
| 4665 | case RTL_GIGA_MAC_VER_12: | ||
| 4666 | case RTL_GIGA_MAC_VER_25: | ||
| 4667 | if (status == RxFIFOOver) | ||
| 4668 | goto done; | ||
| 4669 | break; | ||
| 4670 | default: | ||
| 4671 | break; | ||
| 4672 | } | ||
| 4648 | } | 4673 | } |
| 4649 | 4674 | ||
| 4650 | if (unlikely(status & SYSErr)) { | 4675 | if (unlikely(status & SYSErr)) { |
| @@ -4680,7 +4705,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 4680 | (status & RxFIFOOver) ? (status | RxOverflow) : status); | 4705 | (status & RxFIFOOver) ? (status | RxOverflow) : status); |
| 4681 | status = RTL_R16(IntrStatus); | 4706 | status = RTL_R16(IntrStatus); |
| 4682 | } | 4707 | } |
| 4683 | 4708 | done: | |
| 4684 | return IRQ_RETVAL(handled); | 4709 | return IRQ_RETVAL(handled); |
| 4685 | } | 4710 | } |
| 4686 | 4711 | ||
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 5976d1d51df..640e368ebee 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
| @@ -1777,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev) | |||
| 1777 | "cur_rx:%4.4d, dirty_rx:%4.4d\n", | 1777 | "cur_rx:%4.4d, dirty_rx:%4.4d\n", |
| 1778 | net_dev->name, sis_priv->cur_rx, | 1778 | net_dev->name, sis_priv->cur_rx, |
| 1779 | sis_priv->dirty_rx); | 1779 | sis_priv->dirty_rx); |
| 1780 | dev_kfree_skb(skb); | ||
| 1780 | break; | 1781 | break; |
| 1781 | } | 1782 | } |
| 1782 | 1783 | ||
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 34a0af3837f..0e5f03135b5 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
| @@ -1560,8 +1560,10 @@ static int stmmac_mac_device_setup(struct net_device *dev) | |||
| 1560 | 1560 | ||
| 1561 | priv->hw = device; | 1561 | priv->hw = device; |
| 1562 | 1562 | ||
| 1563 | if (device_can_wakeup(priv->device)) | 1563 | if (device_can_wakeup(priv->device)) { |
| 1564 | priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ | 1564 | priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ |
| 1565 | enable_irq_wake(dev->irq); | ||
| 1566 | } | ||
| 1565 | 1567 | ||
| 1566 | return 0; | 1568 | return 0; |
| 1567 | } | 1569 | } |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 93b32d36661..06c0e503365 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -11158,7 +11158,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 11158 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) | 11158 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) |
| 11159 | break; /* We have no PHY */ | 11159 | break; /* We have no PHY */ |
| 11160 | 11160 | ||
| 11161 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) | 11161 | if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || |
| 11162 | ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && | ||
| 11163 | !netif_running(dev))) | ||
| 11162 | return -EAGAIN; | 11164 | return -EAGAIN; |
| 11163 | 11165 | ||
| 11164 | spin_lock_bh(&tp->lock); | 11166 | spin_lock_bh(&tp->lock); |
| @@ -11174,7 +11176,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 11174 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) | 11176 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) |
| 11175 | break; /* We have no PHY */ | 11177 | break; /* We have no PHY */ |
| 11176 | 11178 | ||
| 11177 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) | 11179 | if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || |
| 11180 | ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && | ||
| 11181 | !netif_running(dev))) | ||
| 11178 | return -EAGAIN; | 11182 | return -EAGAIN; |
| 11179 | 11183 | ||
| 11180 | spin_lock_bh(&tp->lock); | 11184 | spin_lock_bh(&tp->lock); |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 04e8ce14a1d..7113168473c 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * cdc_ncm.c | 2 | * cdc_ncm.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) ST-Ericsson 2010 | 4 | * Copyright (C) ST-Ericsson 2010-2011 |
| 5 | * Contact: Alexey Orishko <alexey.orishko@stericsson.com> | 5 | * Contact: Alexey Orishko <alexey.orishko@stericsson.com> |
| 6 | * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> | 6 | * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> |
| 7 | * | 7 | * |
| @@ -54,7 +54,7 @@ | |||
| 54 | #include <linux/usb/usbnet.h> | 54 | #include <linux/usb/usbnet.h> |
| 55 | #include <linux/usb/cdc.h> | 55 | #include <linux/usb/cdc.h> |
| 56 | 56 | ||
| 57 | #define DRIVER_VERSION "17-Jan-2011" | 57 | #define DRIVER_VERSION "7-Feb-2011" |
| 58 | 58 | ||
| 59 | /* CDC NCM subclass 3.2.1 */ | 59 | /* CDC NCM subclass 3.2.1 */ |
| 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 | 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 |
| @@ -77,6 +77,9 @@ | |||
| 77 | */ | 77 | */ |
| 78 | #define CDC_NCM_DPT_DATAGRAMS_MAX 32 | 78 | #define CDC_NCM_DPT_DATAGRAMS_MAX 32 |
| 79 | 79 | ||
| 80 | /* Maximum amount of IN datagrams in NTB */ | ||
| 81 | #define CDC_NCM_DPT_DATAGRAMS_IN_MAX 0 /* unlimited */ | ||
| 82 | |||
| 80 | /* Restart the timer, if amount of datagrams is less than given value */ | 83 | /* Restart the timer, if amount of datagrams is less than given value */ |
| 81 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 | 84 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 |
| 82 | 85 | ||
| @@ -85,11 +88,6 @@ | |||
| 85 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ | 88 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ |
| 86 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) | 89 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) |
| 87 | 90 | ||
| 88 | struct connection_speed_change { | ||
| 89 | __le32 USBitRate; /* holds 3GPP downlink value, bits per second */ | ||
| 90 | __le32 DSBitRate; /* holds 3GPP uplink value, bits per second */ | ||
| 91 | } __attribute__ ((packed)); | ||
| 92 | |||
| 93 | struct cdc_ncm_data { | 91 | struct cdc_ncm_data { |
| 94 | struct usb_cdc_ncm_nth16 nth16; | 92 | struct usb_cdc_ncm_nth16 nth16; |
| 95 | struct usb_cdc_ncm_ndp16 ndp16; | 93 | struct usb_cdc_ncm_ndp16 ndp16; |
| @@ -198,10 +196,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 198 | { | 196 | { |
| 199 | struct usb_cdc_notification req; | 197 | struct usb_cdc_notification req; |
| 200 | u32 val; | 198 | u32 val; |
| 201 | __le16 max_datagram_size; | ||
| 202 | u8 flags; | 199 | u8 flags; |
| 203 | u8 iface_no; | 200 | u8 iface_no; |
| 204 | int err; | 201 | int err; |
| 202 | u16 ntb_fmt_supported; | ||
| 205 | 203 | ||
| 206 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; | 204 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; |
| 207 | 205 | ||
| @@ -223,6 +221,9 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 223 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); | 221 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); |
| 224 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); | 222 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); |
| 225 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); | 223 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); |
| 224 | /* devices prior to NCM Errata shall set this field to zero */ | ||
| 225 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); | ||
| 226 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); | ||
| 226 | 227 | ||
| 227 | if (ctx->func_desc != NULL) | 228 | if (ctx->func_desc != NULL) |
| 228 | flags = ctx->func_desc->bmNetworkCapabilities; | 229 | flags = ctx->func_desc->bmNetworkCapabilities; |
| @@ -231,22 +232,58 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 231 | 232 | ||
| 232 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " | 233 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " |
| 233 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " | 234 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " |
| 234 | "wNdpOutAlignment=%u flags=0x%x\n", | 235 | "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n", |
| 235 | ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, | 236 | ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, |
| 236 | ctx->tx_ndp_modulus, flags); | 237 | ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags); |
| 237 | 238 | ||
| 238 | /* max count of tx datagrams without terminating NULL entry */ | 239 | /* max count of tx datagrams */ |
| 239 | ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; | 240 | if ((ctx->tx_max_datagrams == 0) || |
| 241 | (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX)) | ||
| 242 | ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; | ||
| 240 | 243 | ||
| 241 | /* verify maximum size of received NTB in bytes */ | 244 | /* verify maximum size of received NTB in bytes */ |
| 242 | if ((ctx->rx_max < | 245 | if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) { |
| 243 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || | 246 | pr_debug("Using min receive length=%d\n", |
| 244 | (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX)) { | 247 | USB_CDC_NCM_NTB_MIN_IN_SIZE); |
| 248 | ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE; | ||
| 249 | } | ||
| 250 | |||
| 251 | if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) { | ||
| 245 | pr_debug("Using default maximum receive length=%d\n", | 252 | pr_debug("Using default maximum receive length=%d\n", |
| 246 | CDC_NCM_NTB_MAX_SIZE_RX); | 253 | CDC_NCM_NTB_MAX_SIZE_RX); |
| 247 | ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; | 254 | ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; |
| 248 | } | 255 | } |
| 249 | 256 | ||
| 257 | /* inform device about NTB input size changes */ | ||
| 258 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { | ||
| 259 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | | ||
| 260 | USB_RECIP_INTERFACE; | ||
| 261 | req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE; | ||
| 262 | req.wValue = 0; | ||
| 263 | req.wIndex = cpu_to_le16(iface_no); | ||
| 264 | |||
| 265 | if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { | ||
| 266 | struct usb_cdc_ncm_ndp_input_size ndp_in_sz; | ||
| 267 | |||
| 268 | req.wLength = 8; | ||
| 269 | ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
| 270 | ndp_in_sz.wNtbInMaxDatagrams = | ||
| 271 | cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); | ||
| 272 | ndp_in_sz.wReserved = 0; | ||
| 273 | err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL, | ||
| 274 | 1000); | ||
| 275 | } else { | ||
| 276 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
| 277 | |||
| 278 | req.wLength = 4; | ||
| 279 | err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, | ||
| 280 | NULL, 1000); | ||
| 281 | } | ||
| 282 | |||
| 283 | if (err) | ||
| 284 | pr_debug("Setting NTB Input Size failed\n"); | ||
| 285 | } | ||
| 286 | |||
| 250 | /* verify maximum size of transmitted NTB in bytes */ | 287 | /* verify maximum size of transmitted NTB in bytes */ |
| 251 | if ((ctx->tx_max < | 288 | if ((ctx->tx_max < |
| 252 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || | 289 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || |
| @@ -297,47 +334,84 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 297 | /* additional configuration */ | 334 | /* additional configuration */ |
| 298 | 335 | ||
| 299 | /* set CRC Mode */ | 336 | /* set CRC Mode */ |
| 300 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; | 337 | if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { |
| 301 | req.bNotificationType = USB_CDC_SET_CRC_MODE; | 338 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 302 | req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); | 339 | USB_RECIP_INTERFACE; |
| 303 | req.wIndex = cpu_to_le16(iface_no); | 340 | req.bNotificationType = USB_CDC_SET_CRC_MODE; |
| 304 | req.wLength = 0; | 341 | req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); |
| 305 | 342 | req.wIndex = cpu_to_le16(iface_no); | |
| 306 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | 343 | req.wLength = 0; |
| 307 | if (err) | 344 | |
| 308 | pr_debug("Setting CRC mode off failed\n"); | 345 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); |
| 346 | if (err) | ||
| 347 | pr_debug("Setting CRC mode off failed\n"); | ||
| 348 | } | ||
| 309 | 349 | ||
| 310 | /* set NTB format */ | 350 | /* set NTB format, if both formats are supported */ |
| 311 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; | 351 | if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { |
| 312 | req.bNotificationType = USB_CDC_SET_NTB_FORMAT; | 352 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 313 | req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); | 353 | USB_RECIP_INTERFACE; |
| 314 | req.wIndex = cpu_to_le16(iface_no); | 354 | req.bNotificationType = USB_CDC_SET_NTB_FORMAT; |
| 315 | req.wLength = 0; | 355 | req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); |
| 356 | req.wIndex = cpu_to_le16(iface_no); | ||
| 357 | req.wLength = 0; | ||
| 358 | |||
| 359 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | ||
| 360 | if (err) | ||
| 361 | pr_debug("Setting NTB format to 16-bit failed\n"); | ||
| 362 | } | ||
| 316 | 363 | ||
| 317 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | 364 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; |
| 318 | if (err) | ||
| 319 | pr_debug("Setting NTB format to 16-bit failed\n"); | ||
| 320 | 365 | ||
| 321 | /* set Max Datagram Size (MTU) */ | 366 | /* set Max Datagram Size (MTU) */ |
| 322 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; | 367 | if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { |
| 323 | req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; | 368 | __le16 max_datagram_size; |
| 324 | req.wValue = 0; | 369 | u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); |
| 325 | req.wIndex = cpu_to_le16(iface_no); | 370 | |
| 326 | req.wLength = cpu_to_le16(2); | 371 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | |
| 372 | USB_RECIP_INTERFACE; | ||
| 373 | req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; | ||
| 374 | req.wValue = 0; | ||
| 375 | req.wIndex = cpu_to_le16(iface_no); | ||
| 376 | req.wLength = cpu_to_le16(2); | ||
| 377 | |||
| 378 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, | ||
| 379 | 1000); | ||
| 380 | if (err) { | ||
| 381 | pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", | ||
| 382 | CDC_NCM_MIN_DATAGRAM_SIZE); | ||
| 383 | } else { | ||
| 384 | ctx->max_datagram_size = le16_to_cpu(max_datagram_size); | ||
| 385 | /* Check Eth descriptor value */ | ||
| 386 | if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) { | ||
| 387 | if (ctx->max_datagram_size > eth_max_sz) | ||
| 388 | ctx->max_datagram_size = eth_max_sz; | ||
| 389 | } else { | ||
| 390 | if (ctx->max_datagram_size > | ||
| 391 | CDC_NCM_MAX_DATAGRAM_SIZE) | ||
| 392 | ctx->max_datagram_size = | ||
| 393 | CDC_NCM_MAX_DATAGRAM_SIZE; | ||
| 394 | } | ||
| 327 | 395 | ||
| 328 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, 1000); | 396 | if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) |
| 329 | if (err) { | 397 | ctx->max_datagram_size = |
| 330 | pr_debug(" GET_MAX_DATAGRAM_SIZE failed, using size=%u\n", | 398 | CDC_NCM_MIN_DATAGRAM_SIZE; |
| 331 | CDC_NCM_MIN_DATAGRAM_SIZE); | 399 | |
| 332 | /* use default */ | 400 | /* if value changed, update device */ |
| 333 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | 401 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 334 | } else { | 402 | USB_RECIP_INTERFACE; |
| 335 | ctx->max_datagram_size = le16_to_cpu(max_datagram_size); | 403 | req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; |
| 404 | req.wValue = 0; | ||
| 405 | req.wIndex = cpu_to_le16(iface_no); | ||
| 406 | req.wLength = 2; | ||
| 407 | max_datagram_size = cpu_to_le16(ctx->max_datagram_size); | ||
| 408 | |||
| 409 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, | ||
| 410 | 0, NULL, 1000); | ||
| 411 | if (err) | ||
| 412 | pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); | ||
| 413 | } | ||
| 336 | 414 | ||
| 337 | if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) | ||
| 338 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | ||
| 339 | else if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) | ||
| 340 | ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; | ||
| 341 | } | 415 | } |
| 342 | 416 | ||
| 343 | if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) | 417 | if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) |
| @@ -466,19 +540,13 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 466 | 540 | ||
| 467 | ctx->ether_desc = | 541 | ctx->ether_desc = |
| 468 | (const struct usb_cdc_ether_desc *)buf; | 542 | (const struct usb_cdc_ether_desc *)buf; |
| 469 | |||
| 470 | dev->hard_mtu = | 543 | dev->hard_mtu = |
| 471 | le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); | 544 | le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); |
| 472 | 545 | ||
| 473 | if (dev->hard_mtu < | 546 | if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE) |
| 474 | (CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN)) | 547 | dev->hard_mtu = CDC_NCM_MIN_DATAGRAM_SIZE; |
| 475 | dev->hard_mtu = | 548 | else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE) |
| 476 | CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN; | 549 | dev->hard_mtu = CDC_NCM_MAX_DATAGRAM_SIZE; |
| 477 | |||
| 478 | else if (dev->hard_mtu > | ||
| 479 | (CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN)) | ||
| 480 | dev->hard_mtu = | ||
| 481 | CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN; | ||
| 482 | break; | 550 | break; |
| 483 | 551 | ||
| 484 | case USB_CDC_NCM_TYPE: | 552 | case USB_CDC_NCM_TYPE: |
| @@ -628,13 +696,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 628 | u32 offset; | 696 | u32 offset; |
| 629 | u32 last_offset; | 697 | u32 last_offset; |
| 630 | u16 n = 0; | 698 | u16 n = 0; |
| 631 | u8 timeout = 0; | 699 | u8 ready2send = 0; |
| 632 | 700 | ||
| 633 | /* if there is a remaining skb, it gets priority */ | 701 | /* if there is a remaining skb, it gets priority */ |
| 634 | if (skb != NULL) | 702 | if (skb != NULL) |
| 635 | swap(skb, ctx->tx_rem_skb); | 703 | swap(skb, ctx->tx_rem_skb); |
| 636 | else | 704 | else |
| 637 | timeout = 1; | 705 | ready2send = 1; |
| 638 | 706 | ||
| 639 | /* | 707 | /* |
| 640 | * +----------------+ | 708 | * +----------------+ |
| @@ -682,9 +750,10 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 682 | 750 | ||
| 683 | for (; n < ctx->tx_max_datagrams; n++) { | 751 | for (; n < ctx->tx_max_datagrams; n++) { |
| 684 | /* check if end of transmit buffer is reached */ | 752 | /* check if end of transmit buffer is reached */ |
| 685 | if (offset >= ctx->tx_max) | 753 | if (offset >= ctx->tx_max) { |
| 754 | ready2send = 1; | ||
| 686 | break; | 755 | break; |
| 687 | 756 | } | |
| 688 | /* compute maximum buffer size */ | 757 | /* compute maximum buffer size */ |
| 689 | rem = ctx->tx_max - offset; | 758 | rem = ctx->tx_max - offset; |
| 690 | 759 | ||
| @@ -711,9 +780,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 711 | } | 780 | } |
| 712 | ctx->tx_rem_skb = skb; | 781 | ctx->tx_rem_skb = skb; |
| 713 | skb = NULL; | 782 | skb = NULL; |
| 714 | 783 | ready2send = 1; | |
| 715 | /* loop one more time */ | ||
| 716 | timeout = 1; | ||
| 717 | } | 784 | } |
| 718 | break; | 785 | break; |
| 719 | } | 786 | } |
| @@ -756,7 +823,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 756 | ctx->tx_curr_last_offset = last_offset; | 823 | ctx->tx_curr_last_offset = last_offset; |
| 757 | goto exit_no_skb; | 824 | goto exit_no_skb; |
| 758 | 825 | ||
| 759 | } else if ((n < ctx->tx_max_datagrams) && (timeout == 0)) { | 826 | } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) { |
| 760 | /* wait for more frames */ | 827 | /* wait for more frames */ |
| 761 | /* push variables */ | 828 | /* push variables */ |
| 762 | ctx->tx_curr_skb = skb_out; | 829 | ctx->tx_curr_skb = skb_out; |
| @@ -813,7 +880,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 813 | cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); | 880 | cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); |
| 814 | ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); | 881 | ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); |
| 815 | ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); | 882 | ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); |
| 816 | ctx->tx_ncm.nth16.wFpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), | 883 | ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), |
| 817 | ctx->tx_ndp_modulus); | 884 | ctx->tx_ndp_modulus); |
| 818 | 885 | ||
| 819 | memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); | 886 | memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); |
| @@ -825,13 +892,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 825 | rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * | 892 | rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * |
| 826 | sizeof(struct usb_cdc_ncm_dpe16)); | 893 | sizeof(struct usb_cdc_ncm_dpe16)); |
| 827 | ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); | 894 | ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); |
| 828 | ctx->tx_ncm.ndp16.wNextFpIndex = 0; /* reserved */ | 895 | ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ |
| 829 | 896 | ||
| 830 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex, | 897 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, |
| 831 | &(ctx->tx_ncm.ndp16), | 898 | &(ctx->tx_ncm.ndp16), |
| 832 | sizeof(ctx->tx_ncm.ndp16)); | 899 | sizeof(ctx->tx_ncm.ndp16)); |
| 833 | 900 | ||
| 834 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex + | 901 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + |
| 835 | sizeof(ctx->tx_ncm.ndp16), | 902 | sizeof(ctx->tx_ncm.ndp16), |
| 836 | &(ctx->tx_ncm.dpe16), | 903 | &(ctx->tx_ncm.dpe16), |
| 837 | (ctx->tx_curr_frame_num + 1) * | 904 | (ctx->tx_curr_frame_num + 1) * |
| @@ -961,7 +1028,7 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
| 961 | goto error; | 1028 | goto error; |
| 962 | } | 1029 | } |
| 963 | 1030 | ||
| 964 | temp = le16_to_cpu(ctx->rx_ncm.nth16.wFpIndex); | 1031 | temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex); |
| 965 | if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { | 1032 | if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { |
| 966 | pr_debug("invalid DPT16 index\n"); | 1033 | pr_debug("invalid DPT16 index\n"); |
| 967 | goto error; | 1034 | goto error; |
| @@ -1048,10 +1115,10 @@ error: | |||
| 1048 | 1115 | ||
| 1049 | static void | 1116 | static void |
| 1050 | cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx, | 1117 | cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx, |
| 1051 | struct connection_speed_change *data) | 1118 | struct usb_cdc_speed_change *data) |
| 1052 | { | 1119 | { |
| 1053 | uint32_t rx_speed = le32_to_cpu(data->USBitRate); | 1120 | uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); |
| 1054 | uint32_t tx_speed = le32_to_cpu(data->DSBitRate); | 1121 | uint32_t tx_speed = le32_to_cpu(data->ULBitRate); |
| 1055 | 1122 | ||
| 1056 | /* | 1123 | /* |
| 1057 | * Currently the USB-NET API does not support reporting the actual | 1124 | * Currently the USB-NET API does not support reporting the actual |
| @@ -1092,7 +1159,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) | |||
| 1092 | /* test for split data in 8-byte chunks */ | 1159 | /* test for split data in 8-byte chunks */ |
| 1093 | if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { | 1160 | if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { |
| 1094 | cdc_ncm_speed_change(ctx, | 1161 | cdc_ncm_speed_change(ctx, |
| 1095 | (struct connection_speed_change *)urb->transfer_buffer); | 1162 | (struct usb_cdc_speed_change *)urb->transfer_buffer); |
| 1096 | return; | 1163 | return; |
| 1097 | } | 1164 | } |
| 1098 | 1165 | ||
| @@ -1120,12 +1187,12 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) | |||
| 1120 | break; | 1187 | break; |
| 1121 | 1188 | ||
| 1122 | case USB_CDC_NOTIFY_SPEED_CHANGE: | 1189 | case USB_CDC_NOTIFY_SPEED_CHANGE: |
| 1123 | if (urb->actual_length < | 1190 | if (urb->actual_length < (sizeof(*event) + |
| 1124 | (sizeof(*event) + sizeof(struct connection_speed_change))) | 1191 | sizeof(struct usb_cdc_speed_change))) |
| 1125 | set_bit(EVENT_STS_SPLIT, &dev->flags); | 1192 | set_bit(EVENT_STS_SPLIT, &dev->flags); |
| 1126 | else | 1193 | else |
| 1127 | cdc_ncm_speed_change(ctx, | 1194 | cdc_ncm_speed_change(ctx, |
| 1128 | (struct connection_speed_change *) &event[1]); | 1195 | (struct usb_cdc_speed_change *) &event[1]); |
| 1129 | break; | 1196 | break; |
| 1130 | 1197 | ||
| 1131 | default: | 1198 | default: |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bed8fcedff4..6d83812603b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -2628,15 +2628,15 @@ exit: | |||
| 2628 | 2628 | ||
| 2629 | static void hso_free_tiomget(struct hso_serial *serial) | 2629 | static void hso_free_tiomget(struct hso_serial *serial) |
| 2630 | { | 2630 | { |
| 2631 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 2631 | struct hso_tiocmget *tiocmget; |
| 2632 | if (!serial) | ||
| 2633 | return; | ||
| 2634 | tiocmget = serial->tiocmget; | ||
| 2632 | if (tiocmget) { | 2635 | if (tiocmget) { |
| 2633 | if (tiocmget->urb) { | 2636 | usb_free_urb(tiocmget->urb); |
| 2634 | usb_free_urb(tiocmget->urb); | 2637 | tiocmget->urb = NULL; |
| 2635 | tiocmget->urb = NULL; | ||
| 2636 | } | ||
| 2637 | serial->tiocmget = NULL; | 2638 | serial->tiocmget = NULL; |
| 2638 | kfree(tiocmget); | 2639 | kfree(tiocmget); |
| 2639 | |||
| 2640 | } | 2640 | } |
| 2641 | } | 2641 | } |
| 2642 | 2642 | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ed9a41643ff..95c41d56631 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -931,8 +931,10 @@ fail_halt: | |||
| 931 | if (urb != NULL) { | 931 | if (urb != NULL) { |
| 932 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 932 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
| 933 | status = usb_autopm_get_interface(dev->intf); | 933 | status = usb_autopm_get_interface(dev->intf); |
| 934 | if (status < 0) | 934 | if (status < 0) { |
| 935 | usb_free_urb(urb); | ||
| 935 | goto fail_lowmem; | 936 | goto fail_lowmem; |
| 937 | } | ||
| 936 | if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) | 938 | if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) |
| 937 | resched = 0; | 939 | resched = 0; |
| 938 | usb_autopm_put_interface(dev->intf); | 940 | usb_autopm_put_interface(dev->intf); |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 90a23e410d1..82dba5aaf42 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -446,6 +446,20 @@ static void skb_recv_done(struct virtqueue *rvq) | |||
| 446 | } | 446 | } |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | static void virtnet_napi_enable(struct virtnet_info *vi) | ||
| 450 | { | ||
| 451 | napi_enable(&vi->napi); | ||
| 452 | |||
| 453 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 454 | * won't get another interrupt, so process any outstanding packets | ||
| 455 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 456 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 457 | if (napi_schedule_prep(&vi->napi)) { | ||
| 458 | virtqueue_disable_cb(vi->rvq); | ||
| 459 | __napi_schedule(&vi->napi); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 449 | static void refill_work(struct work_struct *work) | 463 | static void refill_work(struct work_struct *work) |
| 450 | { | 464 | { |
| 451 | struct virtnet_info *vi; | 465 | struct virtnet_info *vi; |
| @@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work) | |||
| 454 | vi = container_of(work, struct virtnet_info, refill.work); | 468 | vi = container_of(work, struct virtnet_info, refill.work); |
| 455 | napi_disable(&vi->napi); | 469 | napi_disable(&vi->napi); |
| 456 | still_empty = !try_fill_recv(vi, GFP_KERNEL); | 470 | still_empty = !try_fill_recv(vi, GFP_KERNEL); |
| 457 | napi_enable(&vi->napi); | 471 | virtnet_napi_enable(vi); |
| 458 | 472 | ||
| 459 | /* In theory, this can happen: if we don't get any buffers in | 473 | /* In theory, this can happen: if we don't get any buffers in |
| 460 | * we will *never* try to fill again. */ | 474 | * we will *never* try to fill again. */ |
| @@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev) | |||
| 638 | { | 652 | { |
| 639 | struct virtnet_info *vi = netdev_priv(dev); | 653 | struct virtnet_info *vi = netdev_priv(dev); |
| 640 | 654 | ||
| 641 | napi_enable(&vi->napi); | 655 | virtnet_napi_enable(vi); |
| 642 | |||
| 643 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 644 | * won't get another interrupt, so process any outstanding packets | ||
| 645 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 646 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 647 | if (napi_schedule_prep(&vi->napi)) { | ||
| 648 | virtqueue_disable_cb(vi->rvq); | ||
| 649 | __napi_schedule(&vi->napi); | ||
| 650 | } | ||
| 651 | return 0; | 656 | return 0; |
| 652 | } | 657 | } |
| 653 | 658 | ||
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 01c05f53e2f..228d4f7a58a 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c | |||
| @@ -3690,7 +3690,7 @@ __vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, | |||
| 3690 | if (status != VXGE_HW_OK) | 3690 | if (status != VXGE_HW_OK) |
| 3691 | goto exit; | 3691 | goto exit; |
| 3692 | 3692 | ||
| 3693 | if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || | 3693 | if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) && |
| 3694 | (rts_table != | 3694 | (rts_table != |
| 3695 | VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) | 3695 | VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) |
| 3696 | *data1 = 0; | 3696 | *data1 = 0; |
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 0064be7ce5c..21091c26a9a 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c | |||
| @@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah) | |||
| 838 | for (i = 0; i < qmax; i++) { | 838 | for (i = 0; i < qmax; i++) { |
| 839 | err = ath5k_hw_stop_tx_dma(ah, i); | 839 | err = ath5k_hw_stop_tx_dma(ah, i); |
| 840 | /* -EINVAL -> queue inactive */ | 840 | /* -EINVAL -> queue inactive */ |
| 841 | if (err != -EINVAL) | 841 | if (err && err != -EINVAL) |
| 842 | return err; | 842 | return err; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | return err; | 845 | return 0; |
| 846 | } | 846 | } |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e5f2b96a4c6..a702817daf7 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
| @@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
| 86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
| 87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | dur = ieee80211_generic_frame_duration(sc->hw, |
| 88 | NULL, len, rate); | 88 | NULL, len, rate); |
| 89 | return dur; | 89 | return le16_to_cpu(dur); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | bitrate = rate->bitrate; | 92 | bitrate = rate->bitrate; |
| @@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
| 265 | * what rate we should choose to TX ACKs. */ | 265 | * what rate we should choose to TX ACKs. */ |
| 266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); |
| 267 | 267 | ||
| 268 | tx_time = le16_to_cpu(tx_time); | ||
| 269 | |||
| 270 | ath5k_hw_reg_write(ah, tx_time, reg); | 268 | ath5k_hw_reg_write(ah, tx_time, reg); |
| 271 | 269 | ||
| 272 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f8a7771faee..f44c84ab5dc 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
| @@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | |||
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | /* WAR for ASPM system hang */ | 428 | /* WAR for ASPM system hang */ |
| 429 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { | 429 | if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) |
| 430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); | 430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); |
| 431 | } | ||
| 432 | 431 | ||
| 433 | if (AR_SREV_9285E_20(ah)) | 432 | if (AR_SREV_9285E_20(ah)) |
| 434 | val |= AR_WA_BIT23; | 433 | val |= AR_WA_BIT23; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3681caf5428..23838e37d45 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -218,6 +218,7 @@ struct ath_frame_info { | |||
| 218 | struct ath_buf_state { | 218 | struct ath_buf_state { |
| 219 | u8 bf_type; | 219 | u8 bf_type; |
| 220 | u8 bfs_paprd; | 220 | u8 bfs_paprd; |
| 221 | unsigned long bfs_paprd_timestamp; | ||
| 221 | enum ath9k_internal_frame_type bfs_ftype; | 222 | enum ath9k_internal_frame_type bfs_ftype; |
| 222 | }; | 223 | }; |
| 223 | 224 | ||
| @@ -593,7 +594,6 @@ struct ath_softc { | |||
| 593 | struct work_struct paprd_work; | 594 | struct work_struct paprd_work; |
| 594 | struct work_struct hw_check_work; | 595 | struct work_struct hw_check_work; |
| 595 | struct completion paprd_complete; | 596 | struct completion paprd_complete; |
| 596 | bool paprd_pending; | ||
| 597 | 597 | ||
| 598 | u32 intrstatus; | 598 | u32 intrstatus; |
| 599 | u32 sc_flags; /* SC_OP_* */ | 599 | u32 sc_flags; /* SC_OP_* */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 38433f9bfe5..0352f0994ca 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | |||
| 142 | { | 142 | { |
| 143 | ath9k_htc_exit_debug(priv->ah); | 143 | ath9k_htc_exit_debug(priv->ah); |
| 144 | ath9k_hw_deinit(priv->ah); | 144 | ath9k_hw_deinit(priv->ah); |
| 145 | tasklet_kill(&priv->swba_tasklet); | ||
| 146 | tasklet_kill(&priv->rx_tasklet); | ||
| 147 | tasklet_kill(&priv->tx_tasklet); | ||
| 148 | kfree(priv->ah); | 145 | kfree(priv->ah); |
| 149 | priv->ah = NULL; | 146 | priv->ah = NULL; |
| 150 | } | 147 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f4d576bc3cc..6bb59958f71 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1025,12 +1025,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1025 | int ret = 0; | 1025 | int ret = 0; |
| 1026 | u8 cmd_rsp; | 1026 | u8 cmd_rsp; |
| 1027 | 1027 | ||
| 1028 | /* Cancel all the running timers/work .. */ | ||
| 1029 | cancel_work_sync(&priv->fatal_work); | ||
| 1030 | cancel_work_sync(&priv->ps_work); | ||
| 1031 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
| 1032 | ath9k_led_stop_brightness(priv); | ||
| 1033 | |||
| 1034 | mutex_lock(&priv->mutex); | 1028 | mutex_lock(&priv->mutex); |
| 1035 | 1029 | ||
| 1036 | if (priv->op_flags & OP_INVALID) { | 1030 | if (priv->op_flags & OP_INVALID) { |
| @@ -1044,8 +1038,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1044 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 1038 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
| 1045 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 1039 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
| 1046 | WMI_CMD(WMI_STOP_RECV_CMDID); | 1040 | WMI_CMD(WMI_STOP_RECV_CMDID); |
| 1041 | |||
| 1042 | tasklet_kill(&priv->swba_tasklet); | ||
| 1043 | tasklet_kill(&priv->rx_tasklet); | ||
| 1044 | tasklet_kill(&priv->tx_tasklet); | ||
| 1045 | |||
| 1047 | skb_queue_purge(&priv->tx_queue); | 1046 | skb_queue_purge(&priv->tx_queue); |
| 1048 | 1047 | ||
| 1048 | mutex_unlock(&priv->mutex); | ||
| 1049 | |||
| 1050 | /* Cancel all the running timers/work .. */ | ||
| 1051 | cancel_work_sync(&priv->fatal_work); | ||
| 1052 | cancel_work_sync(&priv->ps_work); | ||
| 1053 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
| 1054 | ath9k_led_stop_brightness(priv); | ||
| 1055 | |||
| 1056 | mutex_lock(&priv->mutex); | ||
| 1057 | |||
| 1049 | /* Remove monitor interface here */ | 1058 | /* Remove monitor interface here */ |
| 1050 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | 1059 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { |
| 1051 | if (ath9k_htc_remove_monitor_interface(priv)) | 1060 | if (ath9k_htc_remove_monitor_interface(priv)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 767d8b86f1e..087a6a95edd 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -598,8 +598,6 @@ err_btcoex: | |||
| 598 | err_queues: | 598 | err_queues: |
| 599 | ath9k_hw_deinit(ah); | 599 | ath9k_hw_deinit(ah); |
| 600 | err_hw: | 600 | err_hw: |
| 601 | tasklet_kill(&sc->intr_tq); | ||
| 602 | tasklet_kill(&sc->bcon_tasklet); | ||
| 603 | 601 | ||
| 604 | kfree(ah); | 602 | kfree(ah); |
| 605 | sc->sc_ah = NULL; | 603 | sc->sc_ah = NULL; |
| @@ -807,9 +805,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
| 807 | 805 | ||
| 808 | ath9k_hw_deinit(sc->sc_ah); | 806 | ath9k_hw_deinit(sc->sc_ah); |
| 809 | 807 | ||
| 810 | tasklet_kill(&sc->intr_tq); | ||
| 811 | tasklet_kill(&sc->bcon_tasklet); | ||
| 812 | |||
| 813 | kfree(sc->sc_ah); | 808 | kfree(sc->sc_ah); |
| 814 | sc->sc_ah = NULL; | 809 | sc->sc_ah = NULL; |
| 815 | } | 810 | } |
| @@ -824,6 +819,8 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
| 824 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 819 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
| 825 | ath_deinit_leds(sc); | 820 | ath_deinit_leds(sc); |
| 826 | 821 | ||
| 822 | ath9k_ps_restore(sc); | ||
| 823 | |||
| 827 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 824 | for (i = 0; i < sc->num_sec_wiphy; i++) { |
| 828 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | 825 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; |
| 829 | if (aphy == NULL) | 826 | if (aphy == NULL) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c79c97be6cd..da5c64597c1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -325,6 +325,8 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
| 325 | { | 325 | { |
| 326 | struct ieee80211_hw *hw = sc->hw; | 326 | struct ieee80211_hw *hw = sc->hw; |
| 327 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 327 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
| 328 | struct ath_hw *ah = sc->sc_ah; | ||
| 329 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 328 | struct ath_tx_control txctl; | 330 | struct ath_tx_control txctl; |
| 329 | int time_left; | 331 | int time_left; |
| 330 | 332 | ||
| @@ -340,14 +342,16 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
| 340 | tx_info->control.rates[1].idx = -1; | 342 | tx_info->control.rates[1].idx = -1; |
| 341 | 343 | ||
| 342 | init_completion(&sc->paprd_complete); | 344 | init_completion(&sc->paprd_complete); |
| 343 | sc->paprd_pending = true; | ||
| 344 | txctl.paprd = BIT(chain); | 345 | txctl.paprd = BIT(chain); |
| 345 | if (ath_tx_start(hw, skb, &txctl) != 0) | 346 | |
| 347 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
| 348 | ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); | ||
| 349 | dev_kfree_skb_any(skb); | ||
| 346 | return false; | 350 | return false; |
| 351 | } | ||
| 347 | 352 | ||
| 348 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | 353 | time_left = wait_for_completion_timeout(&sc->paprd_complete, |
| 349 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 354 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); |
| 350 | sc->paprd_pending = false; | ||
| 351 | 355 | ||
| 352 | if (!time_left) | 356 | if (!time_left) |
| 353 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, | 357 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, |
| @@ -953,8 +957,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 953 | 957 | ||
| 954 | spin_unlock_bh(&sc->sc_pcu_lock); | 958 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 955 | ath9k_ps_restore(sc); | 959 | ath9k_ps_restore(sc); |
| 956 | |||
| 957 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | ||
| 958 | } | 960 | } |
| 959 | 961 | ||
| 960 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 962 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
| @@ -1309,6 +1311,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1309 | 1311 | ||
| 1310 | spin_lock_bh(&sc->sc_pcu_lock); | 1312 | spin_lock_bh(&sc->sc_pcu_lock); |
| 1311 | 1313 | ||
| 1314 | /* prevent tasklets to enable interrupts once we disable them */ | ||
| 1315 | ah->imask &= ~ATH9K_INT_GLOBAL; | ||
| 1316 | |||
| 1312 | /* make sure h/w will not generate any interrupt | 1317 | /* make sure h/w will not generate any interrupt |
| 1313 | * before setting the invalid flag. */ | 1318 | * before setting the invalid flag. */ |
| 1314 | ath9k_hw_disable_interrupts(ah); | 1319 | ath9k_hw_disable_interrupts(ah); |
| @@ -1326,6 +1331,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1326 | 1331 | ||
| 1327 | spin_unlock_bh(&sc->sc_pcu_lock); | 1332 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 1328 | 1333 | ||
| 1334 | /* we can now sync irq and kill any running tasklets, since we already | ||
| 1335 | * disabled interrupts and not holding a spin lock */ | ||
| 1336 | synchronize_irq(sc->irq); | ||
| 1337 | tasklet_kill(&sc->intr_tq); | ||
| 1338 | tasklet_kill(&sc->bcon_tasklet); | ||
| 1339 | |||
| 1329 | ath9k_ps_restore(sc); | 1340 | ath9k_ps_restore(sc); |
| 1330 | 1341 | ||
| 1331 | sc->ps_idle = true; | 1342 | sc->ps_idle = true; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 33a37edbaf7..07b7804aec5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1725,6 +1725,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1725 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, | 1725 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, |
| 1726 | bf->bf_state.bfs_paprd); | 1726 | bf->bf_state.bfs_paprd); |
| 1727 | 1727 | ||
| 1728 | if (txctl->paprd) | ||
| 1729 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
| 1730 | |||
| 1728 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); | 1731 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); |
| 1729 | } | 1732 | } |
| 1730 | 1733 | ||
| @@ -1886,7 +1889,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1886 | bf->bf_buf_addr = 0; | 1889 | bf->bf_buf_addr = 0; |
| 1887 | 1890 | ||
| 1888 | if (bf->bf_state.bfs_paprd) { | 1891 | if (bf->bf_state.bfs_paprd) { |
| 1889 | if (!sc->paprd_pending) | 1892 | if (time_after(jiffies, |
| 1893 | bf->bf_state.bfs_paprd_timestamp + | ||
| 1894 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) | ||
| 1890 | dev_kfree_skb_any(skb); | 1895 | dev_kfree_skb_any(skb); |
| 1891 | else | 1896 | else |
| 1892 | complete(&sc->paprd_complete); | 1897 | complete(&sc->paprd_complete); |
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 939a0e96ed1..84866a4b835 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
| @@ -564,7 +564,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
| 564 | cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); | 564 | cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); |
| 565 | 565 | ||
| 566 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ | 566 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ |
| 567 | cam = !!(tim_ie->bitmap_ctrl & 0x01); | 567 | cam |= !!(tim_ie->bitmap_ctrl & 0x01); |
| 568 | 568 | ||
| 569 | if (!cam) { | 569 | if (!cam) { |
| 570 | /* back to low-power land. */ | 570 | /* back to low-power land. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a9b852be450..39b6f16c87f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
| @@ -402,72 +402,6 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv, | |||
| 402 | } | 402 | } |
| 403 | #endif | 403 | #endif |
| 404 | 404 | ||
| 405 | /** | ||
| 406 | * iwl3945_good_plcp_health - checks for plcp error. | ||
| 407 | * | ||
| 408 | * When the plcp error is exceeding the thresholds, reset the radio | ||
| 409 | * to improve the throughput. | ||
| 410 | */ | ||
| 411 | static bool iwl3945_good_plcp_health(struct iwl_priv *priv, | ||
| 412 | struct iwl_rx_packet *pkt) | ||
| 413 | { | ||
| 414 | bool rc = true; | ||
| 415 | struct iwl3945_notif_statistics current_stat; | ||
| 416 | int combined_plcp_delta; | ||
| 417 | unsigned int plcp_msec; | ||
| 418 | unsigned long plcp_received_jiffies; | ||
| 419 | |||
| 420 | if (priv->cfg->base_params->plcp_delta_threshold == | ||
| 421 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
| 422 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | ||
| 423 | return rc; | ||
| 424 | } | ||
| 425 | memcpy(¤t_stat, pkt->u.raw, sizeof(struct | ||
| 426 | iwl3945_notif_statistics)); | ||
| 427 | /* | ||
| 428 | * check for plcp_err and trigger radio reset if it exceeds | ||
| 429 | * the plcp error threshold plcp_delta. | ||
| 430 | */ | ||
| 431 | plcp_received_jiffies = jiffies; | ||
| 432 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
| 433 | (long) priv->plcp_jiffies); | ||
| 434 | priv->plcp_jiffies = plcp_received_jiffies; | ||
| 435 | /* | ||
| 436 | * check to make sure plcp_msec is not 0 to prevent division | ||
| 437 | * by zero. | ||
| 438 | */ | ||
| 439 | if (plcp_msec) { | ||
| 440 | combined_plcp_delta = | ||
| 441 | (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - | ||
| 442 | le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); | ||
| 443 | |||
| 444 | if ((combined_plcp_delta > 0) && | ||
| 445 | ((combined_plcp_delta * 100) / plcp_msec) > | ||
| 446 | priv->cfg->base_params->plcp_delta_threshold) { | ||
| 447 | /* | ||
| 448 | * if plcp_err exceed the threshold, the following | ||
| 449 | * data is printed in csv format: | ||
| 450 | * Text: plcp_err exceeded %d, | ||
| 451 | * Received ofdm.plcp_err, | ||
| 452 | * Current ofdm.plcp_err, | ||
| 453 | * combined_plcp_delta, | ||
| 454 | * plcp_msec | ||
| 455 | */ | ||
| 456 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||
| 457 | "%u, %d, %u mSecs\n", | ||
| 458 | priv->cfg->base_params->plcp_delta_threshold, | ||
| 459 | le32_to_cpu(current_stat.rx.ofdm.plcp_err), | ||
| 460 | combined_plcp_delta, plcp_msec); | ||
| 461 | /* | ||
| 462 | * Reset the RF radio due to the high plcp | ||
| 463 | * error rate | ||
| 464 | */ | ||
| 465 | rc = false; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | return rc; | ||
| 469 | } | ||
| 470 | |||
| 471 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 405 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
| 472 | struct iwl_rx_mem_buffer *rxb) | 406 | struct iwl_rx_mem_buffer *rxb) |
| 473 | { | 407 | { |
| @@ -2734,7 +2668,6 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
| 2734 | .isr_ops = { | 2668 | .isr_ops = { |
| 2735 | .isr = iwl_isr_legacy, | 2669 | .isr = iwl_isr_legacy, |
| 2736 | }, | 2670 | }, |
| 2737 | .check_plcp_health = iwl3945_good_plcp_health, | ||
| 2738 | 2671 | ||
| 2739 | .debugfs_ops = { | 2672 | .debugfs_ops = { |
| 2740 | .rx_stats_read = iwl3945_ucode_rx_stats_read, | 2673 | .rx_stats_read = iwl3945_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af505bcd7ae..ef36aff1bb4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
| @@ -681,6 +681,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
| 681 | .fw_name_pre = IWL6050_FW_PRE, \ | 681 | .fw_name_pre = IWL6050_FW_PRE, \ |
| 682 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ | 682 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ |
| 683 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ | 683 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ |
| 684 | .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ | ||
| 685 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ | ||
| 684 | .ops = &iwl6050_ops, \ | 686 | .ops = &iwl6050_ops, \ |
| 685 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 687 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
| 686 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 688 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36335b1b54d..c1cfd9952e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -1157,6 +1157,9 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
| 1157 | /* only Re-enable if disabled by irq */ | 1157 | /* only Re-enable if disabled by irq */ |
| 1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
| 1159 | iwl_enable_interrupts(priv); | 1159 | iwl_enable_interrupts(priv); |
| 1160 | /* Re-enable RF_KILL if it occurred */ | ||
| 1161 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
| 1162 | iwl_enable_rfkill_int(priv); | ||
| 1160 | 1163 | ||
| 1161 | #ifdef CONFIG_IWLWIFI_DEBUG | 1164 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 1162 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | 1165 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { |
| @@ -1371,6 +1374,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
| 1371 | /* only Re-enable if disabled by irq */ | 1374 | /* only Re-enable if disabled by irq */ |
| 1372 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1375 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
| 1373 | iwl_enable_interrupts(priv); | 1376 | iwl_enable_interrupts(priv); |
| 1377 | /* Re-enable RF_KILL if it occurred */ | ||
| 1378 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
| 1379 | iwl_enable_rfkill_int(priv); | ||
| 1374 | } | 1380 | } |
| 1375 | 1381 | ||
| 1376 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | 1382 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index b8433f3a9bc..62876cd5c41 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
| @@ -726,9 +726,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | |||
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | 728 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, |
| 729 | u8 efuse_data, u8 offset, int *bcontinual, | 729 | u8 efuse_data, u8 offset, int *bcontinual, |
| 730 | u8 *write_state, struct pgpkt_struct target_pkt, | 730 | u8 *write_state, struct pgpkt_struct *target_pkt, |
| 731 | int *repeat_times, int *bresult, u8 word_en) | 731 | int *repeat_times, int *bresult, u8 word_en) |
| 732 | { | 732 | { |
| 733 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 733 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 734 | struct pgpkt_struct tmp_pkt; | 734 | struct pgpkt_struct tmp_pkt; |
| @@ -744,8 +744,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 744 | tmp_pkt.word_en = tmp_header & 0x0F; | 744 | tmp_pkt.word_en = tmp_header & 0x0F; |
| 745 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); | 745 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); |
| 746 | 746 | ||
| 747 | if (tmp_pkt.offset != target_pkt.offset) { | 747 | if (tmp_pkt.offset != target_pkt->offset) { |
| 748 | efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; | 748 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
| 749 | *write_state = PG_STATE_HEADER; | 749 | *write_state = PG_STATE_HEADER; |
| 750 | } else { | 750 | } else { |
| 751 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { | 751 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { |
| @@ -756,23 +756,23 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | if (bdataempty == false) { | 758 | if (bdataempty == false) { |
| 759 | efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; | 759 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
| 760 | *write_state = PG_STATE_HEADER; | 760 | *write_state = PG_STATE_HEADER; |
| 761 | } else { | 761 | } else { |
| 762 | match_word_en = 0x0F; | 762 | match_word_en = 0x0F; |
| 763 | if (!((target_pkt.word_en & BIT(0)) | | 763 | if (!((target_pkt->word_en & BIT(0)) | |
| 764 | (tmp_pkt.word_en & BIT(0)))) | 764 | (tmp_pkt.word_en & BIT(0)))) |
| 765 | match_word_en &= (~BIT(0)); | 765 | match_word_en &= (~BIT(0)); |
| 766 | 766 | ||
| 767 | if (!((target_pkt.word_en & BIT(1)) | | 767 | if (!((target_pkt->word_en & BIT(1)) | |
| 768 | (tmp_pkt.word_en & BIT(1)))) | 768 | (tmp_pkt.word_en & BIT(1)))) |
| 769 | match_word_en &= (~BIT(1)); | 769 | match_word_en &= (~BIT(1)); |
| 770 | 770 | ||
| 771 | if (!((target_pkt.word_en & BIT(2)) | | 771 | if (!((target_pkt->word_en & BIT(2)) | |
| 772 | (tmp_pkt.word_en & BIT(2)))) | 772 | (tmp_pkt.word_en & BIT(2)))) |
| 773 | match_word_en &= (~BIT(2)); | 773 | match_word_en &= (~BIT(2)); |
| 774 | 774 | ||
| 775 | if (!((target_pkt.word_en & BIT(3)) | | 775 | if (!((target_pkt->word_en & BIT(3)) | |
| 776 | (tmp_pkt.word_en & BIT(3)))) | 776 | (tmp_pkt.word_en & BIT(3)))) |
| 777 | match_word_en &= (~BIT(3)); | 777 | match_word_en &= (~BIT(3)); |
| 778 | 778 | ||
| @@ -780,7 +780,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 780 | badworden = efuse_word_enable_data_write( | 780 | badworden = efuse_word_enable_data_write( |
| 781 | hw, *efuse_addr + 1, | 781 | hw, *efuse_addr + 1, |
| 782 | tmp_pkt.word_en, | 782 | tmp_pkt.word_en, |
| 783 | target_pkt.data); | 783 | target_pkt->data); |
| 784 | 784 | ||
| 785 | if (0x0F != (badworden & 0x0F)) { | 785 | if (0x0F != (badworden & 0x0F)) { |
| 786 | u8 reorg_offset = offset; | 786 | u8 reorg_offset = offset; |
| @@ -791,26 +791,26 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | tmp_word_en = 0x0F; | 793 | tmp_word_en = 0x0F; |
| 794 | if ((target_pkt.word_en & BIT(0)) ^ | 794 | if ((target_pkt->word_en & BIT(0)) ^ |
| 795 | (match_word_en & BIT(0))) | 795 | (match_word_en & BIT(0))) |
| 796 | tmp_word_en &= (~BIT(0)); | 796 | tmp_word_en &= (~BIT(0)); |
| 797 | 797 | ||
| 798 | if ((target_pkt.word_en & BIT(1)) ^ | 798 | if ((target_pkt->word_en & BIT(1)) ^ |
| 799 | (match_word_en & BIT(1))) | 799 | (match_word_en & BIT(1))) |
| 800 | tmp_word_en &= (~BIT(1)); | 800 | tmp_word_en &= (~BIT(1)); |
| 801 | 801 | ||
| 802 | if ((target_pkt.word_en & BIT(2)) ^ | 802 | if ((target_pkt->word_en & BIT(2)) ^ |
| 803 | (match_word_en & BIT(2))) | 803 | (match_word_en & BIT(2))) |
| 804 | tmp_word_en &= (~BIT(2)); | 804 | tmp_word_en &= (~BIT(2)); |
| 805 | 805 | ||
| 806 | if ((target_pkt.word_en & BIT(3)) ^ | 806 | if ((target_pkt->word_en & BIT(3)) ^ |
| 807 | (match_word_en & BIT(3))) | 807 | (match_word_en & BIT(3))) |
| 808 | tmp_word_en &= (~BIT(3)); | 808 | tmp_word_en &= (~BIT(3)); |
| 809 | 809 | ||
| 810 | if ((tmp_word_en & 0x0F) != 0x0F) { | 810 | if ((tmp_word_en & 0x0F) != 0x0F) { |
| 811 | *efuse_addr = efuse_get_current_size(hw); | 811 | *efuse_addr = efuse_get_current_size(hw); |
| 812 | target_pkt.offset = offset; | 812 | target_pkt->offset = offset; |
| 813 | target_pkt.word_en = tmp_word_en; | 813 | target_pkt->word_en = tmp_word_en; |
| 814 | } else | 814 | } else |
| 815 | *bcontinual = false; | 815 | *bcontinual = false; |
| 816 | *write_state = PG_STATE_HEADER; | 816 | *write_state = PG_STATE_HEADER; |
| @@ -821,8 +821,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 821 | } | 821 | } |
| 822 | } else { | 822 | } else { |
| 823 | *efuse_addr += (2 * tmp_word_cnts) + 1; | 823 | *efuse_addr += (2 * tmp_word_cnts) + 1; |
| 824 | target_pkt.offset = offset; | 824 | target_pkt->offset = offset; |
| 825 | target_pkt.word_en = word_en; | 825 | target_pkt->word_en = word_en; |
| 826 | *write_state = PG_STATE_HEADER; | 826 | *write_state = PG_STATE_HEADER; |
| 827 | } | 827 | } |
| 828 | } | 828 | } |
| @@ -938,7 +938,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
| 938 | efuse_write_data_case1(hw, &efuse_addr, | 938 | efuse_write_data_case1(hw, &efuse_addr, |
| 939 | efuse_data, offset, | 939 | efuse_data, offset, |
| 940 | &bcontinual, | 940 | &bcontinual, |
| 941 | &write_state, target_pkt, | 941 | &write_state, &target_pkt, |
| 942 | &repeat_times, &bresult, | 942 | &repeat_times, &bresult, |
| 943 | word_en); | 943 | word_en); |
| 944 | else | 944 | else |
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 012e1a4016f..40372bac948 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c | |||
| @@ -1039,6 +1039,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1039 | 1039 | ||
| 1040 | if (changed & BSS_CHANGED_BEACON) { | 1040 | if (changed & BSS_CHANGED_BEACON) { |
| 1041 | beacon = ieee80211_beacon_get(hw, vif); | 1041 | beacon = ieee80211_beacon_get(hw, vif); |
| 1042 | if (!beacon) | ||
| 1043 | goto out_sleep; | ||
| 1044 | |||
| 1042 | ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, | 1045 | ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, |
| 1043 | beacon->len); | 1046 | beacon->len); |
| 1044 | 1047 | ||
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 46714910f98..7145ea54378 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
| @@ -110,9 +110,8 @@ static void wl1271_spi_reset(struct wl1271 *wl) | |||
| 110 | spi_message_add_tail(&t, &m); | 110 | spi_message_add_tail(&t, &m); |
| 111 | 111 | ||
| 112 | spi_sync(wl_to_spi(wl), &m); | 112 | spi_sync(wl_to_spi(wl), &m); |
| 113 | kfree(cmd); | ||
| 114 | |||
| 115 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); | 113 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); |
| 114 | kfree(cmd); | ||
| 116 | } | 115 | } |
| 117 | 116 | ||
| 118 | static void wl1271_spi_init(struct wl1271 *wl) | 117 | static void wl1271_spi_init(struct wl1271 *wl) |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 546de574982..da1f1212034 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -120,6 +120,9 @@ struct netfront_info { | |||
| 120 | unsigned long rx_pfn_array[NET_RX_RING_SIZE]; | 120 | unsigned long rx_pfn_array[NET_RX_RING_SIZE]; |
| 121 | struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; | 121 | struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; |
| 122 | struct mmu_update rx_mmu[NET_RX_RING_SIZE]; | 122 | struct mmu_update rx_mmu[NET_RX_RING_SIZE]; |
| 123 | |||
| 124 | /* Statistics */ | ||
| 125 | int rx_gso_checksum_fixup; | ||
| 123 | }; | 126 | }; |
| 124 | 127 | ||
| 125 | struct netfront_rx_info { | 128 | struct netfront_rx_info { |
| @@ -770,11 +773,29 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np, | |||
| 770 | return cons; | 773 | return cons; |
| 771 | } | 774 | } |
| 772 | 775 | ||
| 773 | static int skb_checksum_setup(struct sk_buff *skb) | 776 | static int checksum_setup(struct net_device *dev, struct sk_buff *skb) |
| 774 | { | 777 | { |
| 775 | struct iphdr *iph; | 778 | struct iphdr *iph; |
| 776 | unsigned char *th; | 779 | unsigned char *th; |
| 777 | int err = -EPROTO; | 780 | int err = -EPROTO; |
| 781 | int recalculate_partial_csum = 0; | ||
| 782 | |||
| 783 | /* | ||
| 784 | * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy | ||
| 785 | * peers can fail to set NETRXF_csum_blank when sending a GSO | ||
| 786 | * frame. In this case force the SKB to CHECKSUM_PARTIAL and | ||
| 787 | * recalculate the partial checksum. | ||
| 788 | */ | ||
| 789 | if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { | ||
| 790 | struct netfront_info *np = netdev_priv(dev); | ||
| 791 | np->rx_gso_checksum_fixup++; | ||
| 792 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
| 793 | recalculate_partial_csum = 1; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ | ||
| 797 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
| 798 | return 0; | ||
| 778 | 799 | ||
| 779 | if (skb->protocol != htons(ETH_P_IP)) | 800 | if (skb->protocol != htons(ETH_P_IP)) |
| 780 | goto out; | 801 | goto out; |
| @@ -788,9 +809,23 @@ static int skb_checksum_setup(struct sk_buff *skb) | |||
| 788 | switch (iph->protocol) { | 809 | switch (iph->protocol) { |
| 789 | case IPPROTO_TCP: | 810 | case IPPROTO_TCP: |
| 790 | skb->csum_offset = offsetof(struct tcphdr, check); | 811 | skb->csum_offset = offsetof(struct tcphdr, check); |
| 812 | |||
| 813 | if (recalculate_partial_csum) { | ||
| 814 | struct tcphdr *tcph = (struct tcphdr *)th; | ||
| 815 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 816 | skb->len - iph->ihl*4, | ||
| 817 | IPPROTO_TCP, 0); | ||
| 818 | } | ||
| 791 | break; | 819 | break; |
| 792 | case IPPROTO_UDP: | 820 | case IPPROTO_UDP: |
| 793 | skb->csum_offset = offsetof(struct udphdr, check); | 821 | skb->csum_offset = offsetof(struct udphdr, check); |
| 822 | |||
| 823 | if (recalculate_partial_csum) { | ||
| 824 | struct udphdr *udph = (struct udphdr *)th; | ||
| 825 | udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 826 | skb->len - iph->ihl*4, | ||
| 827 | IPPROTO_UDP, 0); | ||
| 828 | } | ||
| 794 | break; | 829 | break; |
| 795 | default: | 830 | default: |
| 796 | if (net_ratelimit()) | 831 | if (net_ratelimit()) |
| @@ -829,13 +864,11 @@ static int handle_incoming_queue(struct net_device *dev, | |||
| 829 | /* Ethernet work: Delayed to here as it peeks the header. */ | 864 | /* Ethernet work: Delayed to here as it peeks the header. */ |
| 830 | skb->protocol = eth_type_trans(skb, dev); | 865 | skb->protocol = eth_type_trans(skb, dev); |
| 831 | 866 | ||
| 832 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 867 | if (checksum_setup(dev, skb)) { |
| 833 | if (skb_checksum_setup(skb)) { | 868 | kfree_skb(skb); |
| 834 | kfree_skb(skb); | 869 | packets_dropped++; |
| 835 | packets_dropped++; | 870 | dev->stats.rx_errors++; |
| 836 | dev->stats.rx_errors++; | 871 | continue; |
| 837 | continue; | ||
| 838 | } | ||
| 839 | } | 872 | } |
| 840 | 873 | ||
| 841 | dev->stats.rx_packets++; | 874 | dev->stats.rx_packets++; |
| @@ -1632,12 +1665,59 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1632 | } | 1665 | } |
| 1633 | } | 1666 | } |
| 1634 | 1667 | ||
| 1668 | static const struct xennet_stat { | ||
| 1669 | char name[ETH_GSTRING_LEN]; | ||
| 1670 | u16 offset; | ||
| 1671 | } xennet_stats[] = { | ||
| 1672 | { | ||
| 1673 | "rx_gso_checksum_fixup", | ||
| 1674 | offsetof(struct netfront_info, rx_gso_checksum_fixup) | ||
| 1675 | }, | ||
| 1676 | }; | ||
| 1677 | |||
| 1678 | static int xennet_get_sset_count(struct net_device *dev, int string_set) | ||
| 1679 | { | ||
| 1680 | switch (string_set) { | ||
| 1681 | case ETH_SS_STATS: | ||
| 1682 | return ARRAY_SIZE(xennet_stats); | ||
| 1683 | default: | ||
| 1684 | return -EINVAL; | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | static void xennet_get_ethtool_stats(struct net_device *dev, | ||
| 1689 | struct ethtool_stats *stats, u64 * data) | ||
| 1690 | { | ||
| 1691 | void *np = netdev_priv(dev); | ||
| 1692 | int i; | ||
| 1693 | |||
| 1694 | for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) | ||
| 1695 | data[i] = *(int *)(np + xennet_stats[i].offset); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data) | ||
| 1699 | { | ||
| 1700 | int i; | ||
| 1701 | |||
| 1702 | switch (stringset) { | ||
| 1703 | case ETH_SS_STATS: | ||
| 1704 | for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) | ||
| 1705 | memcpy(data + i * ETH_GSTRING_LEN, | ||
| 1706 | xennet_stats[i].name, ETH_GSTRING_LEN); | ||
| 1707 | break; | ||
| 1708 | } | ||
| 1709 | } | ||
| 1710 | |||
| 1635 | static const struct ethtool_ops xennet_ethtool_ops = | 1711 | static const struct ethtool_ops xennet_ethtool_ops = |
| 1636 | { | 1712 | { |
| 1637 | .set_tx_csum = ethtool_op_set_tx_csum, | 1713 | .set_tx_csum = ethtool_op_set_tx_csum, |
| 1638 | .set_sg = xennet_set_sg, | 1714 | .set_sg = xennet_set_sg, |
| 1639 | .set_tso = xennet_set_tso, | 1715 | .set_tso = xennet_set_tso, |
| 1640 | .get_link = ethtool_op_get_link, | 1716 | .get_link = ethtool_op_get_link, |
| 1717 | |||
| 1718 | .get_sset_count = xennet_get_sset_count, | ||
| 1719 | .get_ethtool_stats = xennet_get_ethtool_stats, | ||
| 1720 | .get_strings = xennet_get_strings, | ||
| 1641 | }; | 1721 | }; |
| 1642 | 1722 | ||
| 1643 | #ifdef CONFIG_SYSFS | 1723 | #ifdef CONFIG_SYSFS |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 8ecaac98392..ea25e5bfcf2 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
| 25 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
| 26 | #include <linux/security.h> | ||
| 26 | #include <linux/pci-aspm.h> | 27 | #include <linux/pci-aspm.h> |
| 27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 28 | #include "pci.h" | 29 | #include "pci.h" |
| @@ -368,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
| 368 | u8 *data = (u8*) buf; | 369 | u8 *data = (u8*) buf; |
| 369 | 370 | ||
| 370 | /* Several chips lock up trying to read undefined config space */ | 371 | /* Several chips lock up trying to read undefined config space */ |
| 371 | if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) { | 372 | if (security_capable(filp->f_cred, CAP_SYS_ADMIN) == 0) { |
| 372 | size = dev->cfg_size; | 373 | size = dev->cfg_size; |
| 373 | } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 374 | } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
| 374 | size = 128; | 375 | size = 128; |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index c086fc30a84..242bbf86c74 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
| @@ -81,12 +81,16 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
| 81 | 81 | ||
| 82 | static int rtc_proc_open(struct inode *inode, struct file *file) | 82 | static int rtc_proc_open(struct inode *inode, struct file *file) |
| 83 | { | 83 | { |
| 84 | int ret; | ||
| 84 | struct rtc_device *rtc = PDE(inode)->data; | 85 | struct rtc_device *rtc = PDE(inode)->data; |
| 85 | 86 | ||
| 86 | if (!try_module_get(THIS_MODULE)) | 87 | if (!try_module_get(THIS_MODULE)) |
| 87 | return -ENODEV; | 88 | return -ENODEV; |
| 88 | 89 | ||
| 89 | return single_open(file, rtc_proc_show, rtc); | 90 | ret = single_open(file, rtc_proc_show, rtc); |
| 91 | if (ret) | ||
| 92 | module_put(THIS_MODULE); | ||
| 93 | return ret; | ||
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | static int rtc_proc_release(struct inode *inode, struct file *file) | 96 | static int rtc_proc_release(struct inode *inode, struct file *file) |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 65ebee0a326..b6a6356d09b 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
| @@ -565,7 +565,7 @@ static int netiucv_callback_connreq(struct iucv_path *path, | |||
| 565 | struct iucv_event ev; | 565 | struct iucv_event ev; |
| 566 | int rc; | 566 | int rc; |
| 567 | 567 | ||
| 568 | if (memcmp(iucvMagic, ipuser, sizeof(ipuser))) | 568 | if (memcmp(iucvMagic, ipuser, 16)) |
| 569 | /* ipuser must match iucvMagic. */ | 569 | /* ipuser must match iucvMagic. */ |
| 570 | return -EINVAL; | 570 | return -EINVAL; |
| 571 | rc = -EINVAL; | 571 | rc = -EINVAL; |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 29f848bfc12..019ae58ab91 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -988,16 +988,30 @@ static void qeth_get_channel_path_desc(struct qeth_card *card) | |||
| 988 | chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); | 988 | chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); |
| 989 | if (chp_dsc != NULL) { | 989 | if (chp_dsc != NULL) { |
| 990 | /* CHPP field bit 6 == 1 -> single queue */ | 990 | /* CHPP field bit 6 == 1 -> single queue */ |
| 991 | if ((chp_dsc->chpp & 0x02) == 0x02) | 991 | if ((chp_dsc->chpp & 0x02) == 0x02) { |
| 992 | if ((atomic_read(&card->qdio.state) != | ||
| 993 | QETH_QDIO_UNINITIALIZED) && | ||
| 994 | (card->qdio.no_out_queues == 4)) | ||
| 995 | /* change from 4 to 1 outbound queues */ | ||
| 996 | qeth_free_qdio_buffers(card); | ||
| 992 | card->qdio.no_out_queues = 1; | 997 | card->qdio.no_out_queues = 1; |
| 998 | if (card->qdio.default_out_queue != 0) | ||
| 999 | dev_info(&card->gdev->dev, | ||
| 1000 | "Priority Queueing not supported\n"); | ||
| 1001 | card->qdio.default_out_queue = 0; | ||
| 1002 | } else { | ||
| 1003 | if ((atomic_read(&card->qdio.state) != | ||
| 1004 | QETH_QDIO_UNINITIALIZED) && | ||
| 1005 | (card->qdio.no_out_queues == 1)) { | ||
| 1006 | /* change from 1 to 4 outbound queues */ | ||
| 1007 | qeth_free_qdio_buffers(card); | ||
| 1008 | card->qdio.default_out_queue = 2; | ||
| 1009 | } | ||
| 1010 | card->qdio.no_out_queues = 4; | ||
| 1011 | } | ||
| 993 | card->info.func_level = 0x4100 + chp_dsc->desc; | 1012 | card->info.func_level = 0x4100 + chp_dsc->desc; |
| 994 | kfree(chp_dsc); | 1013 | kfree(chp_dsc); |
| 995 | } | 1014 | } |
| 996 | if (card->qdio.no_out_queues == 1) { | ||
| 997 | card->qdio.default_out_queue = 0; | ||
| 998 | dev_info(&card->gdev->dev, | ||
| 999 | "Priority Queueing not supported\n"); | ||
| 1000 | } | ||
| 1001 | QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); | 1015 | QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); |
| 1002 | QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); | 1016 | QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); |
| 1003 | return; | 1017 | return; |
| @@ -1832,33 +1846,6 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card) | |||
| 1832 | } | 1846 | } |
| 1833 | } | 1847 | } |
| 1834 | 1848 | ||
| 1835 | static inline int qeth_get_max_mtu_for_card(int cardtype) | ||
| 1836 | { | ||
| 1837 | switch (cardtype) { | ||
| 1838 | |||
| 1839 | case QETH_CARD_TYPE_UNKNOWN: | ||
| 1840 | case QETH_CARD_TYPE_OSD: | ||
| 1841 | case QETH_CARD_TYPE_OSN: | ||
| 1842 | case QETH_CARD_TYPE_OSM: | ||
| 1843 | case QETH_CARD_TYPE_OSX: | ||
| 1844 | return 61440; | ||
| 1845 | case QETH_CARD_TYPE_IQD: | ||
| 1846 | return 57344; | ||
| 1847 | default: | ||
| 1848 | return 1500; | ||
| 1849 | } | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | static inline int qeth_get_mtu_out_of_mpc(int cardtype) | ||
| 1853 | { | ||
| 1854 | switch (cardtype) { | ||
| 1855 | case QETH_CARD_TYPE_IQD: | ||
| 1856 | return 1; | ||
| 1857 | default: | ||
| 1858 | return 0; | ||
| 1859 | } | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | static inline int qeth_get_mtu_outof_framesize(int framesize) | 1849 | static inline int qeth_get_mtu_outof_framesize(int framesize) |
| 1863 | { | 1850 | { |
| 1864 | switch (framesize) { | 1851 | switch (framesize) { |
| @@ -1881,10 +1868,9 @@ static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu) | |||
| 1881 | case QETH_CARD_TYPE_OSD: | 1868 | case QETH_CARD_TYPE_OSD: |
| 1882 | case QETH_CARD_TYPE_OSM: | 1869 | case QETH_CARD_TYPE_OSM: |
| 1883 | case QETH_CARD_TYPE_OSX: | 1870 | case QETH_CARD_TYPE_OSX: |
| 1884 | return ((mtu >= 576) && (mtu <= 61440)); | ||
| 1885 | case QETH_CARD_TYPE_IQD: | 1871 | case QETH_CARD_TYPE_IQD: |
| 1886 | return ((mtu >= 576) && | 1872 | return ((mtu >= 576) && |
| 1887 | (mtu <= card->info.max_mtu + 4096 - 32)); | 1873 | (mtu <= card->info.max_mtu)); |
| 1888 | case QETH_CARD_TYPE_OSN: | 1874 | case QETH_CARD_TYPE_OSN: |
| 1889 | case QETH_CARD_TYPE_UNKNOWN: | 1875 | case QETH_CARD_TYPE_UNKNOWN: |
| 1890 | default: | 1876 | default: |
| @@ -1907,7 +1893,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
| 1907 | memcpy(&card->token.ulp_filter_r, | 1893 | memcpy(&card->token.ulp_filter_r, |
| 1908 | QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data), | 1894 | QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data), |
| 1909 | QETH_MPC_TOKEN_LENGTH); | 1895 | QETH_MPC_TOKEN_LENGTH); |
| 1910 | if (qeth_get_mtu_out_of_mpc(card->info.type)) { | 1896 | if (card->info.type == QETH_CARD_TYPE_IQD) { |
| 1911 | memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2); | 1897 | memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2); |
| 1912 | mtu = qeth_get_mtu_outof_framesize(framesize); | 1898 | mtu = qeth_get_mtu_outof_framesize(framesize); |
| 1913 | if (!mtu) { | 1899 | if (!mtu) { |
| @@ -1915,12 +1901,21 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
| 1915 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); | 1901 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); |
| 1916 | return 0; | 1902 | return 0; |
| 1917 | } | 1903 | } |
| 1918 | card->info.max_mtu = mtu; | 1904 | if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) { |
| 1905 | /* frame size has changed */ | ||
| 1906 | if (card->dev && | ||
| 1907 | ((card->dev->mtu == card->info.initial_mtu) || | ||
| 1908 | (card->dev->mtu > mtu))) | ||
| 1909 | card->dev->mtu = mtu; | ||
| 1910 | qeth_free_qdio_buffers(card); | ||
| 1911 | } | ||
| 1919 | card->info.initial_mtu = mtu; | 1912 | card->info.initial_mtu = mtu; |
| 1913 | card->info.max_mtu = mtu; | ||
| 1920 | card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE; | 1914 | card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE; |
| 1921 | } else { | 1915 | } else { |
| 1922 | card->info.initial_mtu = qeth_get_initial_mtu_for_card(card); | 1916 | card->info.initial_mtu = qeth_get_initial_mtu_for_card(card); |
| 1923 | card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type); | 1917 | card->info.max_mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU( |
| 1918 | iob->data); | ||
| 1924 | card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; | 1919 | card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; |
| 1925 | } | 1920 | } |
| 1926 | 1921 | ||
| @@ -3775,6 +3770,47 @@ static inline int qeth_get_qdio_q_format(struct qeth_card *card) | |||
| 3775 | } | 3770 | } |
| 3776 | } | 3771 | } |
| 3777 | 3772 | ||
| 3773 | static void qeth_determine_capabilities(struct qeth_card *card) | ||
| 3774 | { | ||
| 3775 | int rc; | ||
| 3776 | int length; | ||
| 3777 | char *prcd; | ||
| 3778 | struct ccw_device *ddev; | ||
| 3779 | int ddev_offline = 0; | ||
| 3780 | |||
| 3781 | QETH_DBF_TEXT(SETUP, 2, "detcapab"); | ||
| 3782 | ddev = CARD_DDEV(card); | ||
| 3783 | if (!ddev->online) { | ||
| 3784 | ddev_offline = 1; | ||
| 3785 | rc = ccw_device_set_online(ddev); | ||
| 3786 | if (rc) { | ||
| 3787 | QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); | ||
| 3788 | goto out; | ||
| 3789 | } | ||
| 3790 | } | ||
| 3791 | |||
| 3792 | rc = qeth_read_conf_data(card, (void **) &prcd, &length); | ||
| 3793 | if (rc) { | ||
| 3794 | QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", | ||
| 3795 | dev_name(&card->gdev->dev), rc); | ||
| 3796 | QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); | ||
| 3797 | goto out_offline; | ||
| 3798 | } | ||
| 3799 | qeth_configure_unitaddr(card, prcd); | ||
| 3800 | qeth_configure_blkt_default(card, prcd); | ||
| 3801 | kfree(prcd); | ||
| 3802 | |||
| 3803 | rc = qdio_get_ssqd_desc(ddev, &card->ssqd); | ||
| 3804 | if (rc) | ||
| 3805 | QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); | ||
| 3806 | |||
| 3807 | out_offline: | ||
| 3808 | if (ddev_offline == 1) | ||
| 3809 | ccw_device_set_offline(ddev); | ||
| 3810 | out: | ||
| 3811 | return; | ||
| 3812 | } | ||
| 3813 | |||
| 3778 | static int qeth_qdio_establish(struct qeth_card *card) | 3814 | static int qeth_qdio_establish(struct qeth_card *card) |
| 3779 | { | 3815 | { |
| 3780 | struct qdio_initialize init_data; | 3816 | struct qdio_initialize init_data; |
| @@ -3905,6 +3941,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card) | |||
| 3905 | 3941 | ||
| 3906 | QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); | 3942 | QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); |
| 3907 | atomic_set(&card->force_alloc_skb, 0); | 3943 | atomic_set(&card->force_alloc_skb, 0); |
| 3944 | qeth_get_channel_path_desc(card); | ||
| 3908 | retry: | 3945 | retry: |
| 3909 | if (retries) | 3946 | if (retries) |
| 3910 | QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", | 3947 | QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", |
| @@ -3933,6 +3970,7 @@ retriable: | |||
| 3933 | else | 3970 | else |
| 3934 | goto retry; | 3971 | goto retry; |
| 3935 | } | 3972 | } |
| 3973 | qeth_determine_capabilities(card); | ||
| 3936 | qeth_init_tokens(card); | 3974 | qeth_init_tokens(card); |
| 3937 | qeth_init_func_level(card); | 3975 | qeth_init_func_level(card); |
| 3938 | rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); | 3976 | rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); |
| @@ -4202,41 +4240,6 @@ void qeth_core_free_discipline(struct qeth_card *card) | |||
| 4202 | card->discipline.ccwgdriver = NULL; | 4240 | card->discipline.ccwgdriver = NULL; |
| 4203 | } | 4241 | } |
| 4204 | 4242 | ||
| 4205 | static void qeth_determine_capabilities(struct qeth_card *card) | ||
| 4206 | { | ||
| 4207 | int rc; | ||
| 4208 | int length; | ||
| 4209 | char *prcd; | ||
| 4210 | |||
| 4211 | QETH_DBF_TEXT(SETUP, 2, "detcapab"); | ||
| 4212 | rc = ccw_device_set_online(CARD_DDEV(card)); | ||
| 4213 | if (rc) { | ||
| 4214 | QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); | ||
| 4215 | goto out; | ||
| 4216 | } | ||
| 4217 | |||
| 4218 | |||
| 4219 | rc = qeth_read_conf_data(card, (void **) &prcd, &length); | ||
| 4220 | if (rc) { | ||
| 4221 | QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", | ||
| 4222 | dev_name(&card->gdev->dev), rc); | ||
| 4223 | QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); | ||
| 4224 | goto out_offline; | ||
| 4225 | } | ||
| 4226 | qeth_configure_unitaddr(card, prcd); | ||
| 4227 | qeth_configure_blkt_default(card, prcd); | ||
| 4228 | kfree(prcd); | ||
| 4229 | |||
| 4230 | rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); | ||
| 4231 | if (rc) | ||
| 4232 | QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); | ||
| 4233 | |||
| 4234 | out_offline: | ||
| 4235 | ccw_device_set_offline(CARD_DDEV(card)); | ||
| 4236 | out: | ||
| 4237 | return; | ||
| 4238 | } | ||
| 4239 | |||
| 4240 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) | 4243 | static int qeth_core_probe_device(struct ccwgroup_device *gdev) |
| 4241 | { | 4244 | { |
| 4242 | struct qeth_card *card; | 4245 | struct qeth_card *card; |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2ac8f6aff5a..ada0fe78237 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
| @@ -573,13 +573,13 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card, | |||
| 573 | case IPA_RC_L2_DUP_LAYER3_MAC: | 573 | case IPA_RC_L2_DUP_LAYER3_MAC: |
| 574 | dev_warn(&card->gdev->dev, | 574 | dev_warn(&card->gdev->dev, |
| 575 | "MAC address %pM already exists\n", | 575 | "MAC address %pM already exists\n", |
| 576 | card->dev->dev_addr); | 576 | cmd->data.setdelmac.mac); |
| 577 | break; | 577 | break; |
| 578 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | 578 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: |
| 579 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | 579 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: |
| 580 | dev_warn(&card->gdev->dev, | 580 | dev_warn(&card->gdev->dev, |
| 581 | "MAC address %pM is not authorized\n", | 581 | "MAC address %pM is not authorized\n", |
| 582 | card->dev->dev_addr); | 582 | cmd->data.setdelmac.mac); |
| 583 | break; | 583 | break; |
| 584 | default: | 584 | default: |
| 585 | break; | 585 | break; |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 65e1cf10494..207b7d74244 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
| @@ -60,7 +60,7 @@ static struct iucv_handler smsg_handler = { | |||
| 60 | static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], | 60 | static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], |
| 61 | u8 ipuser[16]) | 61 | u8 ipuser[16]) |
| 62 | { | 62 | { |
| 63 | if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0) | 63 | if (strncmp(ipvmid, "*MSG ", 8) != 0) |
| 64 | return -EINVAL; | 64 | return -EINVAL; |
| 65 | /* Path pending from *MSG. */ | 65 | /* Path pending from *MSG. */ |
| 66 | return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); | 66 | return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); |
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 475c31ae985..77b26f5b9c3 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** O.S : Linux | 3 | ** O.S : Linux |
| 4 | ** FILE NAME : arcmsr.h | 4 | ** FILE NAME : arcmsr.h |
| 5 | ** BY : Erich Chen | 5 | ** BY : Nick Cheng |
| 6 | ** Description: SCSI RAID Device Driver for | 6 | ** Description: SCSI RAID Device Driver for |
| 7 | ** ARECA RAID Host adapter | 7 | ** ARECA RAID Host adapter |
| 8 | ******************************************************************************* | 8 | ******************************************************************************* |
| @@ -46,8 +46,12 @@ | |||
| 46 | struct device_attribute; | 46 | struct device_attribute; |
| 47 | /*The limit of outstanding scsi command that firmware can handle*/ | 47 | /*The limit of outstanding scsi command that firmware can handle*/ |
| 48 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 | 48 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 |
| 49 | #define ARCMSR_MAX_FREECCB_NUM 320 | 49 | #ifdef CONFIG_XEN |
| 50 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/02/02" | 50 | #define ARCMSR_MAX_FREECCB_NUM 160 |
| 51 | #else | ||
| 52 | #define ARCMSR_MAX_FREECCB_NUM 320 | ||
| 53 | #endif | ||
| 54 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/08/05" | ||
| 51 | #define ARCMSR_SCSI_INITIATOR_ID 255 | 55 | #define ARCMSR_SCSI_INITIATOR_ID 255 |
| 52 | #define ARCMSR_MAX_XFER_SECTORS 512 | 56 | #define ARCMSR_MAX_XFER_SECTORS 512 |
| 53 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 | 57 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 |
| @@ -60,7 +64,6 @@ struct device_attribute; | |||
| 60 | #define ARCMSR_MAX_HBB_POSTQUEUE 264 | 64 | #define ARCMSR_MAX_HBB_POSTQUEUE 264 |
| 61 | #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ | 65 | #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ |
| 62 | #define ARCMSR_CDB_SG_PAGE_LENGTH 256 | 66 | #define ARCMSR_CDB_SG_PAGE_LENGTH 256 |
| 63 | #define SCSI_CMD_ARECA_SPECIFIC 0xE1 | ||
| 64 | #ifndef PCI_DEVICE_ID_ARECA_1880 | 67 | #ifndef PCI_DEVICE_ID_ARECA_1880 |
| 65 | #define PCI_DEVICE_ID_ARECA_1880 0x1880 | 68 | #define PCI_DEVICE_ID_ARECA_1880 0x1880 |
| 66 | #endif | 69 | #endif |
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index a4e04c50c43..acdae33de52 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** O.S : Linux | 3 | ** O.S : Linux |
| 4 | ** FILE NAME : arcmsr_attr.c | 4 | ** FILE NAME : arcmsr_attr.c |
| 5 | ** BY : Erich Chen | 5 | ** BY : Nick Cheng |
| 6 | ** Description: attributes exported to sysfs and device host | 6 | ** Description: attributes exported to sysfs and device host |
| 7 | ******************************************************************************* | 7 | ******************************************************************************* |
| 8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved | 8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved |
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 1cadcd6b7da..984bd527c6c 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** O.S : Linux | 3 | ** O.S : Linux |
| 4 | ** FILE NAME : arcmsr_hba.c | 4 | ** FILE NAME : arcmsr_hba.c |
| 5 | ** BY : Erich Chen | 5 | ** BY : Nick Cheng |
| 6 | ** Description: SCSI RAID Device Driver for | 6 | ** Description: SCSI RAID Device Driver for |
| 7 | ** ARECA RAID Host adapter | 7 | ** ARECA RAID Host adapter |
| 8 | ******************************************************************************* | 8 | ******************************************************************************* |
| @@ -76,7 +76,7 @@ MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapte | |||
| 76 | MODULE_LICENSE("Dual BSD/GPL"); | 76 | MODULE_LICENSE("Dual BSD/GPL"); |
| 77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); | 77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); |
| 78 | static int sleeptime = 10; | 78 | static int sleeptime = 10; |
| 79 | static int retrycount = 30; | 79 | static int retrycount = 12; |
| 80 | wait_queue_head_t wait_q; | 80 | wait_queue_head_t wait_q; |
| 81 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, | 81 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, |
| 82 | struct scsi_cmnd *cmd); | 82 | struct scsi_cmnd *cmd); |
| @@ -187,7 +187,6 @@ int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd) | |||
| 187 | if (isleep > 0) { | 187 | if (isleep > 0) { |
| 188 | msleep(isleep*1000); | 188 | msleep(isleep*1000); |
| 189 | } | 189 | } |
| 190 | printk(KERN_NOTICE "wake-up\n"); | ||
| 191 | return 0; | 190 | return 0; |
| 192 | } | 191 | } |
| 193 | 192 | ||
| @@ -921,7 +920,6 @@ static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, | |||
| 921 | } | 920 | } |
| 922 | 921 | ||
| 923 | static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error) | 922 | static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error) |
| 924 | |||
| 925 | { | 923 | { |
| 926 | int id, lun; | 924 | int id, lun; |
| 927 | if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) { | 925 | if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) { |
| @@ -948,7 +946,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct Comma | |||
| 948 | , pCCB->startdone | 946 | , pCCB->startdone |
| 949 | , atomic_read(&acb->ccboutstandingcount)); | 947 | , atomic_read(&acb->ccboutstandingcount)); |
| 950 | return; | 948 | return; |
| 951 | } | 949 | } |
| 952 | arcmsr_report_ccb_state(acb, pCCB, error); | 950 | arcmsr_report_ccb_state(acb, pCCB, error); |
| 953 | } | 951 | } |
| 954 | 952 | ||
| @@ -981,7 +979,7 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | |||
| 981 | case ACB_ADAPTER_TYPE_B: { | 979 | case ACB_ADAPTER_TYPE_B: { |
| 982 | struct MessageUnit_B *reg = acb->pmuB; | 980 | struct MessageUnit_B *reg = acb->pmuB; |
| 983 | /*clear all outbound posted Q*/ | 981 | /*clear all outbound posted Q*/ |
| 984 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, ®->iop2drv_doorbell); /* clear doorbell interrupt */ | 982 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); /* clear doorbell interrupt */ |
| 985 | for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { | 983 | for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { |
| 986 | if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { | 984 | if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { |
| 987 | writel(0, ®->done_qbuffer[i]); | 985 | writel(0, ®->done_qbuffer[i]); |
| @@ -1511,7 +1509,6 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) | |||
| 1511 | arcmsr_drain_donequeue(acb, pCCB, error); | 1509 | arcmsr_drain_donequeue(acb, pCCB, error); |
| 1512 | } | 1510 | } |
| 1513 | } | 1511 | } |
| 1514 | |||
| 1515 | static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) | 1512 | static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) |
| 1516 | { | 1513 | { |
| 1517 | uint32_t index; | 1514 | uint32_t index; |
| @@ -2106,10 +2103,6 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, | |||
| 2106 | if (atomic_read(&acb->ccboutstandingcount) >= | 2103 | if (atomic_read(&acb->ccboutstandingcount) >= |
| 2107 | ARCMSR_MAX_OUTSTANDING_CMD) | 2104 | ARCMSR_MAX_OUTSTANDING_CMD) |
| 2108 | return SCSI_MLQUEUE_HOST_BUSY; | 2105 | return SCSI_MLQUEUE_HOST_BUSY; |
| 2109 | if ((scsicmd == SCSI_CMD_ARECA_SPECIFIC)) { | ||
| 2110 | printk(KERN_NOTICE "Receiveing SCSI_CMD_ARECA_SPECIFIC command..\n"); | ||
| 2111 | return 0; | ||
| 2112 | } | ||
| 2113 | ccb = arcmsr_get_freeccb(acb); | 2106 | ccb = arcmsr_get_freeccb(acb); |
| 2114 | if (!ccb) | 2107 | if (!ccb) |
| 2115 | return SCSI_MLQUEUE_HOST_BUSY; | 2108 | return SCSI_MLQUEUE_HOST_BUSY; |
| @@ -2393,6 +2386,7 @@ static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, | |||
| 2393 | int index, rtn; | 2386 | int index, rtn; |
| 2394 | bool error; | 2387 | bool error; |
| 2395 | polling_hbb_ccb_retry: | 2388 | polling_hbb_ccb_retry: |
| 2389 | |||
| 2396 | poll_count++; | 2390 | poll_count++; |
| 2397 | /* clear doorbell interrupt */ | 2391 | /* clear doorbell interrupt */ |
| 2398 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); | 2392 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); |
| @@ -2663,6 +2657,7 @@ static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) | |||
| 2663 | { | 2657 | { |
| 2664 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 2658 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
| 2665 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ | 2659 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ |
| 2660 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2666 | return; | 2661 | return; |
| 2667 | } else { | 2662 | } else { |
| 2668 | acb->fw_flag = FW_NORMAL; | 2663 | acb->fw_flag = FW_NORMAL; |
| @@ -2670,8 +2665,10 @@ static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) | |||
| 2670 | atomic_set(&acb->rq_map_token, 16); | 2665 | atomic_set(&acb->rq_map_token, 16); |
| 2671 | } | 2666 | } |
| 2672 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | 2667 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); |
| 2673 | if (atomic_dec_and_test(&acb->rq_map_token)) | 2668 | if (atomic_dec_and_test(&acb->rq_map_token)) { |
| 2669 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2674 | return; | 2670 | return; |
| 2671 | } | ||
| 2675 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | 2672 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
| 2676 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | 2673 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| 2677 | } | 2674 | } |
| @@ -2682,15 +2679,18 @@ static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) | |||
| 2682 | { | 2679 | { |
| 2683 | struct MessageUnit_B __iomem *reg = acb->pmuB; | 2680 | struct MessageUnit_B __iomem *reg = acb->pmuB; |
| 2684 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ | 2681 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ |
| 2682 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2685 | return; | 2683 | return; |
| 2686 | } else { | 2684 | } else { |
| 2687 | acb->fw_flag = FW_NORMAL; | 2685 | acb->fw_flag = FW_NORMAL; |
| 2688 | if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { | 2686 | if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { |
| 2689 | atomic_set(&acb->rq_map_token,16); | 2687 | atomic_set(&acb->rq_map_token, 16); |
| 2690 | } | 2688 | } |
| 2691 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | 2689 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); |
| 2692 | if(atomic_dec_and_test(&acb->rq_map_token)) | 2690 | if (atomic_dec_and_test(&acb->rq_map_token)) { |
| 2691 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2693 | return; | 2692 | return; |
| 2693 | } | ||
| 2694 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); | 2694 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); |
| 2695 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | 2695 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| 2696 | } | 2696 | } |
| @@ -2701,6 +2701,7 @@ static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb) | |||
| 2701 | { | 2701 | { |
| 2702 | struct MessageUnit_C __iomem *reg = acb->pmuC; | 2702 | struct MessageUnit_C __iomem *reg = acb->pmuC; |
| 2703 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { | 2703 | if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { |
| 2704 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2704 | return; | 2705 | return; |
| 2705 | } else { | 2706 | } else { |
| 2706 | acb->fw_flag = FW_NORMAL; | 2707 | acb->fw_flag = FW_NORMAL; |
| @@ -2708,8 +2709,10 @@ static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb) | |||
| 2708 | atomic_set(&acb->rq_map_token, 16); | 2709 | atomic_set(&acb->rq_map_token, 16); |
| 2709 | } | 2710 | } |
| 2710 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); | 2711 | atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); |
| 2711 | if (atomic_dec_and_test(&acb->rq_map_token)) | 2712 | if (atomic_dec_and_test(&acb->rq_map_token)) { |
| 2713 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | ||
| 2712 | return; | 2714 | return; |
| 2715 | } | ||
| 2713 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | 2716 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
| 2714 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); | 2717 | writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); |
| 2715 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); | 2718 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| @@ -2897,6 +2900,8 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) | |||
| 2897 | uint32_t intmask_org; | 2900 | uint32_t intmask_org; |
| 2898 | uint8_t rtnval = 0x00; | 2901 | uint8_t rtnval = 0x00; |
| 2899 | int i = 0; | 2902 | int i = 0; |
| 2903 | unsigned long flags; | ||
| 2904 | |||
| 2900 | if (atomic_read(&acb->ccboutstandingcount) != 0) { | 2905 | if (atomic_read(&acb->ccboutstandingcount) != 0) { |
| 2901 | /* disable all outbound interrupt */ | 2906 | /* disable all outbound interrupt */ |
| 2902 | intmask_org = arcmsr_disable_outbound_ints(acb); | 2907 | intmask_org = arcmsr_disable_outbound_ints(acb); |
| @@ -2907,7 +2912,12 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) | |||
| 2907 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | 2912 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { |
| 2908 | ccb = acb->pccb_pool[i]; | 2913 | ccb = acb->pccb_pool[i]; |
| 2909 | if (ccb->startdone == ARCMSR_CCB_START) { | 2914 | if (ccb->startdone == ARCMSR_CCB_START) { |
| 2910 | arcmsr_ccb_complete(ccb); | 2915 | scsi_dma_unmap(ccb->pcmd); |
| 2916 | ccb->startdone = ARCMSR_CCB_DONE; | ||
| 2917 | ccb->ccb_flags = 0; | ||
| 2918 | spin_lock_irqsave(&acb->ccblist_lock, flags); | ||
| 2919 | list_add_tail(&ccb->list, &acb->ccb_free_list); | ||
| 2920 | spin_unlock_irqrestore(&acb->ccblist_lock, flags); | ||
| 2911 | } | 2921 | } |
| 2912 | } | 2922 | } |
| 2913 | atomic_set(&acb->ccboutstandingcount, 0); | 2923 | atomic_set(&acb->ccboutstandingcount, 0); |
| @@ -2920,8 +2930,7 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) | |||
| 2920 | 2930 | ||
| 2921 | static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | 2931 | static int arcmsr_bus_reset(struct scsi_cmnd *cmd) |
| 2922 | { | 2932 | { |
| 2923 | struct AdapterControlBlock *acb = | 2933 | struct AdapterControlBlock *acb; |
| 2924 | (struct AdapterControlBlock *)cmd->device->host->hostdata; | ||
| 2925 | uint32_t intmask_org, outbound_doorbell; | 2934 | uint32_t intmask_org, outbound_doorbell; |
| 2926 | int retry_count = 0; | 2935 | int retry_count = 0; |
| 2927 | int rtn = FAILED; | 2936 | int rtn = FAILED; |
| @@ -2971,31 +2980,16 @@ sleep_again: | |||
| 2971 | atomic_set(&acb->rq_map_token, 16); | 2980 | atomic_set(&acb->rq_map_token, 16); |
| 2972 | atomic_set(&acb->ante_token_value, 16); | 2981 | atomic_set(&acb->ante_token_value, 16); |
| 2973 | acb->fw_flag = FW_NORMAL; | 2982 | acb->fw_flag = FW_NORMAL; |
| 2974 | init_timer(&acb->eternal_timer); | 2983 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| 2975 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | ||
| 2976 | acb->eternal_timer.data = (unsigned long) acb; | ||
| 2977 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
| 2978 | add_timer(&acb->eternal_timer); | ||
| 2979 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 2984 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
| 2980 | rtn = SUCCESS; | 2985 | rtn = SUCCESS; |
| 2981 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); | 2986 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); |
| 2982 | } else { | 2987 | } else { |
| 2983 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 2988 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
| 2984 | if (atomic_read(&acb->rq_map_token) == 0) { | 2989 | atomic_set(&acb->rq_map_token, 16); |
| 2985 | atomic_set(&acb->rq_map_token, 16); | 2990 | atomic_set(&acb->ante_token_value, 16); |
| 2986 | atomic_set(&acb->ante_token_value, 16); | 2991 | acb->fw_flag = FW_NORMAL; |
| 2987 | acb->fw_flag = FW_NORMAL; | 2992 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); |
| 2988 | init_timer(&acb->eternal_timer); | ||
| 2989 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | ||
| 2990 | acb->eternal_timer.data = (unsigned long) acb; | ||
| 2991 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
| 2992 | add_timer(&acb->eternal_timer); | ||
| 2993 | } else { | ||
| 2994 | atomic_set(&acb->rq_map_token, 16); | ||
| 2995 | atomic_set(&acb->ante_token_value, 16); | ||
| 2996 | acb->fw_flag = FW_NORMAL; | ||
| 2997 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | ||
| 2998 | } | ||
| 2999 | rtn = SUCCESS; | 2993 | rtn = SUCCESS; |
| 3000 | } | 2994 | } |
| 3001 | break; | 2995 | break; |
| @@ -3007,21 +3001,10 @@ sleep_again: | |||
| 3007 | rtn = FAILED; | 3001 | rtn = FAILED; |
| 3008 | } else { | 3002 | } else { |
| 3009 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 3003 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
| 3010 | if (atomic_read(&acb->rq_map_token) == 0) { | 3004 | atomic_set(&acb->rq_map_token, 16); |
| 3011 | atomic_set(&acb->rq_map_token, 16); | 3005 | atomic_set(&acb->ante_token_value, 16); |
| 3012 | atomic_set(&acb->ante_token_value, 16); | 3006 | acb->fw_flag = FW_NORMAL; |
| 3013 | acb->fw_flag = FW_NORMAL; | 3007 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| 3014 | init_timer(&acb->eternal_timer); | ||
| 3015 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | ||
| 3016 | acb->eternal_timer.data = (unsigned long) acb; | ||
| 3017 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
| 3018 | add_timer(&acb->eternal_timer); | ||
| 3019 | } else { | ||
| 3020 | atomic_set(&acb->rq_map_token, 16); | ||
| 3021 | atomic_set(&acb->ante_token_value, 16); | ||
| 3022 | acb->fw_flag = FW_NORMAL; | ||
| 3023 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | ||
| 3024 | } | ||
| 3025 | rtn = SUCCESS; | 3008 | rtn = SUCCESS; |
| 3026 | } | 3009 | } |
| 3027 | break; | 3010 | break; |
| @@ -3067,31 +3050,16 @@ sleep: | |||
| 3067 | atomic_set(&acb->rq_map_token, 16); | 3050 | atomic_set(&acb->rq_map_token, 16); |
| 3068 | atomic_set(&acb->ante_token_value, 16); | 3051 | atomic_set(&acb->ante_token_value, 16); |
| 3069 | acb->fw_flag = FW_NORMAL; | 3052 | acb->fw_flag = FW_NORMAL; |
| 3070 | init_timer(&acb->eternal_timer); | 3053 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); |
| 3071 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); | ||
| 3072 | acb->eternal_timer.data = (unsigned long) acb; | ||
| 3073 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
| 3074 | add_timer(&acb->eternal_timer); | ||
| 3075 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 3054 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
| 3076 | rtn = SUCCESS; | 3055 | rtn = SUCCESS; |
| 3077 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); | 3056 | printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n"); |
| 3078 | } else { | 3057 | } else { |
| 3079 | acb->acb_flags &= ~ACB_F_BUS_RESET; | 3058 | acb->acb_flags &= ~ACB_F_BUS_RESET; |
| 3080 | if (atomic_read(&acb->rq_map_token) == 0) { | 3059 | atomic_set(&acb->rq_map_token, 16); |
| 3081 | atomic_set(&acb->rq_map_token, 16); | 3060 | atomic_set(&acb->ante_token_value, 16); |
| 3082 | atomic_set(&acb->ante_token_value, 16); | 3061 | acb->fw_flag = FW_NORMAL; |
| 3083 | acb->fw_flag = FW_NORMAL; | 3062 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); |
| 3084 | init_timer(&acb->eternal_timer); | ||
| 3085 | acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ); | ||
| 3086 | acb->eternal_timer.data = (unsigned long) acb; | ||
| 3087 | acb->eternal_timer.function = &arcmsr_request_device_map; | ||
| 3088 | add_timer(&acb->eternal_timer); | ||
| 3089 | } else { | ||
| 3090 | atomic_set(&acb->rq_map_token, 16); | ||
| 3091 | atomic_set(&acb->ante_token_value, 16); | ||
| 3092 | acb->fw_flag = FW_NORMAL; | ||
| 3093 | mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ)); | ||
| 3094 | } | ||
| 3095 | rtn = SUCCESS; | 3063 | rtn = SUCCESS; |
| 3096 | } | 3064 | } |
| 3097 | break; | 3065 | break; |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 5815cbeb27a..9a7aaf5f131 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
| @@ -646,6 +646,7 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) | |||
| 646 | 646 | ||
| 647 | spin_lock_irqsave(shost->host_lock, flags); | 647 | spin_lock_irqsave(shost->host_lock, flags); |
| 648 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); | 648 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); |
| 649 | shost->host_eh_scheduled = 0; | ||
| 649 | spin_unlock_irqrestore(shost->host_lock, flags); | 650 | spin_unlock_irqrestore(shost->host_lock, flags); |
| 650 | 651 | ||
| 651 | SAS_DPRINTK("Enter %s\n", __func__); | 652 | SAS_DPRINTK("Enter %s\n", __func__); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index b2a817055b8..9ead0399808 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
| @@ -2176,9 +2176,9 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 2176 | /* adjust hba_queue_depth, reply_free_queue_depth, | 2176 | /* adjust hba_queue_depth, reply_free_queue_depth, |
| 2177 | * and queue_size | 2177 | * and queue_size |
| 2178 | */ | 2178 | */ |
| 2179 | ioc->hba_queue_depth -= queue_diff; | 2179 | ioc->hba_queue_depth -= (queue_diff / 2); |
| 2180 | ioc->reply_free_queue_depth -= queue_diff; | 2180 | ioc->reply_free_queue_depth -= (queue_diff / 2); |
| 2181 | queue_size -= queue_diff; | 2181 | queue_size = facts->MaxReplyDescriptorPostQueueDepth; |
| 2182 | } | 2182 | } |
| 2183 | ioc->reply_post_queue_depth = queue_size; | 2183 | ioc->reply_post_queue_depth = queue_size; |
| 2184 | 2184 | ||
| @@ -3941,6 +3941,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3941 | static void | 3941 | static void |
| 3942 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | 3942 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) |
| 3943 | { | 3943 | { |
| 3944 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
| 3945 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
| 3944 | switch (reset_phase) { | 3946 | switch (reset_phase) { |
| 3945 | case MPT2_IOC_PRE_RESET: | 3947 | case MPT2_IOC_PRE_RESET: |
| 3946 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | 3948 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " |
| @@ -3971,8 +3973,6 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
| 3971 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | 3973 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); |
| 3972 | break; | 3974 | break; |
| 3973 | } | 3975 | } |
| 3974 | mpt2sas_scsih_reset_handler(ioc, reset_phase); | ||
| 3975 | mpt2sas_ctl_reset_handler(ioc, reset_phase); | ||
| 3976 | } | 3976 | } |
| 3977 | 3977 | ||
| 3978 | /** | 3978 | /** |
| @@ -4026,6 +4026,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 4026 | { | 4026 | { |
| 4027 | int r; | 4027 | int r; |
| 4028 | unsigned long flags; | 4028 | unsigned long flags; |
| 4029 | u8 pe_complete = ioc->wait_for_port_enable_to_complete; | ||
| 4029 | 4030 | ||
| 4030 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 4031 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
| 4031 | __func__)); | 4032 | __func__)); |
| @@ -4068,6 +4069,14 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 4068 | if (r) | 4069 | if (r) |
| 4069 | goto out; | 4070 | goto out; |
| 4070 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); | 4071 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); |
| 4072 | |||
| 4073 | /* If this hard reset is called while port enable is active, then | ||
| 4074 | * there is no reason to call make_ioc_operational | ||
| 4075 | */ | ||
| 4076 | if (pe_complete) { | ||
| 4077 | r = -EFAULT; | ||
| 4078 | goto out; | ||
| 4079 | } | ||
| 4071 | r = _base_make_ioc_operational(ioc, sleep_flag); | 4080 | r = _base_make_ioc_operational(ioc, sleep_flag); |
| 4072 | if (!r) | 4081 | if (!r) |
| 4073 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); | 4082 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index eda347c5797..5ded3db6e31 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
| @@ -819,7 +819,7 @@ _scsih_is_end_device(u32 device_info) | |||
| 819 | } | 819 | } |
| 820 | 820 | ||
| 821 | /** | 821 | /** |
| 822 | * mptscsih_get_scsi_lookup - returns scmd entry | 822 | * _scsih_scsi_lookup_get - returns scmd entry |
| 823 | * @ioc: per adapter object | 823 | * @ioc: per adapter object |
| 824 | * @smid: system request message index | 824 | * @smid: system request message index |
| 825 | * | 825 | * |
| @@ -832,6 +832,28 @@ _scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
| 832 | } | 832 | } |
| 833 | 833 | ||
| 834 | /** | 834 | /** |
| 835 | * _scsih_scsi_lookup_get_clear - returns scmd entry | ||
| 836 | * @ioc: per adapter object | ||
| 837 | * @smid: system request message index | ||
| 838 | * | ||
| 839 | * Returns the smid stored scmd pointer. | ||
| 840 | * Then will derefrence the stored scmd pointer. | ||
| 841 | */ | ||
| 842 | static inline struct scsi_cmnd * | ||
| 843 | _scsih_scsi_lookup_get_clear(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
| 844 | { | ||
| 845 | unsigned long flags; | ||
| 846 | struct scsi_cmnd *scmd; | ||
| 847 | |||
| 848 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
| 849 | scmd = ioc->scsi_lookup[smid - 1].scmd; | ||
| 850 | ioc->scsi_lookup[smid - 1].scmd = NULL; | ||
| 851 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
| 852 | |||
| 853 | return scmd; | ||
| 854 | } | ||
| 855 | |||
| 856 | /** | ||
| 835 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup | 857 | * _scsih_scsi_lookup_find_by_scmd - scmd lookup |
| 836 | * @ioc: per adapter object | 858 | * @ioc: per adapter object |
| 837 | * @smid: system request message index | 859 | * @smid: system request message index |
| @@ -2981,9 +3003,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
| 2981 | u16 handle; | 3003 | u16 handle; |
| 2982 | 3004 | ||
| 2983 | for (i = 0 ; i < event_data->NumEntries; i++) { | 3005 | for (i = 0 ; i < event_data->NumEntries; i++) { |
| 2984 | if (event_data->PHY[i].PhyStatus & | ||
| 2985 | MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) | ||
| 2986 | continue; | ||
| 2987 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | 3006 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); |
| 2988 | if (!handle) | 3007 | if (!handle) |
| 2989 | continue; | 3008 | continue; |
| @@ -3210,7 +3229,7 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc) | |||
| 3210 | u16 count = 0; | 3229 | u16 count = 0; |
| 3211 | 3230 | ||
| 3212 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { | 3231 | for (smid = 1; smid <= ioc->scsiio_depth; smid++) { |
| 3213 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3232 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
| 3214 | if (!scmd) | 3233 | if (!scmd) |
| 3215 | continue; | 3234 | continue; |
| 3216 | count++; | 3235 | count++; |
| @@ -3804,7 +3823,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 3804 | u32 response_code = 0; | 3823 | u32 response_code = 0; |
| 3805 | 3824 | ||
| 3806 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3825 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 3807 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3826 | scmd = _scsih_scsi_lookup_get_clear(ioc, smid); |
| 3808 | if (scmd == NULL) | 3827 | if (scmd == NULL) |
| 3809 | return 1; | 3828 | return 1; |
| 3810 | 3829 | ||
| @@ -5005,6 +5024,12 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5005 | event_data); | 5024 | event_data); |
| 5006 | #endif | 5025 | #endif |
| 5007 | 5026 | ||
| 5027 | /* In MPI Revision K (0xC), the internal device reset complete was | ||
| 5028 | * implemented, so avoid setting tm_busy flag for older firmware. | ||
| 5029 | */ | ||
| 5030 | if ((ioc->facts.HeaderVersion >> 8) < 0xC) | ||
| 5031 | return; | ||
| 5032 | |||
| 5008 | if (event_data->ReasonCode != | 5033 | if (event_data->ReasonCode != |
| 5009 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && | 5034 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && |
| 5010 | event_data->ReasonCode != | 5035 | event_data->ReasonCode != |
| @@ -5099,6 +5124,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5099 | struct fw_event_work *fw_event) | 5124 | struct fw_event_work *fw_event) |
| 5100 | { | 5125 | { |
| 5101 | struct scsi_cmnd *scmd; | 5126 | struct scsi_cmnd *scmd; |
| 5127 | struct scsi_device *sdev; | ||
| 5102 | u16 smid, handle; | 5128 | u16 smid, handle; |
| 5103 | u32 lun; | 5129 | u32 lun; |
| 5104 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 5130 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
| @@ -5109,12 +5135,17 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5109 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; | 5135 | Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; |
| 5110 | #endif | 5136 | #endif |
| 5111 | u16 ioc_status; | 5137 | u16 ioc_status; |
| 5138 | unsigned long flags; | ||
| 5139 | int r; | ||
| 5140 | |||
| 5112 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " | 5141 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " |
| 5113 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, | 5142 | "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, |
| 5114 | event_data->PortWidth)); | 5143 | event_data->PortWidth)); |
| 5115 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 5144 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
| 5116 | __func__)); | 5145 | __func__)); |
| 5117 | 5146 | ||
| 5147 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
| 5148 | ioc->broadcast_aen_busy = 0; | ||
| 5118 | termination_count = 0; | 5149 | termination_count = 0; |
| 5119 | query_count = 0; | 5150 | query_count = 0; |
| 5120 | mpi_reply = ioc->tm_cmds.reply; | 5151 | mpi_reply = ioc->tm_cmds.reply; |
| @@ -5122,7 +5153,8 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5122 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 5153 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
| 5123 | if (!scmd) | 5154 | if (!scmd) |
| 5124 | continue; | 5155 | continue; |
| 5125 | sas_device_priv_data = scmd->device->hostdata; | 5156 | sdev = scmd->device; |
| 5157 | sas_device_priv_data = sdev->hostdata; | ||
| 5126 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) | 5158 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) |
| 5127 | continue; | 5159 | continue; |
| 5128 | /* skip hidden raid components */ | 5160 | /* skip hidden raid components */ |
| @@ -5138,6 +5170,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5138 | lun = sas_device_priv_data->lun; | 5170 | lun = sas_device_priv_data->lun; |
| 5139 | query_count++; | 5171 | query_count++; |
| 5140 | 5172 | ||
| 5173 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | ||
| 5141 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5174 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, |
| 5142 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); | 5175 | MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, NULL); |
| 5143 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 5176 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
| @@ -5147,14 +5180,20 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, | |||
| 5147 | (mpi_reply->ResponseCode == | 5180 | (mpi_reply->ResponseCode == |
| 5148 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || | 5181 | MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || |
| 5149 | mpi_reply->ResponseCode == | 5182 | mpi_reply->ResponseCode == |
| 5150 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) | 5183 | MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC)) { |
| 5184 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
| 5151 | continue; | 5185 | continue; |
| 5152 | 5186 | } | |
| 5153 | mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, | 5187 | r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, |
| 5154 | MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, 0, 30, NULL); | 5188 | sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, |
| 5189 | scmd); | ||
| 5190 | if (r == FAILED) | ||
| 5191 | sdev_printk(KERN_WARNING, sdev, "task abort: FAILED " | ||
| 5192 | "scmd(%p)\n", scmd); | ||
| 5155 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); | 5193 | termination_count += le32_to_cpu(mpi_reply->TerminationCount); |
| 5194 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | ||
| 5156 | } | 5195 | } |
| 5157 | ioc->broadcast_aen_busy = 0; | 5196 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
| 5158 | 5197 | ||
| 5159 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT | 5198 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT |
| 5160 | "%s - exit, query_count = %d termination_count = %d\n", | 5199 | "%s - exit, query_count = %d termination_count = %d\n", |
| @@ -6626,6 +6665,7 @@ _scsih_remove(struct pci_dev *pdev) | |||
| 6626 | destroy_workqueue(wq); | 6665 | destroy_workqueue(wq); |
| 6627 | 6666 | ||
| 6628 | /* release all the volumes */ | 6667 | /* release all the volumes */ |
| 6668 | _scsih_ir_shutdown(ioc); | ||
| 6629 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, | 6669 | list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, |
| 6630 | list) { | 6670 | list) { |
| 6631 | if (raid_device->starget) { | 6671 | if (raid_device->starget) { |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 44578b56ad0..d3e58d763b4 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
| @@ -1561,6 +1561,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
| 1561 | { | 1561 | { |
| 1562 | struct Scsi_Host *host = rport_to_shost(rport); | 1562 | struct Scsi_Host *host = rport_to_shost(rport); |
| 1563 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; | 1563 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
| 1564 | unsigned long flags; | ||
| 1564 | 1565 | ||
| 1565 | if (!fcport) | 1566 | if (!fcport) |
| 1566 | return; | 1567 | return; |
| @@ -1573,10 +1574,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
| 1573 | * Transport has effectively 'deleted' the rport, clear | 1574 | * Transport has effectively 'deleted' the rport, clear |
| 1574 | * all local references. | 1575 | * all local references. |
| 1575 | */ | 1576 | */ |
| 1576 | spin_lock_irq(host->host_lock); | 1577 | spin_lock_irqsave(host->host_lock, flags); |
| 1577 | fcport->rport = fcport->drport = NULL; | 1578 | fcport->rport = fcport->drport = NULL; |
| 1578 | *((fc_port_t **)rport->dd_data) = NULL; | 1579 | *((fc_port_t **)rport->dd_data) = NULL; |
| 1579 | spin_unlock_irq(host->host_lock); | 1580 | spin_unlock_irqrestore(host->host_lock, flags); |
| 1580 | 1581 | ||
| 1581 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | 1582 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) |
| 1582 | return; | 1583 | return; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f948e1a73ae..d9479c3fe5f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -2505,11 +2505,12 @@ qla2x00_rport_del(void *data) | |||
| 2505 | { | 2505 | { |
| 2506 | fc_port_t *fcport = data; | 2506 | fc_port_t *fcport = data; |
| 2507 | struct fc_rport *rport; | 2507 | struct fc_rport *rport; |
| 2508 | unsigned long flags; | ||
| 2508 | 2509 | ||
| 2509 | spin_lock_irq(fcport->vha->host->host_lock); | 2510 | spin_lock_irqsave(fcport->vha->host->host_lock, flags); |
| 2510 | rport = fcport->drport ? fcport->drport: fcport->rport; | 2511 | rport = fcport->drport ? fcport->drport: fcport->rport; |
| 2511 | fcport->drport = NULL; | 2512 | fcport->drport = NULL; |
| 2512 | spin_unlock_irq(fcport->vha->host->host_lock); | 2513 | spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); |
| 2513 | if (rport) | 2514 | if (rport) |
| 2514 | fc_remote_port_delete(rport); | 2515 | fc_remote_port_delete(rport); |
| 2515 | } | 2516 | } |
| @@ -2879,6 +2880,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
| 2879 | struct fc_rport_identifiers rport_ids; | 2880 | struct fc_rport_identifiers rport_ids; |
| 2880 | struct fc_rport *rport; | 2881 | struct fc_rport *rport; |
| 2881 | struct qla_hw_data *ha = vha->hw; | 2882 | struct qla_hw_data *ha = vha->hw; |
| 2883 | unsigned long flags; | ||
| 2882 | 2884 | ||
| 2883 | qla2x00_rport_del(fcport); | 2885 | qla2x00_rport_del(fcport); |
| 2884 | 2886 | ||
| @@ -2893,9 +2895,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
| 2893 | "Unable to allocate fc remote port!\n"); | 2895 | "Unable to allocate fc remote port!\n"); |
| 2894 | return; | 2896 | return; |
| 2895 | } | 2897 | } |
| 2896 | spin_lock_irq(fcport->vha->host->host_lock); | 2898 | spin_lock_irqsave(fcport->vha->host->host_lock, flags); |
| 2897 | *((fc_port_t **)rport->dd_data) = fcport; | 2899 | *((fc_port_t **)rport->dd_data) = fcport; |
| 2898 | spin_unlock_irq(fcport->vha->host->host_lock); | 2900 | spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); |
| 2899 | 2901 | ||
| 2900 | rport->supported_classes = fcport->supported_classes; | 2902 | rport->supported_classes = fcport->supported_classes; |
| 2901 | 2903 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c194c23ca1f..f27724d76cf 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -562,7 +562,6 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) | |||
| 562 | } | 562 | } |
| 563 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 563 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
| 564 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 564 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
| 565 | atomic_read(&fcport->state) == FCS_DEVICE_LOST || | ||
| 566 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { | 565 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
| 567 | cmd->result = DID_NO_CONNECT << 16; | 566 | cmd->result = DID_NO_CONNECT << 16; |
| 568 | goto qc24_fail_command; | 567 | goto qc24_fail_command; |
| @@ -2513,6 +2512,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
| 2513 | { | 2512 | { |
| 2514 | struct fc_rport *rport; | 2513 | struct fc_rport *rport; |
| 2515 | scsi_qla_host_t *base_vha; | 2514 | scsi_qla_host_t *base_vha; |
| 2515 | unsigned long flags; | ||
| 2516 | 2516 | ||
| 2517 | if (!fcport->rport) | 2517 | if (!fcport->rport) |
| 2518 | return; | 2518 | return; |
| @@ -2520,9 +2520,9 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
| 2520 | rport = fcport->rport; | 2520 | rport = fcport->rport; |
| 2521 | if (defer) { | 2521 | if (defer) { |
| 2522 | base_vha = pci_get_drvdata(vha->hw->pdev); | 2522 | base_vha = pci_get_drvdata(vha->hw->pdev); |
| 2523 | spin_lock_irq(vha->host->host_lock); | 2523 | spin_lock_irqsave(vha->host->host_lock, flags); |
| 2524 | fcport->drport = rport; | 2524 | fcport->drport = rport; |
| 2525 | spin_unlock_irq(vha->host->host_lock); | 2525 | spin_unlock_irqrestore(vha->host->host_lock, flags); |
| 2526 | set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); | 2526 | set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); |
| 2527 | qla2xxx_wake_dpc(base_vha); | 2527 | qla2xxx_wake_dpc(base_vha); |
| 2528 | } else | 2528 | } else |
| @@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data) | |||
| 3282 | 3282 | ||
| 3283 | set_user_nice(current, -20); | 3283 | set_user_nice(current, -20); |
| 3284 | 3284 | ||
| 3285 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 3285 | while (!kthread_should_stop()) { | 3286 | while (!kthread_should_stop()) { |
| 3286 | DEBUG3(printk("qla2x00: DPC handler sleeping\n")); | 3287 | DEBUG3(printk("qla2x00: DPC handler sleeping\n")); |
| 3287 | 3288 | ||
| 3288 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 3289 | schedule(); | 3289 | schedule(); |
| 3290 | __set_current_state(TASK_RUNNING); | 3290 | __set_current_state(TASK_RUNNING); |
| 3291 | 3291 | ||
| @@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data) | |||
| 3454 | qla2x00_do_dpc_all_vps(base_vha); | 3454 | qla2x00_do_dpc_all_vps(base_vha); |
| 3455 | 3455 | ||
| 3456 | ha->dpc_active = 0; | 3456 | ha->dpc_active = 0; |
| 3457 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 3457 | } /* End of while(1) */ | 3458 | } /* End of while(1) */ |
| 3459 | __set_current_state(TASK_RUNNING); | ||
| 3458 | 3460 | ||
| 3459 | DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); | 3461 | DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); |
| 3460 | 3462 | ||
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7b310934efe..a6b2d72022f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
| @@ -1671,7 +1671,7 @@ static int do_device_access(struct scsi_cmnd *scmd, | |||
| 1671 | unsigned long long lba, unsigned int num, int write) | 1671 | unsigned long long lba, unsigned int num, int write) |
| 1672 | { | 1672 | { |
| 1673 | int ret; | 1673 | int ret; |
| 1674 | unsigned int block, rest = 0; | 1674 | unsigned long long block, rest = 0; |
| 1675 | int (*func)(struct scsi_cmnd *, unsigned char *, int); | 1675 | int (*func)(struct scsi_cmnd *, unsigned char *, int); |
| 1676 | 1676 | ||
| 1677 | func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; | 1677 | func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; |
diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c index 351d8a375b5..19752b09e15 100644 --- a/drivers/spi/pxa2xx_spi_pci.c +++ b/drivers/spi/pxa2xx_spi_pci.c | |||
| @@ -7,10 +7,9 @@ | |||
| 7 | #include <linux/of_device.h> | 7 | #include <linux/of_device.h> |
| 8 | #include <linux/spi/pxa2xx_spi.h> | 8 | #include <linux/spi/pxa2xx_spi.h> |
| 9 | 9 | ||
| 10 | struct awesome_struct { | 10 | struct ce4100_info { |
| 11 | struct ssp_device ssp; | 11 | struct ssp_device ssp; |
| 12 | struct platform_device spi_pdev; | 12 | struct platform_device *spi_pdev; |
| 13 | struct pxa2xx_spi_master spi_pdata; | ||
| 14 | }; | 13 | }; |
| 15 | 14 | ||
| 16 | static DEFINE_MUTEX(ssp_lock); | 15 | static DEFINE_MUTEX(ssp_lock); |
| @@ -51,23 +50,15 @@ void pxa_ssp_free(struct ssp_device *ssp) | |||
| 51 | } | 50 | } |
| 52 | EXPORT_SYMBOL_GPL(pxa_ssp_free); | 51 | EXPORT_SYMBOL_GPL(pxa_ssp_free); |
| 53 | 52 | ||
| 54 | static void plat_dev_release(struct device *dev) | ||
| 55 | { | ||
| 56 | struct awesome_struct *as = container_of(dev, | ||
| 57 | struct awesome_struct, spi_pdev.dev); | ||
| 58 | |||
| 59 | of_device_node_put(&as->spi_pdev.dev); | ||
| 60 | } | ||
| 61 | |||
| 62 | static int __devinit ce4100_spi_probe(struct pci_dev *dev, | 53 | static int __devinit ce4100_spi_probe(struct pci_dev *dev, |
| 63 | const struct pci_device_id *ent) | 54 | const struct pci_device_id *ent) |
| 64 | { | 55 | { |
| 65 | int ret; | 56 | int ret; |
| 66 | resource_size_t phys_beg; | 57 | resource_size_t phys_beg; |
| 67 | resource_size_t phys_len; | 58 | resource_size_t phys_len; |
| 68 | struct awesome_struct *spi_info; | 59 | struct ce4100_info *spi_info; |
| 69 | struct platform_device *pdev; | 60 | struct platform_device *pdev; |
| 70 | struct pxa2xx_spi_master *spi_pdata; | 61 | struct pxa2xx_spi_master spi_pdata; |
| 71 | struct ssp_device *ssp; | 62 | struct ssp_device *ssp; |
| 72 | 63 | ||
| 73 | ret = pci_enable_device(dev); | 64 | ret = pci_enable_device(dev); |
| @@ -84,33 +75,30 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, | |||
| 84 | return ret; | 75 | return ret; |
| 85 | } | 76 | } |
| 86 | 77 | ||
| 78 | pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); | ||
| 87 | spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); | 79 | spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); |
| 88 | if (!spi_info) { | 80 | if (!pdev || !spi_info ) { |
| 89 | ret = -ENOMEM; | 81 | ret = -ENOMEM; |
| 90 | goto err_kz; | 82 | goto err_nomem; |
| 91 | } | 83 | } |
| 92 | ssp = &spi_info->ssp; | 84 | memset(&spi_pdata, 0, sizeof(spi_pdata)); |
| 93 | pdev = &spi_info->spi_pdev; | 85 | spi_pdata.num_chipselect = dev->devfn; |
| 94 | spi_pdata = &spi_info->spi_pdata; | ||
| 95 | 86 | ||
| 96 | pdev->name = "pxa2xx-spi"; | 87 | ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); |
| 97 | pdev->id = dev->devfn; | 88 | if (ret) |
| 98 | pdev->dev.parent = &dev->dev; | 89 | goto err_nomem; |
| 99 | pdev->dev.platform_data = &spi_info->spi_pdata; | ||
| 100 | 90 | ||
| 91 | pdev->dev.parent = &dev->dev; | ||
| 101 | #ifdef CONFIG_OF | 92 | #ifdef CONFIG_OF |
| 102 | pdev->dev.of_node = dev->dev.of_node; | 93 | pdev->dev.of_node = dev->dev.of_node; |
| 103 | #endif | 94 | #endif |
| 104 | pdev->dev.release = plat_dev_release; | 95 | ssp = &spi_info->ssp; |
| 105 | |||
| 106 | spi_pdata->num_chipselect = dev->devfn; | ||
| 107 | |||
| 108 | ssp->phys_base = pci_resource_start(dev, 0); | 96 | ssp->phys_base = pci_resource_start(dev, 0); |
| 109 | ssp->mmio_base = ioremap(phys_beg, phys_len); | 97 | ssp->mmio_base = ioremap(phys_beg, phys_len); |
| 110 | if (!ssp->mmio_base) { | 98 | if (!ssp->mmio_base) { |
| 111 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | 99 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); |
| 112 | ret = -EIO; | 100 | ret = -EIO; |
| 113 | goto err_remap; | 101 | goto err_nomem; |
| 114 | } | 102 | } |
| 115 | ssp->irq = dev->irq; | 103 | ssp->irq = dev->irq; |
| 116 | ssp->port_id = pdev->id; | 104 | ssp->port_id = pdev->id; |
| @@ -122,7 +110,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, | |||
| 122 | 110 | ||
| 123 | pci_set_drvdata(dev, spi_info); | 111 | pci_set_drvdata(dev, spi_info); |
| 124 | 112 | ||
| 125 | ret = platform_device_register(pdev); | 113 | ret = platform_device_add(pdev); |
| 126 | if (ret) | 114 | if (ret) |
| 127 | goto err_dev_add; | 115 | goto err_dev_add; |
| 128 | 116 | ||
| @@ -135,27 +123,21 @@ err_dev_add: | |||
| 135 | mutex_unlock(&ssp_lock); | 123 | mutex_unlock(&ssp_lock); |
| 136 | iounmap(ssp->mmio_base); | 124 | iounmap(ssp->mmio_base); |
| 137 | 125 | ||
| 138 | err_remap: | 126 | err_nomem: |
| 139 | kfree(spi_info); | ||
| 140 | |||
| 141 | err_kz: | ||
| 142 | release_mem_region(phys_beg, phys_len); | 127 | release_mem_region(phys_beg, phys_len); |
| 143 | 128 | platform_device_put(pdev); | |
| 129 | kfree(spi_info); | ||
| 144 | return ret; | 130 | return ret; |
| 145 | } | 131 | } |
| 146 | 132 | ||
| 147 | static void __devexit ce4100_spi_remove(struct pci_dev *dev) | 133 | static void __devexit ce4100_spi_remove(struct pci_dev *dev) |
| 148 | { | 134 | { |
| 149 | struct awesome_struct *spi_info; | 135 | struct ce4100_info *spi_info; |
| 150 | struct platform_device *pdev; | ||
| 151 | struct ssp_device *ssp; | 136 | struct ssp_device *ssp; |
| 152 | 137 | ||
| 153 | spi_info = pci_get_drvdata(dev); | 138 | spi_info = pci_get_drvdata(dev); |
| 154 | |||
| 155 | ssp = &spi_info->ssp; | 139 | ssp = &spi_info->ssp; |
| 156 | pdev = &spi_info->spi_pdev; | 140 | platform_device_unregister(spi_info->spi_pdev); |
| 157 | |||
| 158 | platform_device_unregister(pdev); | ||
| 159 | 141 | ||
| 160 | iounmap(ssp->mmio_base); | 142 | iounmap(ssp->mmio_base); |
| 161 | release_mem_region(pci_resource_start(dev, 0), | 143 | release_mem_region(pci_resource_start(dev, 0), |
| @@ -171,7 +153,6 @@ static void __devexit ce4100_spi_remove(struct pci_dev *dev) | |||
| 171 | } | 153 | } |
| 172 | 154 | ||
| 173 | static struct pci_device_id ce4100_spi_devices[] __devinitdata = { | 155 | static struct pci_device_id ce4100_spi_devices[] __devinitdata = { |
| 174 | |||
| 175 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, | 156 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, |
| 176 | { }, | 157 | { }, |
| 177 | }; | 158 | }; |
diff --git a/drivers/spi/spi_sh_msiof.c b/drivers/spi/spi_sh_msiof.c index 56f60c8ea0a..2c665fceaac 100644 --- a/drivers/spi/spi_sh_msiof.c +++ b/drivers/spi/spi_sh_msiof.c | |||
| @@ -509,9 +509,11 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
| 509 | bytes_done = 0; | 509 | bytes_done = 0; |
| 510 | 510 | ||
| 511 | while (bytes_done < t->len) { | 511 | while (bytes_done < t->len) { |
| 512 | void *rx_buf = t->rx_buf ? t->rx_buf + bytes_done : NULL; | ||
| 513 | const void *tx_buf = t->tx_buf ? t->tx_buf + bytes_done : NULL; | ||
| 512 | n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, | 514 | n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, |
| 513 | t->tx_buf + bytes_done, | 515 | tx_buf, |
| 514 | t->rx_buf + bytes_done, | 516 | rx_buf, |
| 515 | words, bits); | 517 | words, bits); |
| 516 | if (n < 0) | 518 | if (n < 0) |
| 517 | break; | 519 | break; |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index c7345dbf43f..f8533795ee7 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
| @@ -733,7 +733,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, | |||
| 733 | 733 | ||
| 734 | /* Fetch the vendor specific tuples. */ | 734 | /* Fetch the vendor specific tuples. */ |
| 735 | res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS, | 735 | res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS, |
| 736 | ssb_pcmcia_do_get_invariants, sprom); | 736 | ssb_pcmcia_do_get_invariants, iv); |
| 737 | if ((res == 0) || (res == -ENOSPC)) | 737 | if ((res == 0) || (res == -ENOSPC)) |
| 738 | return 0; | 738 | return 0; |
| 739 | 739 | ||
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index f1235884cc5..cd8392badff 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c | |||
| @@ -263,9 +263,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, | |||
| 263 | switch (type) { | 263 | switch (type) { |
| 264 | case NL80211_CHAN_HT20: | 264 | case NL80211_CHAN_HT20: |
| 265 | case NL80211_CHAN_NO_HT: | 265 | case NL80211_CHAN_NO_HT: |
| 266 | WL_LOCK(wl); | ||
| 267 | err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); | 266 | err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); |
| 268 | WL_UNLOCK(wl); | ||
| 269 | break; | 267 | break; |
| 270 | case NL80211_CHAN_HT40MINUS: | 268 | case NL80211_CHAN_HT40MINUS: |
| 271 | case NL80211_CHAN_HT40PLUS: | 269 | case NL80211_CHAN_HT40PLUS: |
| @@ -285,6 +283,7 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
| 285 | int err = 0; | 283 | int err = 0; |
| 286 | int new_int; | 284 | int new_int; |
| 287 | 285 | ||
| 286 | WL_LOCK(wl); | ||
| 288 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { | 287 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { |
| 289 | WL_NONE("%s: Setting listen interval to %d\n", | 288 | WL_NONE("%s: Setting listen interval to %d\n", |
| 290 | __func__, conf->listen_interval); | 289 | __func__, conf->listen_interval); |
| @@ -341,6 +340,7 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | config_out: | 342 | config_out: |
| 343 | WL_UNLOCK(wl); | ||
| 344 | return err; | 344 | return err; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| @@ -459,13 +459,21 @@ wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) | |||
| 459 | 459 | ||
| 460 | static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) | 460 | static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) |
| 461 | { | 461 | { |
| 462 | struct wl_info *wl = hw->priv; | ||
| 462 | WL_NONE("Scan Start\n"); | 463 | WL_NONE("Scan Start\n"); |
| 464 | WL_LOCK(wl); | ||
| 465 | wlc_scan_start(wl->wlc); | ||
| 466 | WL_UNLOCK(wl); | ||
| 463 | return; | 467 | return; |
| 464 | } | 468 | } |
| 465 | 469 | ||
| 466 | static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) | 470 | static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) |
| 467 | { | 471 | { |
| 472 | struct wl_info *wl = hw->priv; | ||
| 468 | WL_NONE("Scan Complete\n"); | 473 | WL_NONE("Scan Complete\n"); |
| 474 | WL_LOCK(wl); | ||
| 475 | wlc_scan_stop(wl->wlc); | ||
| 476 | WL_UNLOCK(wl); | ||
| 469 | return; | 477 | return; |
| 470 | } | 478 | } |
| 471 | 479 | ||
diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index a1303863686..e37e8058e2b 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c | |||
| @@ -8461,3 +8461,16 @@ static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, | |||
| 8461 | 8461 | ||
| 8462 | kfree(qi); | 8462 | kfree(qi); |
| 8463 | } | 8463 | } |
| 8464 | |||
| 8465 | /* | ||
| 8466 | * Flag 'scan in progress' to withold dynamic phy calibration | ||
| 8467 | */ | ||
| 8468 | void wlc_scan_start(struct wlc_info *wlc) | ||
| 8469 | { | ||
| 8470 | wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true); | ||
| 8471 | } | ||
| 8472 | |||
| 8473 | void wlc_scan_stop(struct wlc_info *wlc) | ||
| 8474 | { | ||
| 8475 | wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); | ||
| 8476 | } | ||
diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 146a6904a39..aff413001b7 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h | |||
| @@ -570,6 +570,8 @@ extern void wlc_enable_mac(struct wlc_info *wlc); | |||
| 570 | extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); | 570 | extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); |
| 571 | extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); | 571 | extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); |
| 572 | extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); | 572 | extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); |
| 573 | extern void wlc_scan_start(struct wlc_info *wlc); | ||
| 574 | extern void wlc_scan_stop(struct wlc_info *wlc); | ||
| 573 | 575 | ||
| 574 | static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, | 576 | static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, |
| 575 | uint *arg) | 577 | uint *arg) |
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index aad47326d6d..1502d80f6f7 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig | |||
| @@ -439,6 +439,7 @@ config COMEDI_NI_AT_AO | |||
| 439 | config COMEDI_NI_ATMIO | 439 | config COMEDI_NI_ATMIO |
| 440 | tristate "NI AT-MIO E series ISA-PNP card support" | 440 | tristate "NI AT-MIO E series ISA-PNP card support" |
| 441 | depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON | 441 | depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON |
| 442 | select COMEDI_8255 | ||
| 442 | default N | 443 | default N |
| 443 | ---help--- | 444 | ---help--- |
| 444 | Enable support for National Instruments AT-MIO E series cards | 445 | Enable support for National Instruments AT-MIO E series cards |
| @@ -1040,6 +1041,8 @@ config COMEDI_NI_PCIDIO | |||
| 1040 | config COMEDI_NI_PCIMIO | 1041 | config COMEDI_NI_PCIMIO |
| 1041 | tristate "NI PCI-MIO-E series and M series support" | 1042 | tristate "NI PCI-MIO-E series and M series support" |
| 1042 | depends on COMEDI_NI_TIO && COMEDI_NI_COMMON | 1043 | depends on COMEDI_NI_TIO && COMEDI_NI_COMMON |
| 1044 | select COMEDI_8255 | ||
| 1045 | select COMEDI_FC | ||
| 1043 | default N | 1046 | default N |
| 1044 | ---help--- | 1047 | ---help--- |
| 1045 | Enable support for National Instruments PCI-MIO-E series and M series | 1048 | Enable support for National Instruments PCI-MIO-E series and M series |
| @@ -1164,6 +1167,7 @@ config COMEDI_NI_LABPC_CS | |||
| 1164 | config COMEDI_NI_MIO_CS | 1167 | config COMEDI_NI_MIO_CS |
| 1165 | tristate "NI DAQCard E series PCMCIA support" | 1168 | tristate "NI DAQCard E series PCMCIA support" |
| 1166 | depends on COMEDI_NI_TIO && COMEDI_NI_COMMON | 1169 | depends on COMEDI_NI_TIO && COMEDI_NI_COMMON |
| 1170 | select COMEDI_8255 | ||
| 1167 | select COMEDI_FC | 1171 | select COMEDI_FC |
| 1168 | default N | 1172 | default N |
| 1169 | ---help--- | 1173 | ---help--- |
| @@ -1268,7 +1272,6 @@ config COMEDI_MITE | |||
| 1268 | config COMEDI_NI_TIO | 1272 | config COMEDI_NI_TIO |
| 1269 | tristate "NI general purpose counter support" | 1273 | tristate "NI general purpose counter support" |
| 1270 | depends on COMEDI_MITE | 1274 | depends on COMEDI_MITE |
| 1271 | select COMEDI_8255 | ||
| 1272 | default N | 1275 | default N |
| 1273 | ---help--- | 1276 | ---help--- |
| 1274 | Enable support for National Instruments general purpose counters. | 1277 | Enable support for National Instruments general purpose counters. |
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index cd25b241cc1..fd274e9c7b7 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c | |||
| @@ -61,8 +61,6 @@ | |||
| 61 | #define PCI_DAQ_SIZE 4096 | 61 | #define PCI_DAQ_SIZE 4096 |
| 62 | #define PCI_DAQ_SIZE_660X 8192 | 62 | #define PCI_DAQ_SIZE_660X 8192 |
| 63 | 63 | ||
| 64 | MODULE_LICENSE("GPL"); | ||
| 65 | |||
| 66 | struct mite_struct *mite_devices; | 64 | struct mite_struct *mite_devices; |
| 67 | EXPORT_SYMBOL(mite_devices); | 65 | EXPORT_SYMBOL(mite_devices); |
| 68 | 66 | ||
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 14e716e99a5..54741c9e1af 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c | |||
| @@ -527,3 +527,7 @@ static void __exit driver_ni6527_cleanup_module(void) | |||
| 527 | 527 | ||
| 528 | module_init(driver_ni6527_init_module); | 528 | module_init(driver_ni6527_init_module); |
| 529 | module_exit(driver_ni6527_cleanup_module); | 529 | module_exit(driver_ni6527_cleanup_module); |
| 530 | |||
| 531 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 532 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 533 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 8b8e2aaf77f..403fc0997d3 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c | |||
| @@ -871,3 +871,7 @@ static void __exit driver_ni_65xx_cleanup_module(void) | |||
| 871 | 871 | ||
| 872 | module_init(driver_ni_65xx_init_module); | 872 | module_init(driver_ni_65xx_init_module); |
| 873 | module_exit(driver_ni_65xx_cleanup_module); | 873 | module_exit(driver_ni_65xx_cleanup_module); |
| 874 | |||
| 875 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 876 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 877 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6612b085c4e..ca2aeaa9449 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c | |||
| @@ -1421,3 +1421,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, | |||
| 1421 | }; | 1421 | }; |
| 1422 | return 0; | 1422 | return 0; |
| 1423 | } | 1423 | } |
| 1424 | |||
| 1425 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 1426 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 1427 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index e9f034efdc6..d8d91f90060 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c | |||
| @@ -384,3 +384,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot) | |||
| 384 | mite_list_devices(); | 384 | mite_list_devices(); |
| 385 | return -EIO; | 385 | return -EIO; |
| 386 | } | 386 | } |
| 387 | |||
| 388 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 389 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 390 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 84a15c34e48..005d2fe86ee 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c | |||
| @@ -1354,3 +1354,7 @@ static void __exit driver_pcidio_cleanup_module(void) | |||
| 1354 | 1354 | ||
| 1355 | module_init(driver_pcidio_init_module); | 1355 | module_init(driver_pcidio_init_module); |
| 1356 | module_exit(driver_pcidio_cleanup_module); | 1356 | module_exit(driver_pcidio_cleanup_module); |
| 1357 | |||
| 1358 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 1359 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 1360 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 23a38124728..9148abdad07 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c | |||
| @@ -1853,3 +1853,7 @@ static int pcimio_dio_change(struct comedi_device *dev, | |||
| 1853 | 1853 | ||
| 1854 | return 0; | 1854 | return 0; |
| 1855 | } | 1855 | } |
| 1856 | |||
| 1857 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | ||
| 1858 | MODULE_DESCRIPTION("Comedi low-level driver"); | ||
| 1859 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 54706a16dc0..b41c9640b72 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c | |||
| @@ -236,6 +236,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, | |||
| 236 | if (status == 1) { | 236 | if (status == 1) { |
| 237 | netif_carrier_on(net); | 237 | netif_carrier_on(net); |
| 238 | netif_wake_queue(net); | 238 | netif_wake_queue(net); |
| 239 | netif_notify_peers(net); | ||
| 239 | } else { | 240 | } else { |
| 240 | netif_carrier_off(net); | 241 | netif_carrier_off(net); |
| 241 | netif_stop_queue(net); | 242 | netif_stop_queue(net); |
diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index e38e89df6e8..e2f6d6a3c85 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c | |||
| @@ -874,7 +874,10 @@ static int nc_set_selected_input_dev(u8 value) | |||
| 874 | sc_access[3].reg_addr = 0x109; | 874 | sc_access[3].reg_addr = 0x109; |
| 875 | sc_access[3].mask = MASK6; | 875 | sc_access[3].mask = MASK6; |
| 876 | sc_access[3].value = 0x00; | 876 | sc_access[3].value = 0x00; |
| 877 | num_val = 4; | 877 | sc_access[4].reg_addr = 0x104; |
| 878 | sc_access[4].value = 0x3C; | ||
| 879 | sc_access[4].mask = 0xff; | ||
| 880 | num_val = 5; | ||
| 878 | break; | 881 | break; |
| 879 | default: | 882 | default: |
| 880 | return -EINVAL; | 883 | return -EINVAL; |
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 5415712f01f..4bd8cbdaee7 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
| @@ -227,6 +227,7 @@ static int zram_read(struct zram *zram, struct bio *bio) | |||
| 227 | 227 | ||
| 228 | if (zram_test_flag(zram, index, ZRAM_ZERO)) { | 228 | if (zram_test_flag(zram, index, ZRAM_ZERO)) { |
| 229 | handle_zero_page(page); | 229 | handle_zero_page(page); |
| 230 | index++; | ||
| 230 | continue; | 231 | continue; |
| 231 | } | 232 | } |
| 232 | 233 | ||
| @@ -235,12 +236,14 @@ static int zram_read(struct zram *zram, struct bio *bio) | |||
| 235 | pr_debug("Read before write: sector=%lu, size=%u", | 236 | pr_debug("Read before write: sector=%lu, size=%u", |
| 236 | (ulong)(bio->bi_sector), bio->bi_size); | 237 | (ulong)(bio->bi_sector), bio->bi_size); |
| 237 | /* Do nothing */ | 238 | /* Do nothing */ |
| 239 | index++; | ||
| 238 | continue; | 240 | continue; |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | /* Page is stored uncompressed since it's incompressible */ | 243 | /* Page is stored uncompressed since it's incompressible */ |
| 242 | if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { | 244 | if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { |
| 243 | handle_uncompressed_page(zram, page, index); | 245 | handle_uncompressed_page(zram, page, index); |
| 246 | index++; | ||
| 244 | continue; | 247 | continue; |
| 245 | } | 248 | } |
| 246 | 249 | ||
| @@ -320,6 +323,7 @@ static int zram_write(struct zram *zram, struct bio *bio) | |||
| 320 | mutex_unlock(&zram->lock); | 323 | mutex_unlock(&zram->lock); |
| 321 | zram_stat_inc(&zram->stats.pages_zero); | 324 | zram_stat_inc(&zram->stats.pages_zero); |
| 322 | zram_set_flag(zram, index, ZRAM_ZERO); | 325 | zram_set_flag(zram, index, ZRAM_ZERO); |
| 326 | index++; | ||
| 323 | continue; | 327 | continue; |
| 324 | } | 328 | } |
| 325 | 329 | ||
diff --git a/drivers/target/Makefile b/drivers/target/Makefile index 5cfd70819f0..973bb190ef5 100644 --- a/drivers/target/Makefile +++ b/drivers/target/Makefile | |||
| @@ -13,8 +13,7 @@ target_core_mod-y := target_core_configfs.o \ | |||
| 13 | target_core_transport.o \ | 13 | target_core_transport.o \ |
| 14 | target_core_cdb.o \ | 14 | target_core_cdb.o \ |
| 15 | target_core_ua.o \ | 15 | target_core_ua.o \ |
| 16 | target_core_rd.o \ | 16 | target_core_rd.o |
| 17 | target_core_mib.o | ||
| 18 | 17 | ||
| 19 | obj-$(CONFIG_TARGET_CORE) += target_core_mod.o | 18 | obj-$(CONFIG_TARGET_CORE) += target_core_mod.o |
| 20 | 19 | ||
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 2764510798b..caf8dc18ee0 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/parser.h> | 37 | #include <linux/parser.h> |
| 38 | #include <linux/syscalls.h> | 38 | #include <linux/syscalls.h> |
| 39 | #include <linux/configfs.h> | 39 | #include <linux/configfs.h> |
| 40 | #include <linux/proc_fs.h> | ||
| 41 | 40 | ||
| 42 | #include <target/target_core_base.h> | 41 | #include <target/target_core_base.h> |
| 43 | #include <target/target_core_device.h> | 42 | #include <target/target_core_device.h> |
| @@ -1971,13 +1970,35 @@ static void target_core_dev_release(struct config_item *item) | |||
| 1971 | { | 1970 | { |
| 1972 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), | 1971 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), |
| 1973 | struct se_subsystem_dev, se_dev_group); | 1972 | struct se_subsystem_dev, se_dev_group); |
| 1974 | struct config_group *dev_cg; | 1973 | struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); |
| 1975 | 1974 | struct se_subsystem_api *t = hba->transport; | |
| 1976 | if (!(se_dev)) | 1975 | struct config_group *dev_cg = &se_dev->se_dev_group; |
| 1977 | return; | ||
| 1978 | 1976 | ||
| 1979 | dev_cg = &se_dev->se_dev_group; | ||
| 1980 | kfree(dev_cg->default_groups); | 1977 | kfree(dev_cg->default_groups); |
| 1978 | /* | ||
| 1979 | * This pointer will set when the storage is enabled with: | ||
| 1980 | *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` | ||
| 1981 | */ | ||
| 1982 | if (se_dev->se_dev_ptr) { | ||
| 1983 | printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" | ||
| 1984 | "virtual_device() for se_dev_ptr: %p\n", | ||
| 1985 | se_dev->se_dev_ptr); | ||
| 1986 | |||
| 1987 | se_free_virtual_device(se_dev->se_dev_ptr, hba); | ||
| 1988 | } else { | ||
| 1989 | /* | ||
| 1990 | * Release struct se_subsystem_dev->se_dev_su_ptr.. | ||
| 1991 | */ | ||
| 1992 | printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" | ||
| 1993 | "device() for se_dev_su_ptr: %p\n", | ||
| 1994 | se_dev->se_dev_su_ptr); | ||
| 1995 | |||
| 1996 | t->free_device(se_dev->se_dev_su_ptr); | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" | ||
| 2000 | "_dev_t: %p\n", se_dev); | ||
| 2001 | kfree(se_dev); | ||
| 1981 | } | 2002 | } |
| 1982 | 2003 | ||
| 1983 | static ssize_t target_core_dev_show(struct config_item *item, | 2004 | static ssize_t target_core_dev_show(struct config_item *item, |
| @@ -2140,7 +2161,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = { | |||
| 2140 | NULL, | 2161 | NULL, |
| 2141 | }; | 2162 | }; |
| 2142 | 2163 | ||
| 2164 | static void target_core_alua_lu_gp_release(struct config_item *item) | ||
| 2165 | { | ||
| 2166 | struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item), | ||
| 2167 | struct t10_alua_lu_gp, lu_gp_group); | ||
| 2168 | |||
| 2169 | core_alua_free_lu_gp(lu_gp); | ||
| 2170 | } | ||
| 2171 | |||
| 2143 | static struct configfs_item_operations target_core_alua_lu_gp_ops = { | 2172 | static struct configfs_item_operations target_core_alua_lu_gp_ops = { |
| 2173 | .release = target_core_alua_lu_gp_release, | ||
| 2144 | .show_attribute = target_core_alua_lu_gp_attr_show, | 2174 | .show_attribute = target_core_alua_lu_gp_attr_show, |
| 2145 | .store_attribute = target_core_alua_lu_gp_attr_store, | 2175 | .store_attribute = target_core_alua_lu_gp_attr_store, |
| 2146 | }; | 2176 | }; |
| @@ -2191,9 +2221,11 @@ static void target_core_alua_drop_lu_gp( | |||
| 2191 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" | 2221 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" |
| 2192 | " Group: core/alua/lu_gps/%s, ID: %hu\n", | 2222 | " Group: core/alua/lu_gps/%s, ID: %hu\n", |
| 2193 | config_item_name(item), lu_gp->lu_gp_id); | 2223 | config_item_name(item), lu_gp->lu_gp_id); |
| 2194 | 2224 | /* | |
| 2225 | * core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release() | ||
| 2226 | * -> target_core_alua_lu_gp_release() | ||
| 2227 | */ | ||
| 2195 | config_item_put(item); | 2228 | config_item_put(item); |
| 2196 | core_alua_free_lu_gp(lu_gp); | ||
| 2197 | } | 2229 | } |
| 2198 | 2230 | ||
| 2199 | static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { | 2231 | static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { |
| @@ -2549,7 +2581,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { | |||
| 2549 | NULL, | 2581 | NULL, |
| 2550 | }; | 2582 | }; |
| 2551 | 2583 | ||
| 2584 | static void target_core_alua_tg_pt_gp_release(struct config_item *item) | ||
| 2585 | { | ||
| 2586 | struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item), | ||
| 2587 | struct t10_alua_tg_pt_gp, tg_pt_gp_group); | ||
| 2588 | |||
| 2589 | core_alua_free_tg_pt_gp(tg_pt_gp); | ||
| 2590 | } | ||
| 2591 | |||
| 2552 | static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { | 2592 | static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { |
| 2593 | .release = target_core_alua_tg_pt_gp_release, | ||
| 2553 | .show_attribute = target_core_alua_tg_pt_gp_attr_show, | 2594 | .show_attribute = target_core_alua_tg_pt_gp_attr_show, |
| 2554 | .store_attribute = target_core_alua_tg_pt_gp_attr_store, | 2595 | .store_attribute = target_core_alua_tg_pt_gp_attr_store, |
| 2555 | }; | 2596 | }; |
| @@ -2602,9 +2643,11 @@ static void target_core_alua_drop_tg_pt_gp( | |||
| 2602 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" | 2643 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" |
| 2603 | " Group: alua/tg_pt_gps/%s, ID: %hu\n", | 2644 | " Group: alua/tg_pt_gps/%s, ID: %hu\n", |
| 2604 | config_item_name(item), tg_pt_gp->tg_pt_gp_id); | 2645 | config_item_name(item), tg_pt_gp->tg_pt_gp_id); |
| 2605 | 2646 | /* | |
| 2647 | * core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release() | ||
| 2648 | * -> target_core_alua_tg_pt_gp_release(). | ||
| 2649 | */ | ||
| 2606 | config_item_put(item); | 2650 | config_item_put(item); |
| 2607 | core_alua_free_tg_pt_gp(tg_pt_gp); | ||
| 2608 | } | 2651 | } |
| 2609 | 2652 | ||
| 2610 | static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { | 2653 | static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { |
| @@ -2771,13 +2814,11 @@ static void target_core_drop_subdev( | |||
| 2771 | struct se_subsystem_api *t; | 2814 | struct se_subsystem_api *t; |
| 2772 | struct config_item *df_item; | 2815 | struct config_item *df_item; |
| 2773 | struct config_group *dev_cg, *tg_pt_gp_cg; | 2816 | struct config_group *dev_cg, *tg_pt_gp_cg; |
| 2774 | int i, ret; | 2817 | int i; |
| 2775 | 2818 | ||
| 2776 | hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); | 2819 | hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); |
| 2777 | 2820 | ||
| 2778 | if (mutex_lock_interruptible(&hba->hba_access_mutex)) | 2821 | mutex_lock(&hba->hba_access_mutex); |
| 2779 | goto out; | ||
| 2780 | |||
| 2781 | t = hba->transport; | 2822 | t = hba->transport; |
| 2782 | 2823 | ||
| 2783 | spin_lock(&se_global->g_device_lock); | 2824 | spin_lock(&se_global->g_device_lock); |
| @@ -2791,7 +2832,10 @@ static void target_core_drop_subdev( | |||
| 2791 | config_item_put(df_item); | 2832 | config_item_put(df_item); |
| 2792 | } | 2833 | } |
| 2793 | kfree(tg_pt_gp_cg->default_groups); | 2834 | kfree(tg_pt_gp_cg->default_groups); |
| 2794 | core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); | 2835 | /* |
| 2836 | * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp | ||
| 2837 | * directly from target_core_alua_tg_pt_gp_release(). | ||
| 2838 | */ | ||
| 2795 | T10_ALUA(se_dev)->default_tg_pt_gp = NULL; | 2839 | T10_ALUA(se_dev)->default_tg_pt_gp = NULL; |
| 2796 | 2840 | ||
| 2797 | dev_cg = &se_dev->se_dev_group; | 2841 | dev_cg = &se_dev->se_dev_group; |
| @@ -2800,38 +2844,12 @@ static void target_core_drop_subdev( | |||
| 2800 | dev_cg->default_groups[i] = NULL; | 2844 | dev_cg->default_groups[i] = NULL; |
| 2801 | config_item_put(df_item); | 2845 | config_item_put(df_item); |
| 2802 | } | 2846 | } |
| 2803 | |||
| 2804 | config_item_put(item); | ||
| 2805 | /* | 2847 | /* |
| 2806 | * This pointer will set when the storage is enabled with: | 2848 | * The releasing of se_dev and associated se_dev->se_dev_ptr is done |
| 2807 | * `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` | 2849 | * from target_core_dev_item_ops->release() ->target_core_dev_release(). |
| 2808 | */ | 2850 | */ |
| 2809 | if (se_dev->se_dev_ptr) { | 2851 | config_item_put(item); |
| 2810 | printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" | ||
| 2811 | "virtual_device() for se_dev_ptr: %p\n", | ||
| 2812 | se_dev->se_dev_ptr); | ||
| 2813 | |||
| 2814 | ret = se_free_virtual_device(se_dev->se_dev_ptr, hba); | ||
| 2815 | if (ret < 0) | ||
| 2816 | goto hba_out; | ||
| 2817 | } else { | ||
| 2818 | /* | ||
| 2819 | * Release struct se_subsystem_dev->se_dev_su_ptr.. | ||
| 2820 | */ | ||
| 2821 | printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" | ||
| 2822 | "device() for se_dev_su_ptr: %p\n", | ||
| 2823 | se_dev->se_dev_su_ptr); | ||
| 2824 | |||
| 2825 | t->free_device(se_dev->se_dev_su_ptr); | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" | ||
| 2829 | "_dev_t: %p\n", se_dev); | ||
| 2830 | |||
| 2831 | hba_out: | ||
| 2832 | mutex_unlock(&hba->hba_access_mutex); | 2852 | mutex_unlock(&hba->hba_access_mutex); |
| 2833 | out: | ||
| 2834 | kfree(se_dev); | ||
| 2835 | } | 2853 | } |
| 2836 | 2854 | ||
| 2837 | static struct configfs_group_operations target_core_hba_group_ops = { | 2855 | static struct configfs_group_operations target_core_hba_group_ops = { |
| @@ -2914,6 +2932,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR); | |||
| 2914 | 2932 | ||
| 2915 | CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); | 2933 | CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); |
| 2916 | 2934 | ||
| 2935 | static void target_core_hba_release(struct config_item *item) | ||
| 2936 | { | ||
| 2937 | struct se_hba *hba = container_of(to_config_group(item), | ||
| 2938 | struct se_hba, hba_group); | ||
| 2939 | core_delete_hba(hba); | ||
| 2940 | } | ||
| 2941 | |||
| 2917 | static struct configfs_attribute *target_core_hba_attrs[] = { | 2942 | static struct configfs_attribute *target_core_hba_attrs[] = { |
| 2918 | &target_core_hba_hba_info.attr, | 2943 | &target_core_hba_hba_info.attr, |
| 2919 | &target_core_hba_hba_mode.attr, | 2944 | &target_core_hba_hba_mode.attr, |
| @@ -2921,6 +2946,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = { | |||
| 2921 | }; | 2946 | }; |
| 2922 | 2947 | ||
| 2923 | static struct configfs_item_operations target_core_hba_item_ops = { | 2948 | static struct configfs_item_operations target_core_hba_item_ops = { |
| 2949 | .release = target_core_hba_release, | ||
| 2924 | .show_attribute = target_core_hba_attr_show, | 2950 | .show_attribute = target_core_hba_attr_show, |
| 2925 | .store_attribute = target_core_hba_attr_store, | 2951 | .store_attribute = target_core_hba_attr_store, |
| 2926 | }; | 2952 | }; |
| @@ -2997,10 +3023,11 @@ static void target_core_call_delhbafromtarget( | |||
| 2997 | struct config_group *group, | 3023 | struct config_group *group, |
| 2998 | struct config_item *item) | 3024 | struct config_item *item) |
| 2999 | { | 3025 | { |
| 3000 | struct se_hba *hba = item_to_hba(item); | 3026 | /* |
| 3001 | 3027 | * core_delete_hba() is called from target_core_hba_item_ops->release() | |
| 3028 | * -> target_core_hba_release() | ||
| 3029 | */ | ||
| 3002 | config_item_put(item); | 3030 | config_item_put(item); |
| 3003 | core_delete_hba(hba); | ||
| 3004 | } | 3031 | } |
| 3005 | 3032 | ||
| 3006 | static struct configfs_group_operations target_core_group_ops = { | 3033 | static struct configfs_group_operations target_core_group_ops = { |
| @@ -3022,7 +3049,6 @@ static int target_core_init_configfs(void) | |||
| 3022 | struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; | 3049 | struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; |
| 3023 | struct config_group *lu_gp_cg = NULL; | 3050 | struct config_group *lu_gp_cg = NULL; |
| 3024 | struct configfs_subsystem *subsys; | 3051 | struct configfs_subsystem *subsys; |
| 3025 | struct proc_dir_entry *scsi_target_proc = NULL; | ||
| 3026 | struct t10_alua_lu_gp *lu_gp; | 3052 | struct t10_alua_lu_gp *lu_gp; |
| 3027 | int ret; | 3053 | int ret; |
| 3028 | 3054 | ||
| @@ -3128,21 +3154,10 @@ static int target_core_init_configfs(void) | |||
| 3128 | if (core_dev_setup_virtual_lun0() < 0) | 3154 | if (core_dev_setup_virtual_lun0() < 0) |
| 3129 | goto out; | 3155 | goto out; |
| 3130 | 3156 | ||
| 3131 | scsi_target_proc = proc_mkdir("scsi_target", 0); | ||
| 3132 | if (!(scsi_target_proc)) { | ||
| 3133 | printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n"); | ||
| 3134 | goto out; | ||
| 3135 | } | ||
| 3136 | ret = init_scsi_target_mib(); | ||
| 3137 | if (ret < 0) | ||
| 3138 | goto out; | ||
| 3139 | |||
| 3140 | return 0; | 3157 | return 0; |
| 3141 | 3158 | ||
| 3142 | out: | 3159 | out: |
| 3143 | configfs_unregister_subsystem(subsys); | 3160 | configfs_unregister_subsystem(subsys); |
| 3144 | if (scsi_target_proc) | ||
| 3145 | remove_proc_entry("scsi_target", 0); | ||
| 3146 | core_dev_release_virtual_lun0(); | 3161 | core_dev_release_virtual_lun0(); |
| 3147 | rd_module_exit(); | 3162 | rd_module_exit(); |
| 3148 | out_global: | 3163 | out_global: |
| @@ -3178,8 +3193,7 @@ static void target_core_exit_configfs(void) | |||
| 3178 | config_item_put(item); | 3193 | config_item_put(item); |
| 3179 | } | 3194 | } |
| 3180 | kfree(lu_gp_cg->default_groups); | 3195 | kfree(lu_gp_cg->default_groups); |
| 3181 | core_alua_free_lu_gp(se_global->default_lu_gp); | 3196 | lu_gp_cg->default_groups = NULL; |
| 3182 | se_global->default_lu_gp = NULL; | ||
| 3183 | 3197 | ||
| 3184 | alua_cg = &se_global->alua_group; | 3198 | alua_cg = &se_global->alua_group; |
| 3185 | for (i = 0; alua_cg->default_groups[i]; i++) { | 3199 | for (i = 0; alua_cg->default_groups[i]; i++) { |
| @@ -3188,6 +3202,7 @@ static void target_core_exit_configfs(void) | |||
| 3188 | config_item_put(item); | 3202 | config_item_put(item); |
| 3189 | } | 3203 | } |
| 3190 | kfree(alua_cg->default_groups); | 3204 | kfree(alua_cg->default_groups); |
| 3205 | alua_cg->default_groups = NULL; | ||
| 3191 | 3206 | ||
| 3192 | hba_cg = &se_global->target_core_hbagroup; | 3207 | hba_cg = &se_global->target_core_hbagroup; |
| 3193 | for (i = 0; hba_cg->default_groups[i]; i++) { | 3208 | for (i = 0; hba_cg->default_groups[i]; i++) { |
| @@ -3196,20 +3211,20 @@ static void target_core_exit_configfs(void) | |||
| 3196 | config_item_put(item); | 3211 | config_item_put(item); |
| 3197 | } | 3212 | } |
| 3198 | kfree(hba_cg->default_groups); | 3213 | kfree(hba_cg->default_groups); |
| 3199 | 3214 | hba_cg->default_groups = NULL; | |
| 3200 | for (i = 0; subsys->su_group.default_groups[i]; i++) { | 3215 | /* |
| 3201 | item = &subsys->su_group.default_groups[i]->cg_item; | 3216 | * We expect subsys->su_group.default_groups to be released |
| 3202 | subsys->su_group.default_groups[i] = NULL; | 3217 | * by configfs subsystem provider logic.. |
| 3203 | config_item_put(item); | 3218 | */ |
| 3204 | } | 3219 | configfs_unregister_subsystem(subsys); |
| 3205 | kfree(subsys->su_group.default_groups); | 3220 | kfree(subsys->su_group.default_groups); |
| 3206 | 3221 | ||
| 3207 | configfs_unregister_subsystem(subsys); | 3222 | core_alua_free_lu_gp(se_global->default_lu_gp); |
| 3223 | se_global->default_lu_gp = NULL; | ||
| 3224 | |||
| 3208 | printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" | 3225 | printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" |
| 3209 | " Infrastructure\n"); | 3226 | " Infrastructure\n"); |
| 3210 | 3227 | ||
| 3211 | remove_scsi_target_mib(); | ||
| 3212 | remove_proc_entry("scsi_target", 0); | ||
| 3213 | core_dev_release_virtual_lun0(); | 3228 | core_dev_release_virtual_lun0(); |
| 3214 | rd_module_exit(); | 3229 | rd_module_exit(); |
| 3215 | release_se_global(); | 3230 | release_se_global(); |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 317ce58d426..5da051a07fa 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
| @@ -373,11 +373,11 @@ int core_update_device_list_for_node( | |||
| 373 | /* | 373 | /* |
| 374 | * deve->se_lun_acl will be NULL for demo-mode created LUNs | 374 | * deve->se_lun_acl will be NULL for demo-mode created LUNs |
| 375 | * that have not been explictly concerted to MappedLUNs -> | 375 | * that have not been explictly concerted to MappedLUNs -> |
| 376 | * struct se_lun_acl. | 376 | * struct se_lun_acl, but we remove deve->alua_port_list from |
| 377 | * port->sep_alua_list. This also means that active UAs and | ||
| 378 | * NodeACL context specific PR metadata for demo-mode | ||
| 379 | * MappedLUN *deve will be released below.. | ||
| 377 | */ | 380 | */ |
| 378 | if (!(deve->se_lun_acl)) | ||
| 379 | return 0; | ||
| 380 | |||
| 381 | spin_lock_bh(&port->sep_alua_lock); | 381 | spin_lock_bh(&port->sep_alua_lock); |
| 382 | list_del(&deve->alua_port_list); | 382 | list_del(&deve->alua_port_list); |
| 383 | spin_unlock_bh(&port->sep_alua_lock); | 383 | spin_unlock_bh(&port->sep_alua_lock); |
| @@ -395,12 +395,14 @@ int core_update_device_list_for_node( | |||
| 395 | printk(KERN_ERR "struct se_dev_entry->se_lun_acl" | 395 | printk(KERN_ERR "struct se_dev_entry->se_lun_acl" |
| 396 | " already set for demo mode -> explict" | 396 | " already set for demo mode -> explict" |
| 397 | " LUN ACL transition\n"); | 397 | " LUN ACL transition\n"); |
| 398 | spin_unlock_irq(&nacl->device_list_lock); | ||
| 398 | return -1; | 399 | return -1; |
| 399 | } | 400 | } |
| 400 | if (deve->se_lun != lun) { | 401 | if (deve->se_lun != lun) { |
| 401 | printk(KERN_ERR "struct se_dev_entry->se_lun does" | 402 | printk(KERN_ERR "struct se_dev_entry->se_lun does" |
| 402 | " match passed struct se_lun for demo mode" | 403 | " match passed struct se_lun for demo mode" |
| 403 | " -> explict LUN ACL transition\n"); | 404 | " -> explict LUN ACL transition\n"); |
| 405 | spin_unlock_irq(&nacl->device_list_lock); | ||
| 404 | return -1; | 406 | return -1; |
| 405 | } | 407 | } |
| 406 | deve->se_lun_acl = lun_acl; | 408 | deve->se_lun_acl = lun_acl; |
| @@ -865,9 +867,6 @@ static void se_dev_stop(struct se_device *dev) | |||
| 865 | } | 867 | } |
| 866 | } | 868 | } |
| 867 | spin_unlock(&hba->device_lock); | 869 | spin_unlock(&hba->device_lock); |
| 868 | |||
| 869 | while (atomic_read(&hba->dev_mib_access_count)) | ||
| 870 | cpu_relax(); | ||
| 871 | } | 870 | } |
| 872 | 871 | ||
| 873 | int se_dev_check_online(struct se_device *dev) | 872 | int se_dev_check_online(struct se_device *dev) |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 32b148d7e26..b65d1c8e774 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
| @@ -214,12 +214,22 @@ TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR); | |||
| 214 | 214 | ||
| 215 | CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); | 215 | CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); |
| 216 | 216 | ||
| 217 | static void target_fabric_mappedlun_release(struct config_item *item) | ||
| 218 | { | ||
| 219 | struct se_lun_acl *lacl = container_of(to_config_group(item), | ||
| 220 | struct se_lun_acl, se_lun_group); | ||
| 221 | struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; | ||
| 222 | |||
| 223 | core_dev_free_initiator_node_lun_acl(se_tpg, lacl); | ||
| 224 | } | ||
| 225 | |||
| 217 | static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { | 226 | static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { |
| 218 | &target_fabric_mappedlun_write_protect.attr, | 227 | &target_fabric_mappedlun_write_protect.attr, |
| 219 | NULL, | 228 | NULL, |
| 220 | }; | 229 | }; |
| 221 | 230 | ||
| 222 | static struct configfs_item_operations target_fabric_mappedlun_item_ops = { | 231 | static struct configfs_item_operations target_fabric_mappedlun_item_ops = { |
| 232 | .release = target_fabric_mappedlun_release, | ||
| 223 | .show_attribute = target_fabric_mappedlun_attr_show, | 233 | .show_attribute = target_fabric_mappedlun_attr_show, |
| 224 | .store_attribute = target_fabric_mappedlun_attr_store, | 234 | .store_attribute = target_fabric_mappedlun_attr_store, |
| 225 | .allow_link = target_fabric_mappedlun_link, | 235 | .allow_link = target_fabric_mappedlun_link, |
| @@ -337,15 +347,21 @@ static void target_fabric_drop_mappedlun( | |||
| 337 | struct config_group *group, | 347 | struct config_group *group, |
| 338 | struct config_item *item) | 348 | struct config_item *item) |
| 339 | { | 349 | { |
| 340 | struct se_lun_acl *lacl = container_of(to_config_group(item), | ||
| 341 | struct se_lun_acl, se_lun_group); | ||
| 342 | struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; | ||
| 343 | |||
| 344 | config_item_put(item); | 350 | config_item_put(item); |
| 345 | core_dev_free_initiator_node_lun_acl(se_tpg, lacl); | 351 | } |
| 352 | |||
| 353 | static void target_fabric_nacl_base_release(struct config_item *item) | ||
| 354 | { | ||
| 355 | struct se_node_acl *se_nacl = container_of(to_config_group(item), | ||
| 356 | struct se_node_acl, acl_group); | ||
| 357 | struct se_portal_group *se_tpg = se_nacl->se_tpg; | ||
| 358 | struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; | ||
| 359 | |||
| 360 | tf->tf_ops.fabric_drop_nodeacl(se_nacl); | ||
| 346 | } | 361 | } |
| 347 | 362 | ||
| 348 | static struct configfs_item_operations target_fabric_nacl_base_item_ops = { | 363 | static struct configfs_item_operations target_fabric_nacl_base_item_ops = { |
| 364 | .release = target_fabric_nacl_base_release, | ||
| 349 | .show_attribute = target_fabric_nacl_base_attr_show, | 365 | .show_attribute = target_fabric_nacl_base_attr_show, |
| 350 | .store_attribute = target_fabric_nacl_base_attr_store, | 366 | .store_attribute = target_fabric_nacl_base_attr_store, |
| 351 | }; | 367 | }; |
| @@ -404,9 +420,6 @@ static void target_fabric_drop_nodeacl( | |||
| 404 | struct config_group *group, | 420 | struct config_group *group, |
| 405 | struct config_item *item) | 421 | struct config_item *item) |
| 406 | { | 422 | { |
| 407 | struct se_portal_group *se_tpg = container_of(group, | ||
| 408 | struct se_portal_group, tpg_acl_group); | ||
| 409 | struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; | ||
| 410 | struct se_node_acl *se_nacl = container_of(to_config_group(item), | 423 | struct se_node_acl *se_nacl = container_of(to_config_group(item), |
| 411 | struct se_node_acl, acl_group); | 424 | struct se_node_acl, acl_group); |
| 412 | struct config_item *df_item; | 425 | struct config_item *df_item; |
| @@ -419,9 +432,10 @@ static void target_fabric_drop_nodeacl( | |||
| 419 | nacl_cg->default_groups[i] = NULL; | 432 | nacl_cg->default_groups[i] = NULL; |
| 420 | config_item_put(df_item); | 433 | config_item_put(df_item); |
| 421 | } | 434 | } |
| 422 | 435 | /* | |
| 436 | * struct se_node_acl free is done in target_fabric_nacl_base_release() | ||
| 437 | */ | ||
| 423 | config_item_put(item); | 438 | config_item_put(item); |
| 424 | tf->tf_ops.fabric_drop_nodeacl(se_nacl); | ||
| 425 | } | 439 | } |
| 426 | 440 | ||
| 427 | static struct configfs_group_operations target_fabric_nacl_group_ops = { | 441 | static struct configfs_group_operations target_fabric_nacl_group_ops = { |
| @@ -437,7 +451,18 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL); | |||
| 437 | 451 | ||
| 438 | CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); | 452 | CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); |
| 439 | 453 | ||
| 454 | static void target_fabric_np_base_release(struct config_item *item) | ||
| 455 | { | ||
| 456 | struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), | ||
| 457 | struct se_tpg_np, tpg_np_group); | ||
| 458 | struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent; | ||
| 459 | struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; | ||
| 460 | |||
| 461 | tf->tf_ops.fabric_drop_np(se_tpg_np); | ||
| 462 | } | ||
| 463 | |||
| 440 | static struct configfs_item_operations target_fabric_np_base_item_ops = { | 464 | static struct configfs_item_operations target_fabric_np_base_item_ops = { |
| 465 | .release = target_fabric_np_base_release, | ||
| 441 | .show_attribute = target_fabric_np_base_attr_show, | 466 | .show_attribute = target_fabric_np_base_attr_show, |
| 442 | .store_attribute = target_fabric_np_base_attr_store, | 467 | .store_attribute = target_fabric_np_base_attr_store, |
| 443 | }; | 468 | }; |
| @@ -466,6 +491,7 @@ static struct config_group *target_fabric_make_np( | |||
| 466 | if (!(se_tpg_np) || IS_ERR(se_tpg_np)) | 491 | if (!(se_tpg_np) || IS_ERR(se_tpg_np)) |
| 467 | return ERR_PTR(-EINVAL); | 492 | return ERR_PTR(-EINVAL); |
| 468 | 493 | ||
| 494 | se_tpg_np->tpg_np_parent = se_tpg; | ||
| 469 | config_group_init_type_name(&se_tpg_np->tpg_np_group, name, | 495 | config_group_init_type_name(&se_tpg_np->tpg_np_group, name, |
| 470 | &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit); | 496 | &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit); |
| 471 | 497 | ||
| @@ -476,14 +502,10 @@ static void target_fabric_drop_np( | |||
| 476 | struct config_group *group, | 502 | struct config_group *group, |
| 477 | struct config_item *item) | 503 | struct config_item *item) |
| 478 | { | 504 | { |
| 479 | struct se_portal_group *se_tpg = container_of(group, | 505 | /* |
| 480 | struct se_portal_group, tpg_np_group); | 506 | * struct se_tpg_np is released via target_fabric_np_base_release() |
| 481 | struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; | 507 | */ |
| 482 | struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), | ||
| 483 | struct se_tpg_np, tpg_np_group); | ||
| 484 | |||
| 485 | config_item_put(item); | 508 | config_item_put(item); |
| 486 | tf->tf_ops.fabric_drop_np(se_tpg_np); | ||
| 487 | } | 509 | } |
| 488 | 510 | ||
| 489 | static struct configfs_group_operations target_fabric_np_group_ops = { | 511 | static struct configfs_group_operations target_fabric_np_group_ops = { |
| @@ -814,7 +836,18 @@ TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL); | |||
| 814 | */ | 836 | */ |
| 815 | CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); | 837 | CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); |
| 816 | 838 | ||
| 839 | static void target_fabric_tpg_release(struct config_item *item) | ||
| 840 | { | ||
| 841 | struct se_portal_group *se_tpg = container_of(to_config_group(item), | ||
| 842 | struct se_portal_group, tpg_group); | ||
| 843 | struct se_wwn *wwn = se_tpg->se_tpg_wwn; | ||
| 844 | struct target_fabric_configfs *tf = wwn->wwn_tf; | ||
| 845 | |||
| 846 | tf->tf_ops.fabric_drop_tpg(se_tpg); | ||
| 847 | } | ||
| 848 | |||
| 817 | static struct configfs_item_operations target_fabric_tpg_base_item_ops = { | 849 | static struct configfs_item_operations target_fabric_tpg_base_item_ops = { |
| 850 | .release = target_fabric_tpg_release, | ||
| 818 | .show_attribute = target_fabric_tpg_attr_show, | 851 | .show_attribute = target_fabric_tpg_attr_show, |
| 819 | .store_attribute = target_fabric_tpg_attr_store, | 852 | .store_attribute = target_fabric_tpg_attr_store, |
| 820 | }; | 853 | }; |
| @@ -872,8 +905,6 @@ static void target_fabric_drop_tpg( | |||
| 872 | struct config_group *group, | 905 | struct config_group *group, |
| 873 | struct config_item *item) | 906 | struct config_item *item) |
| 874 | { | 907 | { |
| 875 | struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group); | ||
| 876 | struct target_fabric_configfs *tf = wwn->wwn_tf; | ||
| 877 | struct se_portal_group *se_tpg = container_of(to_config_group(item), | 908 | struct se_portal_group *se_tpg = container_of(to_config_group(item), |
| 878 | struct se_portal_group, tpg_group); | 909 | struct se_portal_group, tpg_group); |
| 879 | struct config_group *tpg_cg = &se_tpg->tpg_group; | 910 | struct config_group *tpg_cg = &se_tpg->tpg_group; |
| @@ -890,15 +921,28 @@ static void target_fabric_drop_tpg( | |||
| 890 | } | 921 | } |
| 891 | 922 | ||
| 892 | config_item_put(item); | 923 | config_item_put(item); |
| 893 | tf->tf_ops.fabric_drop_tpg(se_tpg); | ||
| 894 | } | 924 | } |
| 895 | 925 | ||
| 926 | static void target_fabric_release_wwn(struct config_item *item) | ||
| 927 | { | ||
| 928 | struct se_wwn *wwn = container_of(to_config_group(item), | ||
| 929 | struct se_wwn, wwn_group); | ||
| 930 | struct target_fabric_configfs *tf = wwn->wwn_tf; | ||
| 931 | |||
| 932 | tf->tf_ops.fabric_drop_wwn(wwn); | ||
| 933 | } | ||
| 934 | |||
| 935 | static struct configfs_item_operations target_fabric_tpg_item_ops = { | ||
| 936 | .release = target_fabric_release_wwn, | ||
| 937 | }; | ||
| 938 | |||
| 896 | static struct configfs_group_operations target_fabric_tpg_group_ops = { | 939 | static struct configfs_group_operations target_fabric_tpg_group_ops = { |
| 897 | .make_group = target_fabric_make_tpg, | 940 | .make_group = target_fabric_make_tpg, |
| 898 | .drop_item = target_fabric_drop_tpg, | 941 | .drop_item = target_fabric_drop_tpg, |
| 899 | }; | 942 | }; |
| 900 | 943 | ||
| 901 | TF_CIT_SETUP(tpg, NULL, &target_fabric_tpg_group_ops, NULL); | 944 | TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops, |
| 945 | NULL); | ||
| 902 | 946 | ||
| 903 | /* End of tfc_tpg_cit */ | 947 | /* End of tfc_tpg_cit */ |
| 904 | 948 | ||
| @@ -932,13 +976,7 @@ static void target_fabric_drop_wwn( | |||
| 932 | struct config_group *group, | 976 | struct config_group *group, |
| 933 | struct config_item *item) | 977 | struct config_item *item) |
| 934 | { | 978 | { |
| 935 | struct target_fabric_configfs *tf = container_of(group, | ||
| 936 | struct target_fabric_configfs, tf_group); | ||
| 937 | struct se_wwn *wwn = container_of(to_config_group(item), | ||
| 938 | struct se_wwn, wwn_group); | ||
| 939 | |||
| 940 | config_item_put(item); | 979 | config_item_put(item); |
| 941 | tf->tf_ops.fabric_drop_wwn(wwn); | ||
| 942 | } | 980 | } |
| 943 | 981 | ||
| 944 | static struct configfs_group_operations target_fabric_wwn_group_ops = { | 982 | static struct configfs_group_operations target_fabric_wwn_group_ops = { |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index c6e0d757e76..67f0c09983c 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
| @@ -154,7 +154,7 @@ static struct se_device *iblock_create_virtdevice( | |||
| 154 | 154 | ||
| 155 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, | 155 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, |
| 156 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); | 156 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); |
| 157 | if (!(bd)) | 157 | if (IS_ERR(bd)) |
| 158 | goto failed; | 158 | goto failed; |
| 159 | /* | 159 | /* |
| 160 | * Setup the local scope queue_limits from struct request_queue->limits | 160 | * Setup the local scope queue_limits from struct request_queue->limits |
| @@ -220,8 +220,10 @@ static void iblock_free_device(void *p) | |||
| 220 | { | 220 | { |
| 221 | struct iblock_dev *ib_dev = p; | 221 | struct iblock_dev *ib_dev = p; |
| 222 | 222 | ||
| 223 | blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); | 223 | if (ib_dev->ibd_bd != NULL) |
| 224 | bioset_free(ib_dev->ibd_bio_set); | 224 | blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); |
| 225 | if (ib_dev->ibd_bio_set != NULL) | ||
| 226 | bioset_free(ib_dev->ibd_bio_set); | ||
| 225 | kfree(ib_dev); | 227 | kfree(ib_dev); |
| 226 | } | 228 | } |
| 227 | 229 | ||
diff --git a/drivers/target/target_core_mib.c b/drivers/target/target_core_mib.c deleted file mode 100644 index d5a48aa0d2d..00000000000 --- a/drivers/target/target_core_mib.c +++ /dev/null | |||
| @@ -1,1078 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Filename: target_core_mib.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. | ||
| 5 | * Copyright (c) 2007-2010 Rising Tide Systems | ||
| 6 | * Copyright (c) 2008-2010 Linux-iSCSI.org | ||
| 7 | * | ||
| 8 | * Nicholas A. Bellinger <nab@linux-iscsi.org> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 23 | * | ||
| 24 | ******************************************************************************/ | ||
| 25 | |||
| 26 | |||
| 27 | #include <linux/kernel.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/delay.h> | ||
| 30 | #include <linux/timer.h> | ||
| 31 | #include <linux/string.h> | ||
| 32 | #include <linux/version.h> | ||
| 33 | #include <generated/utsrelease.h> | ||
| 34 | #include <linux/utsname.h> | ||
| 35 | #include <linux/proc_fs.h> | ||
| 36 | #include <linux/seq_file.h> | ||
| 37 | #include <linux/blkdev.h> | ||
| 38 | #include <scsi/scsi.h> | ||
| 39 | #include <scsi/scsi_device.h> | ||
| 40 | #include <scsi/scsi_host.h> | ||
| 41 | |||
| 42 | #include <target/target_core_base.h> | ||
| 43 | #include <target/target_core_transport.h> | ||
| 44 | #include <target/target_core_fabric_ops.h> | ||
| 45 | #include <target/target_core_configfs.h> | ||
| 46 | |||
| 47 | #include "target_core_hba.h" | ||
| 48 | #include "target_core_mib.h" | ||
| 49 | |||
| 50 | /* SCSI mib table index */ | ||
| 51 | static struct scsi_index_table scsi_index_table; | ||
| 52 | |||
| 53 | #ifndef INITIAL_JIFFIES | ||
| 54 | #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /* SCSI Instance Table */ | ||
| 58 | #define SCSI_INST_SW_INDEX 1 | ||
| 59 | #define SCSI_TRANSPORT_INDEX 1 | ||
| 60 | |||
| 61 | #define NONE "None" | ||
| 62 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) | ||
| 63 | |||
| 64 | static inline int list_is_first(const struct list_head *list, | ||
| 65 | const struct list_head *head) | ||
| 66 | { | ||
| 67 | return list->prev == head; | ||
| 68 | } | ||
| 69 | |||
| 70 | static void *locate_hba_start( | ||
| 71 | struct seq_file *seq, | ||
| 72 | loff_t *pos) | ||
| 73 | { | ||
| 74 | spin_lock(&se_global->g_device_lock); | ||
| 75 | return seq_list_start(&se_global->g_se_dev_list, *pos); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void *locate_hba_next( | ||
| 79 | struct seq_file *seq, | ||
| 80 | void *v, | ||
| 81 | loff_t *pos) | ||
| 82 | { | ||
| 83 | return seq_list_next(v, &se_global->g_se_dev_list, pos); | ||
| 84 | } | ||
| 85 | |||
| 86 | static void locate_hba_stop(struct seq_file *seq, void *v) | ||
| 87 | { | ||
| 88 | spin_unlock(&se_global->g_device_lock); | ||
| 89 | } | ||
| 90 | |||
| 91 | /**************************************************************************** | ||
| 92 | * SCSI MIB Tables | ||
| 93 | ****************************************************************************/ | ||
| 94 | |||
| 95 | /* | ||
| 96 | * SCSI Instance Table | ||
| 97 | */ | ||
| 98 | static void *scsi_inst_seq_start( | ||
| 99 | struct seq_file *seq, | ||
| 100 | loff_t *pos) | ||
| 101 | { | ||
| 102 | spin_lock(&se_global->hba_lock); | ||
| 103 | return seq_list_start(&se_global->g_hba_list, *pos); | ||
| 104 | } | ||
| 105 | |||
| 106 | static void *scsi_inst_seq_next( | ||
| 107 | struct seq_file *seq, | ||
| 108 | void *v, | ||
| 109 | loff_t *pos) | ||
| 110 | { | ||
| 111 | return seq_list_next(v, &se_global->g_hba_list, pos); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void scsi_inst_seq_stop(struct seq_file *seq, void *v) | ||
| 115 | { | ||
| 116 | spin_unlock(&se_global->hba_lock); | ||
| 117 | } | ||
| 118 | |||
| 119 | static int scsi_inst_seq_show(struct seq_file *seq, void *v) | ||
| 120 | { | ||
| 121 | struct se_hba *hba = list_entry(v, struct se_hba, hba_list); | ||
| 122 | |||
| 123 | if (list_is_first(&hba->hba_list, &se_global->g_hba_list)) | ||
| 124 | seq_puts(seq, "inst sw_indx\n"); | ||
| 125 | |||
| 126 | seq_printf(seq, "%u %u\n", hba->hba_index, SCSI_INST_SW_INDEX); | ||
| 127 | seq_printf(seq, "plugin: %s version: %s\n", | ||
| 128 | hba->transport->name, TARGET_CORE_VERSION); | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static const struct seq_operations scsi_inst_seq_ops = { | ||
| 134 | .start = scsi_inst_seq_start, | ||
| 135 | .next = scsi_inst_seq_next, | ||
| 136 | .stop = scsi_inst_seq_stop, | ||
| 137 | .show = scsi_inst_seq_show | ||
| 138 | }; | ||
| 139 | |||
| 140 | static int scsi_inst_seq_open(struct inode *inode, struct file *file) | ||
| 141 | { | ||
| 142 | return seq_open(file, &scsi_inst_seq_ops); | ||
| 143 | } | ||
| 144 | |||
| 145 | static const struct file_operations scsi_inst_seq_fops = { | ||
| 146 | .owner = THIS_MODULE, | ||
| 147 | .open = scsi_inst_seq_open, | ||
| 148 | .read = seq_read, | ||
| 149 | .llseek = seq_lseek, | ||
| 150 | .release = seq_release, | ||
| 151 | }; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * SCSI Device Table | ||
| 155 | */ | ||
| 156 | static void *scsi_dev_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 157 | { | ||
| 158 | return locate_hba_start(seq, pos); | ||
| 159 | } | ||
| 160 | |||
| 161 | static void *scsi_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 162 | { | ||
| 163 | return locate_hba_next(seq, v, pos); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void scsi_dev_seq_stop(struct seq_file *seq, void *v) | ||
| 167 | { | ||
| 168 | locate_hba_stop(seq, v); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int scsi_dev_seq_show(struct seq_file *seq, void *v) | ||
| 172 | { | ||
| 173 | struct se_hba *hba; | ||
| 174 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 175 | g_se_dev_list); | ||
| 176 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 177 | char str[28]; | ||
| 178 | int k; | ||
| 179 | |||
| 180 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 181 | seq_puts(seq, "inst indx role ports\n"); | ||
| 182 | |||
| 183 | if (!(dev)) | ||
| 184 | return 0; | ||
| 185 | |||
| 186 | hba = dev->se_hba; | ||
| 187 | if (!(hba)) { | ||
| 188 | /* Log error ? */ | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | seq_printf(seq, "%u %u %s %u\n", hba->hba_index, | ||
| 193 | dev->dev_index, "Target", dev->dev_port_count); | ||
| 194 | |||
| 195 | memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); | ||
| 196 | |||
| 197 | /* vendor */ | ||
| 198 | for (k = 0; k < 8; k++) | ||
| 199 | str[k] = ISPRINT(DEV_T10_WWN(dev)->vendor[k]) ? | ||
| 200 | DEV_T10_WWN(dev)->vendor[k] : 0x20; | ||
| 201 | str[k] = 0x20; | ||
| 202 | |||
| 203 | /* model */ | ||
| 204 | for (k = 0; k < 16; k++) | ||
| 205 | str[k+9] = ISPRINT(DEV_T10_WWN(dev)->model[k]) ? | ||
| 206 | DEV_T10_WWN(dev)->model[k] : 0x20; | ||
| 207 | str[k + 9] = 0; | ||
| 208 | |||
| 209 | seq_printf(seq, "dev_alias: %s\n", str); | ||
| 210 | |||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | static const struct seq_operations scsi_dev_seq_ops = { | ||
| 215 | .start = scsi_dev_seq_start, | ||
| 216 | .next = scsi_dev_seq_next, | ||
| 217 | .stop = scsi_dev_seq_stop, | ||
| 218 | .show = scsi_dev_seq_show | ||
| 219 | }; | ||
| 220 | |||
| 221 | static int scsi_dev_seq_open(struct inode *inode, struct file *file) | ||
| 222 | { | ||
| 223 | return seq_open(file, &scsi_dev_seq_ops); | ||
| 224 | } | ||
| 225 | |||
| 226 | static const struct file_operations scsi_dev_seq_fops = { | ||
| 227 | .owner = THIS_MODULE, | ||
| 228 | .open = scsi_dev_seq_open, | ||
| 229 | .read = seq_read, | ||
| 230 | .llseek = seq_lseek, | ||
| 231 | .release = seq_release, | ||
| 232 | }; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * SCSI Port Table | ||
| 236 | */ | ||
| 237 | static void *scsi_port_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 238 | { | ||
| 239 | return locate_hba_start(seq, pos); | ||
| 240 | } | ||
| 241 | |||
| 242 | static void *scsi_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 243 | { | ||
| 244 | return locate_hba_next(seq, v, pos); | ||
| 245 | } | ||
| 246 | |||
| 247 | static void scsi_port_seq_stop(struct seq_file *seq, void *v) | ||
| 248 | { | ||
| 249 | locate_hba_stop(seq, v); | ||
| 250 | } | ||
| 251 | |||
| 252 | static int scsi_port_seq_show(struct seq_file *seq, void *v) | ||
| 253 | { | ||
| 254 | struct se_hba *hba; | ||
| 255 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 256 | g_se_dev_list); | ||
| 257 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 258 | struct se_port *sep, *sep_tmp; | ||
| 259 | |||
| 260 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 261 | seq_puts(seq, "inst device indx role busy_count\n"); | ||
| 262 | |||
| 263 | if (!(dev)) | ||
| 264 | return 0; | ||
| 265 | |||
| 266 | hba = dev->se_hba; | ||
| 267 | if (!(hba)) { | ||
| 268 | /* Log error ? */ | ||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* FIXME: scsiPortBusyStatuses count */ | ||
| 273 | spin_lock(&dev->se_port_lock); | ||
| 274 | list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { | ||
| 275 | seq_printf(seq, "%u %u %u %s%u %u\n", hba->hba_index, | ||
| 276 | dev->dev_index, sep->sep_index, "Device", | ||
| 277 | dev->dev_index, 0); | ||
| 278 | } | ||
| 279 | spin_unlock(&dev->se_port_lock); | ||
| 280 | |||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | static const struct seq_operations scsi_port_seq_ops = { | ||
| 285 | .start = scsi_port_seq_start, | ||
| 286 | .next = scsi_port_seq_next, | ||
| 287 | .stop = scsi_port_seq_stop, | ||
| 288 | .show = scsi_port_seq_show | ||
| 289 | }; | ||
| 290 | |||
| 291 | static int scsi_port_seq_open(struct inode *inode, struct file *file) | ||
| 292 | { | ||
| 293 | return seq_open(file, &scsi_port_seq_ops); | ||
| 294 | } | ||
| 295 | |||
| 296 | static const struct file_operations scsi_port_seq_fops = { | ||
| 297 | .owner = THIS_MODULE, | ||
| 298 | .open = scsi_port_seq_open, | ||
| 299 | .read = seq_read, | ||
| 300 | .llseek = seq_lseek, | ||
| 301 | .release = seq_release, | ||
| 302 | }; | ||
| 303 | |||
| 304 | /* | ||
| 305 | * SCSI Transport Table | ||
| 306 | */ | ||
| 307 | static void *scsi_transport_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 308 | { | ||
| 309 | return locate_hba_start(seq, pos); | ||
| 310 | } | ||
| 311 | |||
| 312 | static void *scsi_transport_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 313 | { | ||
| 314 | return locate_hba_next(seq, v, pos); | ||
| 315 | } | ||
| 316 | |||
| 317 | static void scsi_transport_seq_stop(struct seq_file *seq, void *v) | ||
| 318 | { | ||
| 319 | locate_hba_stop(seq, v); | ||
| 320 | } | ||
| 321 | |||
| 322 | static int scsi_transport_seq_show(struct seq_file *seq, void *v) | ||
| 323 | { | ||
| 324 | struct se_hba *hba; | ||
| 325 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 326 | g_se_dev_list); | ||
| 327 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 328 | struct se_port *se, *se_tmp; | ||
| 329 | struct se_portal_group *tpg; | ||
| 330 | struct t10_wwn *wwn; | ||
| 331 | char buf[64]; | ||
| 332 | |||
| 333 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 334 | seq_puts(seq, "inst device indx dev_name\n"); | ||
| 335 | |||
| 336 | if (!(dev)) | ||
| 337 | return 0; | ||
| 338 | |||
| 339 | hba = dev->se_hba; | ||
| 340 | if (!(hba)) { | ||
| 341 | /* Log error ? */ | ||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | wwn = DEV_T10_WWN(dev); | ||
| 346 | |||
| 347 | spin_lock(&dev->se_port_lock); | ||
| 348 | list_for_each_entry_safe(se, se_tmp, &dev->dev_sep_list, sep_list) { | ||
| 349 | tpg = se->sep_tpg; | ||
| 350 | sprintf(buf, "scsiTransport%s", | ||
| 351 | TPG_TFO(tpg)->get_fabric_name()); | ||
| 352 | |||
| 353 | seq_printf(seq, "%u %s %u %s+%s\n", | ||
| 354 | hba->hba_index, /* scsiTransportIndex */ | ||
| 355 | buf, /* scsiTransportType */ | ||
| 356 | (TPG_TFO(tpg)->tpg_get_inst_index != NULL) ? | ||
| 357 | TPG_TFO(tpg)->tpg_get_inst_index(tpg) : | ||
| 358 | 0, | ||
| 359 | TPG_TFO(tpg)->tpg_get_wwn(tpg), | ||
| 360 | (strlen(wwn->unit_serial)) ? | ||
| 361 | /* scsiTransportDevName */ | ||
| 362 | wwn->unit_serial : wwn->vendor); | ||
| 363 | } | ||
| 364 | spin_unlock(&dev->se_port_lock); | ||
| 365 | |||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | |||
| 369 | static const struct seq_operations scsi_transport_seq_ops = { | ||
| 370 | .start = scsi_transport_seq_start, | ||
| 371 | .next = scsi_transport_seq_next, | ||
| 372 | .stop = scsi_transport_seq_stop, | ||
| 373 | .show = scsi_transport_seq_show | ||
| 374 | }; | ||
| 375 | |||
| 376 | static int scsi_transport_seq_open(struct inode *inode, struct file *file) | ||
| 377 | { | ||
| 378 | return seq_open(file, &scsi_transport_seq_ops); | ||
| 379 | } | ||
| 380 | |||
| 381 | static const struct file_operations scsi_transport_seq_fops = { | ||
| 382 | .owner = THIS_MODULE, | ||
| 383 | .open = scsi_transport_seq_open, | ||
| 384 | .read = seq_read, | ||
| 385 | .llseek = seq_lseek, | ||
| 386 | .release = seq_release, | ||
| 387 | }; | ||
| 388 | |||
| 389 | /* | ||
| 390 | * SCSI Target Device Table | ||
| 391 | */ | ||
| 392 | static void *scsi_tgt_dev_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 393 | { | ||
| 394 | return locate_hba_start(seq, pos); | ||
| 395 | } | ||
| 396 | |||
| 397 | static void *scsi_tgt_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 398 | { | ||
| 399 | return locate_hba_next(seq, v, pos); | ||
| 400 | } | ||
| 401 | |||
| 402 | static void scsi_tgt_dev_seq_stop(struct seq_file *seq, void *v) | ||
| 403 | { | ||
| 404 | locate_hba_stop(seq, v); | ||
| 405 | } | ||
| 406 | |||
| 407 | |||
| 408 | #define LU_COUNT 1 /* for now */ | ||
| 409 | static int scsi_tgt_dev_seq_show(struct seq_file *seq, void *v) | ||
| 410 | { | ||
| 411 | struct se_hba *hba; | ||
| 412 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 413 | g_se_dev_list); | ||
| 414 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 415 | int non_accessible_lus = 0; | ||
| 416 | char status[16]; | ||
| 417 | |||
| 418 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 419 | seq_puts(seq, "inst indx num_LUs status non_access_LUs" | ||
| 420 | " resets\n"); | ||
| 421 | |||
| 422 | if (!(dev)) | ||
| 423 | return 0; | ||
| 424 | |||
| 425 | hba = dev->se_hba; | ||
| 426 | if (!(hba)) { | ||
| 427 | /* Log error ? */ | ||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | |||
| 431 | switch (dev->dev_status) { | ||
| 432 | case TRANSPORT_DEVICE_ACTIVATED: | ||
| 433 | strcpy(status, "activated"); | ||
| 434 | break; | ||
| 435 | case TRANSPORT_DEVICE_DEACTIVATED: | ||
| 436 | strcpy(status, "deactivated"); | ||
| 437 | non_accessible_lus = 1; | ||
| 438 | break; | ||
| 439 | case TRANSPORT_DEVICE_SHUTDOWN: | ||
| 440 | strcpy(status, "shutdown"); | ||
| 441 | non_accessible_lus = 1; | ||
| 442 | break; | ||
| 443 | case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: | ||
| 444 | case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: | ||
| 445 | strcpy(status, "offline"); | ||
| 446 | non_accessible_lus = 1; | ||
| 447 | break; | ||
| 448 | default: | ||
| 449 | sprintf(status, "unknown(%d)", dev->dev_status); | ||
| 450 | non_accessible_lus = 1; | ||
| 451 | } | ||
| 452 | |||
| 453 | seq_printf(seq, "%u %u %u %s %u %u\n", | ||
| 454 | hba->hba_index, dev->dev_index, LU_COUNT, | ||
| 455 | status, non_accessible_lus, dev->num_resets); | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static const struct seq_operations scsi_tgt_dev_seq_ops = { | ||
| 461 | .start = scsi_tgt_dev_seq_start, | ||
| 462 | .next = scsi_tgt_dev_seq_next, | ||
| 463 | .stop = scsi_tgt_dev_seq_stop, | ||
| 464 | .show = scsi_tgt_dev_seq_show | ||
| 465 | }; | ||
| 466 | |||
| 467 | static int scsi_tgt_dev_seq_open(struct inode *inode, struct file *file) | ||
| 468 | { | ||
| 469 | return seq_open(file, &scsi_tgt_dev_seq_ops); | ||
| 470 | } | ||
| 471 | |||
| 472 | static const struct file_operations scsi_tgt_dev_seq_fops = { | ||
| 473 | .owner = THIS_MODULE, | ||
| 474 | .open = scsi_tgt_dev_seq_open, | ||
| 475 | .read = seq_read, | ||
| 476 | .llseek = seq_lseek, | ||
| 477 | .release = seq_release, | ||
| 478 | }; | ||
| 479 | |||
| 480 | /* | ||
| 481 | * SCSI Target Port Table | ||
| 482 | */ | ||
| 483 | static void *scsi_tgt_port_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 484 | { | ||
| 485 | return locate_hba_start(seq, pos); | ||
| 486 | } | ||
| 487 | |||
| 488 | static void *scsi_tgt_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 489 | { | ||
| 490 | return locate_hba_next(seq, v, pos); | ||
| 491 | } | ||
| 492 | |||
| 493 | static void scsi_tgt_port_seq_stop(struct seq_file *seq, void *v) | ||
| 494 | { | ||
| 495 | locate_hba_stop(seq, v); | ||
| 496 | } | ||
| 497 | |||
| 498 | static int scsi_tgt_port_seq_show(struct seq_file *seq, void *v) | ||
| 499 | { | ||
| 500 | struct se_hba *hba; | ||
| 501 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 502 | g_se_dev_list); | ||
| 503 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 504 | struct se_port *sep, *sep_tmp; | ||
| 505 | struct se_portal_group *tpg; | ||
| 506 | u32 rx_mbytes, tx_mbytes; | ||
| 507 | unsigned long long num_cmds; | ||
| 508 | char buf[64]; | ||
| 509 | |||
| 510 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 511 | seq_puts(seq, "inst device indx name port_index in_cmds" | ||
| 512 | " write_mbytes read_mbytes hs_in_cmds\n"); | ||
| 513 | |||
| 514 | if (!(dev)) | ||
| 515 | return 0; | ||
| 516 | |||
| 517 | hba = dev->se_hba; | ||
| 518 | if (!(hba)) { | ||
| 519 | /* Log error ? */ | ||
| 520 | return 0; | ||
| 521 | } | ||
| 522 | |||
| 523 | spin_lock(&dev->se_port_lock); | ||
| 524 | list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { | ||
| 525 | tpg = sep->sep_tpg; | ||
| 526 | sprintf(buf, "%sPort#", | ||
| 527 | TPG_TFO(tpg)->get_fabric_name()); | ||
| 528 | |||
| 529 | seq_printf(seq, "%u %u %u %s%d %s%s%d ", | ||
| 530 | hba->hba_index, | ||
| 531 | dev->dev_index, | ||
| 532 | sep->sep_index, | ||
| 533 | buf, sep->sep_index, | ||
| 534 | TPG_TFO(tpg)->tpg_get_wwn(tpg), "+t+", | ||
| 535 | TPG_TFO(tpg)->tpg_get_tag(tpg)); | ||
| 536 | |||
| 537 | spin_lock(&sep->sep_lun->lun_sep_lock); | ||
| 538 | num_cmds = sep->sep_stats.cmd_pdus; | ||
| 539 | rx_mbytes = (sep->sep_stats.rx_data_octets >> 20); | ||
| 540 | tx_mbytes = (sep->sep_stats.tx_data_octets >> 20); | ||
| 541 | spin_unlock(&sep->sep_lun->lun_sep_lock); | ||
| 542 | |||
| 543 | seq_printf(seq, "%llu %u %u %u\n", num_cmds, | ||
| 544 | rx_mbytes, tx_mbytes, 0); | ||
| 545 | } | ||
| 546 | spin_unlock(&dev->se_port_lock); | ||
| 547 | |||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | static const struct seq_operations scsi_tgt_port_seq_ops = { | ||
| 552 | .start = scsi_tgt_port_seq_start, | ||
| 553 | .next = scsi_tgt_port_seq_next, | ||
| 554 | .stop = scsi_tgt_port_seq_stop, | ||
| 555 | .show = scsi_tgt_port_seq_show | ||
| 556 | }; | ||
| 557 | |||
| 558 | static int scsi_tgt_port_seq_open(struct inode *inode, struct file *file) | ||
| 559 | { | ||
| 560 | return seq_open(file, &scsi_tgt_port_seq_ops); | ||
| 561 | } | ||
| 562 | |||
| 563 | static const struct file_operations scsi_tgt_port_seq_fops = { | ||
| 564 | .owner = THIS_MODULE, | ||
| 565 | .open = scsi_tgt_port_seq_open, | ||
| 566 | .read = seq_read, | ||
| 567 | .llseek = seq_lseek, | ||
| 568 | .release = seq_release, | ||
| 569 | }; | ||
| 570 | |||
| 571 | /* | ||
| 572 | * SCSI Authorized Initiator Table: | ||
| 573 | * It contains the SCSI Initiators authorized to be attached to one of the | ||
| 574 | * local Target ports. | ||
| 575 | * Iterates through all active TPGs and extracts the info from the ACLs | ||
| 576 | */ | ||
| 577 | static void *scsi_auth_intr_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 578 | { | ||
| 579 | spin_lock_bh(&se_global->se_tpg_lock); | ||
| 580 | return seq_list_start(&se_global->g_se_tpg_list, *pos); | ||
| 581 | } | ||
| 582 | |||
| 583 | static void *scsi_auth_intr_seq_next(struct seq_file *seq, void *v, | ||
| 584 | loff_t *pos) | ||
| 585 | { | ||
| 586 | return seq_list_next(v, &se_global->g_se_tpg_list, pos); | ||
| 587 | } | ||
| 588 | |||
| 589 | static void scsi_auth_intr_seq_stop(struct seq_file *seq, void *v) | ||
| 590 | { | ||
| 591 | spin_unlock_bh(&se_global->se_tpg_lock); | ||
| 592 | } | ||
| 593 | |||
| 594 | static int scsi_auth_intr_seq_show(struct seq_file *seq, void *v) | ||
| 595 | { | ||
| 596 | struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, | ||
| 597 | se_tpg_list); | ||
| 598 | struct se_dev_entry *deve; | ||
| 599 | struct se_lun *lun; | ||
| 600 | struct se_node_acl *se_nacl; | ||
| 601 | int j; | ||
| 602 | |||
| 603 | if (list_is_first(&se_tpg->se_tpg_list, | ||
| 604 | &se_global->g_se_tpg_list)) | ||
| 605 | seq_puts(seq, "inst dev port indx dev_or_port intr_name " | ||
| 606 | "map_indx att_count num_cmds read_mbytes " | ||
| 607 | "write_mbytes hs_num_cmds creation_time row_status\n"); | ||
| 608 | |||
| 609 | if (!(se_tpg)) | ||
| 610 | return 0; | ||
| 611 | |||
| 612 | spin_lock(&se_tpg->acl_node_lock); | ||
| 613 | list_for_each_entry(se_nacl, &se_tpg->acl_node_list, acl_list) { | ||
| 614 | |||
| 615 | atomic_inc(&se_nacl->mib_ref_count); | ||
| 616 | smp_mb__after_atomic_inc(); | ||
| 617 | spin_unlock(&se_tpg->acl_node_lock); | ||
| 618 | |||
| 619 | spin_lock_irq(&se_nacl->device_list_lock); | ||
| 620 | for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { | ||
| 621 | deve = &se_nacl->device_list[j]; | ||
| 622 | if (!(deve->lun_flags & | ||
| 623 | TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || | ||
| 624 | (!deve->se_lun)) | ||
| 625 | continue; | ||
| 626 | lun = deve->se_lun; | ||
| 627 | if (!lun->lun_se_dev) | ||
| 628 | continue; | ||
| 629 | |||
| 630 | seq_printf(seq, "%u %u %u %u %u %s %u %u %u %u %u %u" | ||
| 631 | " %u %s\n", | ||
| 632 | /* scsiInstIndex */ | ||
| 633 | (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? | ||
| 634 | TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : | ||
| 635 | 0, | ||
| 636 | /* scsiDeviceIndex */ | ||
| 637 | lun->lun_se_dev->dev_index, | ||
| 638 | /* scsiAuthIntrTgtPortIndex */ | ||
| 639 | TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), | ||
| 640 | /* scsiAuthIntrIndex */ | ||
| 641 | se_nacl->acl_index, | ||
| 642 | /* scsiAuthIntrDevOrPort */ | ||
| 643 | 1, | ||
| 644 | /* scsiAuthIntrName */ | ||
| 645 | se_nacl->initiatorname[0] ? | ||
| 646 | se_nacl->initiatorname : NONE, | ||
| 647 | /* FIXME: scsiAuthIntrLunMapIndex */ | ||
| 648 | 0, | ||
| 649 | /* scsiAuthIntrAttachedTimes */ | ||
| 650 | deve->attach_count, | ||
| 651 | /* scsiAuthIntrOutCommands */ | ||
| 652 | deve->total_cmds, | ||
| 653 | /* scsiAuthIntrReadMegaBytes */ | ||
| 654 | (u32)(deve->read_bytes >> 20), | ||
| 655 | /* scsiAuthIntrWrittenMegaBytes */ | ||
| 656 | (u32)(deve->write_bytes >> 20), | ||
| 657 | /* FIXME: scsiAuthIntrHSOutCommands */ | ||
| 658 | 0, | ||
| 659 | /* scsiAuthIntrLastCreation */ | ||
| 660 | (u32)(((u32)deve->creation_time - | ||
| 661 | INITIAL_JIFFIES) * 100 / HZ), | ||
| 662 | /* FIXME: scsiAuthIntrRowStatus */ | ||
| 663 | "Ready"); | ||
| 664 | } | ||
| 665 | spin_unlock_irq(&se_nacl->device_list_lock); | ||
| 666 | |||
| 667 | spin_lock(&se_tpg->acl_node_lock); | ||
| 668 | atomic_dec(&se_nacl->mib_ref_count); | ||
| 669 | smp_mb__after_atomic_dec(); | ||
| 670 | } | ||
| 671 | spin_unlock(&se_tpg->acl_node_lock); | ||
| 672 | |||
| 673 | return 0; | ||
| 674 | } | ||
| 675 | |||
| 676 | static const struct seq_operations scsi_auth_intr_seq_ops = { | ||
| 677 | .start = scsi_auth_intr_seq_start, | ||
| 678 | .next = scsi_auth_intr_seq_next, | ||
| 679 | .stop = scsi_auth_intr_seq_stop, | ||
| 680 | .show = scsi_auth_intr_seq_show | ||
| 681 | }; | ||
| 682 | |||
| 683 | static int scsi_auth_intr_seq_open(struct inode *inode, struct file *file) | ||
| 684 | { | ||
| 685 | return seq_open(file, &scsi_auth_intr_seq_ops); | ||
| 686 | } | ||
| 687 | |||
| 688 | static const struct file_operations scsi_auth_intr_seq_fops = { | ||
| 689 | .owner = THIS_MODULE, | ||
| 690 | .open = scsi_auth_intr_seq_open, | ||
| 691 | .read = seq_read, | ||
| 692 | .llseek = seq_lseek, | ||
| 693 | .release = seq_release, | ||
| 694 | }; | ||
| 695 | |||
| 696 | /* | ||
| 697 | * SCSI Attached Initiator Port Table: | ||
| 698 | * It lists the SCSI Initiators attached to one of the local Target ports. | ||
| 699 | * Iterates through all active TPGs and use active sessions from each TPG | ||
| 700 | * to list the info fo this table. | ||
| 701 | */ | ||
| 702 | static void *scsi_att_intr_port_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 703 | { | ||
| 704 | spin_lock_bh(&se_global->se_tpg_lock); | ||
| 705 | return seq_list_start(&se_global->g_se_tpg_list, *pos); | ||
| 706 | } | ||
| 707 | |||
| 708 | static void *scsi_att_intr_port_seq_next(struct seq_file *seq, void *v, | ||
| 709 | loff_t *pos) | ||
| 710 | { | ||
| 711 | return seq_list_next(v, &se_global->g_se_tpg_list, pos); | ||
| 712 | } | ||
| 713 | |||
| 714 | static void scsi_att_intr_port_seq_stop(struct seq_file *seq, void *v) | ||
| 715 | { | ||
| 716 | spin_unlock_bh(&se_global->se_tpg_lock); | ||
| 717 | } | ||
| 718 | |||
| 719 | static int scsi_att_intr_port_seq_show(struct seq_file *seq, void *v) | ||
| 720 | { | ||
| 721 | struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, | ||
| 722 | se_tpg_list); | ||
| 723 | struct se_dev_entry *deve; | ||
| 724 | struct se_lun *lun; | ||
| 725 | struct se_node_acl *se_nacl; | ||
| 726 | struct se_session *se_sess; | ||
| 727 | unsigned char buf[64]; | ||
| 728 | int j; | ||
| 729 | |||
| 730 | if (list_is_first(&se_tpg->se_tpg_list, | ||
| 731 | &se_global->g_se_tpg_list)) | ||
| 732 | seq_puts(seq, "inst dev port indx port_auth_indx port_name" | ||
| 733 | " port_ident\n"); | ||
| 734 | |||
| 735 | if (!(se_tpg)) | ||
| 736 | return 0; | ||
| 737 | |||
| 738 | spin_lock(&se_tpg->session_lock); | ||
| 739 | list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) { | ||
| 740 | if ((TPG_TFO(se_tpg)->sess_logged_in(se_sess)) || | ||
| 741 | (!se_sess->se_node_acl) || | ||
| 742 | (!se_sess->se_node_acl->device_list)) | ||
| 743 | continue; | ||
| 744 | |||
| 745 | atomic_inc(&se_sess->mib_ref_count); | ||
| 746 | smp_mb__after_atomic_inc(); | ||
| 747 | se_nacl = se_sess->se_node_acl; | ||
| 748 | atomic_inc(&se_nacl->mib_ref_count); | ||
| 749 | smp_mb__after_atomic_inc(); | ||
| 750 | spin_unlock(&se_tpg->session_lock); | ||
| 751 | |||
| 752 | spin_lock_irq(&se_nacl->device_list_lock); | ||
| 753 | for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { | ||
| 754 | deve = &se_nacl->device_list[j]; | ||
| 755 | if (!(deve->lun_flags & | ||
| 756 | TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || | ||
| 757 | (!deve->se_lun)) | ||
| 758 | continue; | ||
| 759 | |||
| 760 | lun = deve->se_lun; | ||
| 761 | if (!lun->lun_se_dev) | ||
| 762 | continue; | ||
| 763 | |||
| 764 | memset(buf, 0, 64); | ||
| 765 | if (TPG_TFO(se_tpg)->sess_get_initiator_sid != NULL) | ||
| 766 | TPG_TFO(se_tpg)->sess_get_initiator_sid( | ||
| 767 | se_sess, (unsigned char *)&buf[0], 64); | ||
| 768 | |||
| 769 | seq_printf(seq, "%u %u %u %u %u %s+i+%s\n", | ||
| 770 | /* scsiInstIndex */ | ||
| 771 | (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? | ||
| 772 | TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : | ||
| 773 | 0, | ||
| 774 | /* scsiDeviceIndex */ | ||
| 775 | lun->lun_se_dev->dev_index, | ||
| 776 | /* scsiPortIndex */ | ||
| 777 | TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), | ||
| 778 | /* scsiAttIntrPortIndex */ | ||
| 779 | (TPG_TFO(se_tpg)->sess_get_index != NULL) ? | ||
| 780 | TPG_TFO(se_tpg)->sess_get_index(se_sess) : | ||
| 781 | 0, | ||
| 782 | /* scsiAttIntrPortAuthIntrIdx */ | ||
| 783 | se_nacl->acl_index, | ||
| 784 | /* scsiAttIntrPortName */ | ||
| 785 | se_nacl->initiatorname[0] ? | ||
| 786 | se_nacl->initiatorname : NONE, | ||
| 787 | /* scsiAttIntrPortIdentifier */ | ||
| 788 | buf); | ||
| 789 | } | ||
| 790 | spin_unlock_irq(&se_nacl->device_list_lock); | ||
| 791 | |||
| 792 | spin_lock(&se_tpg->session_lock); | ||
| 793 | atomic_dec(&se_nacl->mib_ref_count); | ||
| 794 | smp_mb__after_atomic_dec(); | ||
| 795 | atomic_dec(&se_sess->mib_ref_count); | ||
| 796 | smp_mb__after_atomic_dec(); | ||
| 797 | } | ||
| 798 | spin_unlock(&se_tpg->session_lock); | ||
| 799 | |||
| 800 | return 0; | ||
| 801 | } | ||
| 802 | |||
| 803 | static const struct seq_operations scsi_att_intr_port_seq_ops = { | ||
| 804 | .start = scsi_att_intr_port_seq_start, | ||
| 805 | .next = scsi_att_intr_port_seq_next, | ||
| 806 | .stop = scsi_att_intr_port_seq_stop, | ||
| 807 | .show = scsi_att_intr_port_seq_show | ||
| 808 | }; | ||
| 809 | |||
| 810 | static int scsi_att_intr_port_seq_open(struct inode *inode, struct file *file) | ||
| 811 | { | ||
| 812 | return seq_open(file, &scsi_att_intr_port_seq_ops); | ||
| 813 | } | ||
| 814 | |||
| 815 | static const struct file_operations scsi_att_intr_port_seq_fops = { | ||
| 816 | .owner = THIS_MODULE, | ||
| 817 | .open = scsi_att_intr_port_seq_open, | ||
| 818 | .read = seq_read, | ||
| 819 | .llseek = seq_lseek, | ||
| 820 | .release = seq_release, | ||
| 821 | }; | ||
| 822 | |||
| 823 | /* | ||
| 824 | * SCSI Logical Unit Table | ||
| 825 | */ | ||
| 826 | static void *scsi_lu_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 827 | { | ||
| 828 | return locate_hba_start(seq, pos); | ||
| 829 | } | ||
| 830 | |||
| 831 | static void *scsi_lu_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 832 | { | ||
| 833 | return locate_hba_next(seq, v, pos); | ||
| 834 | } | ||
| 835 | |||
| 836 | static void scsi_lu_seq_stop(struct seq_file *seq, void *v) | ||
| 837 | { | ||
| 838 | locate_hba_stop(seq, v); | ||
| 839 | } | ||
| 840 | |||
| 841 | #define SCSI_LU_INDEX 1 | ||
| 842 | static int scsi_lu_seq_show(struct seq_file *seq, void *v) | ||
| 843 | { | ||
| 844 | struct se_hba *hba; | ||
| 845 | struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, | ||
| 846 | g_se_dev_list); | ||
| 847 | struct se_device *dev = se_dev->se_dev_ptr; | ||
| 848 | int j; | ||
| 849 | char str[28]; | ||
| 850 | |||
| 851 | if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) | ||
| 852 | seq_puts(seq, "inst dev indx LUN lu_name vend prod rev" | ||
| 853 | " dev_type status state-bit num_cmds read_mbytes" | ||
| 854 | " write_mbytes resets full_stat hs_num_cmds creation_time\n"); | ||
| 855 | |||
| 856 | if (!(dev)) | ||
| 857 | return 0; | ||
| 858 | |||
| 859 | hba = dev->se_hba; | ||
| 860 | if (!(hba)) { | ||
| 861 | /* Log error ? */ | ||
| 862 | return 0; | ||
| 863 | } | ||
| 864 | |||
| 865 | /* Fix LU state, if we can read it from the device */ | ||
| 866 | seq_printf(seq, "%u %u %u %llu %s", hba->hba_index, | ||
| 867 | dev->dev_index, SCSI_LU_INDEX, | ||
| 868 | (unsigned long long)0, /* FIXME: scsiLuDefaultLun */ | ||
| 869 | (strlen(DEV_T10_WWN(dev)->unit_serial)) ? | ||
| 870 | /* scsiLuWwnName */ | ||
| 871 | (char *)&DEV_T10_WWN(dev)->unit_serial[0] : | ||
| 872 | "None"); | ||
| 873 | |||
| 874 | memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); | ||
| 875 | /* scsiLuVendorId */ | ||
| 876 | for (j = 0; j < 8; j++) | ||
| 877 | str[j] = ISPRINT(DEV_T10_WWN(dev)->vendor[j]) ? | ||
| 878 | DEV_T10_WWN(dev)->vendor[j] : 0x20; | ||
| 879 | str[8] = 0; | ||
| 880 | seq_printf(seq, " %s", str); | ||
| 881 | |||
| 882 | /* scsiLuProductId */ | ||
| 883 | for (j = 0; j < 16; j++) | ||
| 884 | str[j] = ISPRINT(DEV_T10_WWN(dev)->model[j]) ? | ||
| 885 | DEV_T10_WWN(dev)->model[j] : 0x20; | ||
| 886 | str[16] = 0; | ||
| 887 | seq_printf(seq, " %s", str); | ||
| 888 | |||
| 889 | /* scsiLuRevisionId */ | ||
| 890 | for (j = 0; j < 4; j++) | ||
| 891 | str[j] = ISPRINT(DEV_T10_WWN(dev)->revision[j]) ? | ||
| 892 | DEV_T10_WWN(dev)->revision[j] : 0x20; | ||
| 893 | str[4] = 0; | ||
| 894 | seq_printf(seq, " %s", str); | ||
| 895 | |||
| 896 | seq_printf(seq, " %u %s %s %llu %u %u %u %u %u %u\n", | ||
| 897 | /* scsiLuPeripheralType */ | ||
| 898 | TRANSPORT(dev)->get_device_type(dev), | ||
| 899 | (dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ? | ||
| 900 | "available" : "notavailable", /* scsiLuStatus */ | ||
| 901 | "exposed", /* scsiLuState */ | ||
| 902 | (unsigned long long)dev->num_cmds, | ||
| 903 | /* scsiLuReadMegaBytes */ | ||
| 904 | (u32)(dev->read_bytes >> 20), | ||
| 905 | /* scsiLuWrittenMegaBytes */ | ||
| 906 | (u32)(dev->write_bytes >> 20), | ||
| 907 | dev->num_resets, /* scsiLuInResets */ | ||
| 908 | 0, /* scsiLuOutTaskSetFullStatus */ | ||
| 909 | 0, /* scsiLuHSInCommands */ | ||
| 910 | (u32)(((u32)dev->creation_time - INITIAL_JIFFIES) * | ||
| 911 | 100 / HZ)); | ||
| 912 | |||
| 913 | return 0; | ||
| 914 | } | ||
| 915 | |||
| 916 | static const struct seq_operations scsi_lu_seq_ops = { | ||
| 917 | .start = scsi_lu_seq_start, | ||
| 918 | .next = scsi_lu_seq_next, | ||
| 919 | .stop = scsi_lu_seq_stop, | ||
| 920 | .show = scsi_lu_seq_show | ||
| 921 | }; | ||
| 922 | |||
| 923 | static int scsi_lu_seq_open(struct inode *inode, struct file *file) | ||
| 924 | { | ||
| 925 | return seq_open(file, &scsi_lu_seq_ops); | ||
| 926 | } | ||
| 927 | |||
| 928 | static const struct file_operations scsi_lu_seq_fops = { | ||
| 929 | .owner = THIS_MODULE, | ||
| 930 | .open = scsi_lu_seq_open, | ||
| 931 | .read = seq_read, | ||
| 932 | .llseek = seq_lseek, | ||
| 933 | .release = seq_release, | ||
| 934 | }; | ||
| 935 | |||
| 936 | /****************************************************************************/ | ||
| 937 | |||
| 938 | /* | ||
| 939 | * Remove proc fs entries | ||
| 940 | */ | ||
| 941 | void remove_scsi_target_mib(void) | ||
| 942 | { | ||
| 943 | remove_proc_entry("scsi_target/mib/scsi_inst", NULL); | ||
| 944 | remove_proc_entry("scsi_target/mib/scsi_dev", NULL); | ||
| 945 | remove_proc_entry("scsi_target/mib/scsi_port", NULL); | ||
| 946 | remove_proc_entry("scsi_target/mib/scsi_transport", NULL); | ||
| 947 | remove_proc_entry("scsi_target/mib/scsi_tgt_dev", NULL); | ||
| 948 | remove_proc_entry("scsi_target/mib/scsi_tgt_port", NULL); | ||
| 949 | remove_proc_entry("scsi_target/mib/scsi_auth_intr", NULL); | ||
| 950 | remove_proc_entry("scsi_target/mib/scsi_att_intr_port", NULL); | ||
| 951 | remove_proc_entry("scsi_target/mib/scsi_lu", NULL); | ||
| 952 | remove_proc_entry("scsi_target/mib", NULL); | ||
| 953 | } | ||
| 954 | |||
| 955 | /* | ||
| 956 | * Create proc fs entries for the mib tables | ||
| 957 | */ | ||
| 958 | int init_scsi_target_mib(void) | ||
| 959 | { | ||
| 960 | struct proc_dir_entry *dir_entry; | ||
| 961 | struct proc_dir_entry *scsi_inst_entry; | ||
| 962 | struct proc_dir_entry *scsi_dev_entry; | ||
| 963 | struct proc_dir_entry *scsi_port_entry; | ||
| 964 | struct proc_dir_entry *scsi_transport_entry; | ||
| 965 | struct proc_dir_entry *scsi_tgt_dev_entry; | ||
| 966 | struct proc_dir_entry *scsi_tgt_port_entry; | ||
| 967 | struct proc_dir_entry *scsi_auth_intr_entry; | ||
| 968 | struct proc_dir_entry *scsi_att_intr_port_entry; | ||
| 969 | struct proc_dir_entry *scsi_lu_entry; | ||
| 970 | |||
| 971 | dir_entry = proc_mkdir("scsi_target/mib", NULL); | ||
| 972 | if (!(dir_entry)) { | ||
| 973 | printk(KERN_ERR "proc_mkdir() failed.\n"); | ||
| 974 | return -1; | ||
| 975 | } | ||
| 976 | |||
| 977 | scsi_inst_entry = | ||
| 978 | create_proc_entry("scsi_target/mib/scsi_inst", 0, NULL); | ||
| 979 | if (scsi_inst_entry) | ||
| 980 | scsi_inst_entry->proc_fops = &scsi_inst_seq_fops; | ||
| 981 | else | ||
| 982 | goto error; | ||
| 983 | |||
| 984 | scsi_dev_entry = | ||
| 985 | create_proc_entry("scsi_target/mib/scsi_dev", 0, NULL); | ||
| 986 | if (scsi_dev_entry) | ||
| 987 | scsi_dev_entry->proc_fops = &scsi_dev_seq_fops; | ||
| 988 | else | ||
| 989 | goto error; | ||
| 990 | |||
| 991 | scsi_port_entry = | ||
| 992 | create_proc_entry("scsi_target/mib/scsi_port", 0, NULL); | ||
| 993 | if (scsi_port_entry) | ||
| 994 | scsi_port_entry->proc_fops = &scsi_port_seq_fops; | ||
| 995 | else | ||
| 996 | goto error; | ||
| 997 | |||
| 998 | scsi_transport_entry = | ||
| 999 | create_proc_entry("scsi_target/mib/scsi_transport", 0, NULL); | ||
| 1000 | if (scsi_transport_entry) | ||
| 1001 | scsi_transport_entry->proc_fops = &scsi_transport_seq_fops; | ||
| 1002 | else | ||
| 1003 | goto error; | ||
| 1004 | |||
| 1005 | scsi_tgt_dev_entry = | ||
| 1006 | create_proc_entry("scsi_target/mib/scsi_tgt_dev", 0, NULL); | ||
| 1007 | if (scsi_tgt_dev_entry) | ||
| 1008 | scsi_tgt_dev_entry->proc_fops = &scsi_tgt_dev_seq_fops; | ||
| 1009 | else | ||
| 1010 | goto error; | ||
| 1011 | |||
| 1012 | scsi_tgt_port_entry = | ||
| 1013 | create_proc_entry("scsi_target/mib/scsi_tgt_port", 0, NULL); | ||
| 1014 | if (scsi_tgt_port_entry) | ||
| 1015 | scsi_tgt_port_entry->proc_fops = &scsi_tgt_port_seq_fops; | ||
| 1016 | else | ||
| 1017 | goto error; | ||
| 1018 | |||
| 1019 | scsi_auth_intr_entry = | ||
| 1020 | create_proc_entry("scsi_target/mib/scsi_auth_intr", 0, NULL); | ||
| 1021 | if (scsi_auth_intr_entry) | ||
| 1022 | scsi_auth_intr_entry->proc_fops = &scsi_auth_intr_seq_fops; | ||
| 1023 | else | ||
| 1024 | goto error; | ||
| 1025 | |||
| 1026 | scsi_att_intr_port_entry = | ||
| 1027 | create_proc_entry("scsi_target/mib/scsi_att_intr_port", 0, NULL); | ||
| 1028 | if (scsi_att_intr_port_entry) | ||
| 1029 | scsi_att_intr_port_entry->proc_fops = | ||
| 1030 | &scsi_att_intr_port_seq_fops; | ||
| 1031 | else | ||
| 1032 | goto error; | ||
| 1033 | |||
| 1034 | scsi_lu_entry = create_proc_entry("scsi_target/mib/scsi_lu", 0, NULL); | ||
| 1035 | if (scsi_lu_entry) | ||
| 1036 | scsi_lu_entry->proc_fops = &scsi_lu_seq_fops; | ||
| 1037 | else | ||
| 1038 | goto error; | ||
| 1039 | |||
| 1040 | return 0; | ||
| 1041 | |||
| 1042 | error: | ||
| 1043 | printk(KERN_ERR "create_proc_entry() failed.\n"); | ||
| 1044 | remove_scsi_target_mib(); | ||
| 1045 | return -1; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | /* | ||
| 1049 | * Initialize the index table for allocating unique row indexes to various mib | ||
| 1050 | * tables | ||
| 1051 | */ | ||
| 1052 | void init_scsi_index_table(void) | ||
| 1053 | { | ||
| 1054 | memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); | ||
| 1055 | spin_lock_init(&scsi_index_table.lock); | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | /* | ||
| 1059 | * Allocate a new row index for the entry type specified | ||
| 1060 | */ | ||
| 1061 | u32 scsi_get_new_index(scsi_index_t type) | ||
| 1062 | { | ||
| 1063 | u32 new_index; | ||
| 1064 | |||
| 1065 | if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { | ||
| 1066 | printk(KERN_ERR "Invalid index type %d\n", type); | ||
| 1067 | return -1; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | spin_lock(&scsi_index_table.lock); | ||
| 1071 | new_index = ++scsi_index_table.scsi_mib_index[type]; | ||
| 1072 | if (new_index == 0) | ||
| 1073 | new_index = ++scsi_index_table.scsi_mib_index[type]; | ||
| 1074 | spin_unlock(&scsi_index_table.lock); | ||
| 1075 | |||
| 1076 | return new_index; | ||
| 1077 | } | ||
| 1078 | EXPORT_SYMBOL(scsi_get_new_index); | ||
diff --git a/drivers/target/target_core_mib.h b/drivers/target/target_core_mib.h deleted file mode 100644 index 27720463385..00000000000 --- a/drivers/target/target_core_mib.h +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | #ifndef TARGET_CORE_MIB_H | ||
| 2 | #define TARGET_CORE_MIB_H | ||
| 3 | |||
| 4 | typedef enum { | ||
| 5 | SCSI_INST_INDEX, | ||
| 6 | SCSI_DEVICE_INDEX, | ||
| 7 | SCSI_AUTH_INTR_INDEX, | ||
| 8 | SCSI_INDEX_TYPE_MAX | ||
| 9 | } scsi_index_t; | ||
| 10 | |||
| 11 | struct scsi_index_table { | ||
| 12 | spinlock_t lock; | ||
| 13 | u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; | ||
| 14 | } ____cacheline_aligned; | ||
| 15 | |||
| 16 | /* SCSI Port stats */ | ||
| 17 | struct scsi_port_stats { | ||
| 18 | u64 cmd_pdus; | ||
| 19 | u64 tx_data_octets; | ||
| 20 | u64 rx_data_octets; | ||
| 21 | } ____cacheline_aligned; | ||
| 22 | |||
| 23 | extern int init_scsi_target_mib(void); | ||
| 24 | extern void remove_scsi_target_mib(void); | ||
| 25 | extern void init_scsi_index_table(void); | ||
| 26 | extern u32 scsi_get_new_index(scsi_index_t); | ||
| 27 | |||
| 28 | #endif /*** TARGET_CORE_MIB_H ***/ | ||
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 742d24609a9..f2a08477a68 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
| @@ -462,8 +462,8 @@ static struct se_device *pscsi_create_type_disk( | |||
| 462 | */ | 462 | */ |
| 463 | bd = blkdev_get_by_path(se_dev->se_dev_udev_path, | 463 | bd = blkdev_get_by_path(se_dev->se_dev_udev_path, |
| 464 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); | 464 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); |
| 465 | if (!(bd)) { | 465 | if (IS_ERR(bd)) { |
| 466 | printk("pSCSI: blkdev_get_by_path() failed\n"); | 466 | printk(KERN_ERR "pSCSI: blkdev_get_by_path() failed\n"); |
| 467 | scsi_device_put(sd); | 467 | scsi_device_put(sd); |
| 468 | return NULL; | 468 | return NULL; |
| 469 | } | 469 | } |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index abfa81a5711..c26f6746762 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
| @@ -275,7 +275,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( | |||
| 275 | spin_lock_init(&acl->device_list_lock); | 275 | spin_lock_init(&acl->device_list_lock); |
| 276 | spin_lock_init(&acl->nacl_sess_lock); | 276 | spin_lock_init(&acl->nacl_sess_lock); |
| 277 | atomic_set(&acl->acl_pr_ref_count, 0); | 277 | atomic_set(&acl->acl_pr_ref_count, 0); |
| 278 | atomic_set(&acl->mib_ref_count, 0); | ||
| 279 | acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg); | 278 | acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg); |
| 280 | snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); | 279 | snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); |
| 281 | acl->se_tpg = tpg; | 280 | acl->se_tpg = tpg; |
| @@ -318,12 +317,6 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *nacl) | |||
| 318 | cpu_relax(); | 317 | cpu_relax(); |
| 319 | } | 318 | } |
| 320 | 319 | ||
| 321 | void core_tpg_wait_for_mib_ref(struct se_node_acl *nacl) | ||
| 322 | { | ||
| 323 | while (atomic_read(&nacl->mib_ref_count) != 0) | ||
| 324 | cpu_relax(); | ||
| 325 | } | ||
| 326 | |||
| 327 | void core_tpg_clear_object_luns(struct se_portal_group *tpg) | 320 | void core_tpg_clear_object_luns(struct se_portal_group *tpg) |
| 328 | { | 321 | { |
| 329 | int i, ret; | 322 | int i, ret; |
| @@ -480,7 +473,6 @@ int core_tpg_del_initiator_node_acl( | |||
| 480 | spin_unlock_bh(&tpg->session_lock); | 473 | spin_unlock_bh(&tpg->session_lock); |
| 481 | 474 | ||
| 482 | core_tpg_wait_for_nacl_pr_ref(acl); | 475 | core_tpg_wait_for_nacl_pr_ref(acl); |
| 483 | core_tpg_wait_for_mib_ref(acl); | ||
| 484 | core_clear_initiator_node_from_tpg(acl, tpg); | 476 | core_clear_initiator_node_from_tpg(acl, tpg); |
| 485 | core_free_device_list_for_node(acl, tpg); | 477 | core_free_device_list_for_node(acl, tpg); |
| 486 | 478 | ||
| @@ -701,6 +693,8 @@ EXPORT_SYMBOL(core_tpg_register); | |||
| 701 | 693 | ||
| 702 | int core_tpg_deregister(struct se_portal_group *se_tpg) | 694 | int core_tpg_deregister(struct se_portal_group *se_tpg) |
| 703 | { | 695 | { |
| 696 | struct se_node_acl *nacl, *nacl_tmp; | ||
| 697 | |||
| 704 | printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group" | 698 | printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group" |
| 705 | " for endpoint: %s Portal Tag %u\n", | 699 | " for endpoint: %s Portal Tag %u\n", |
| 706 | (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ? | 700 | (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ? |
| @@ -714,6 +708,25 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) | |||
| 714 | 708 | ||
| 715 | while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0) | 709 | while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0) |
| 716 | cpu_relax(); | 710 | cpu_relax(); |
| 711 | /* | ||
| 712 | * Release any remaining demo-mode generated se_node_acl that have | ||
| 713 | * not been released because of TFO->tpg_check_demo_mode_cache() == 1 | ||
| 714 | * in transport_deregister_session(). | ||
| 715 | */ | ||
| 716 | spin_lock_bh(&se_tpg->acl_node_lock); | ||
| 717 | list_for_each_entry_safe(nacl, nacl_tmp, &se_tpg->acl_node_list, | ||
| 718 | acl_list) { | ||
| 719 | list_del(&nacl->acl_list); | ||
| 720 | se_tpg->num_node_acls--; | ||
| 721 | spin_unlock_bh(&se_tpg->acl_node_lock); | ||
| 722 | |||
| 723 | core_tpg_wait_for_nacl_pr_ref(nacl); | ||
| 724 | core_free_device_list_for_node(nacl, se_tpg); | ||
| 725 | TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, nacl); | ||
| 726 | |||
| 727 | spin_lock_bh(&se_tpg->acl_node_lock); | ||
| 728 | } | ||
| 729 | spin_unlock_bh(&se_tpg->acl_node_lock); | ||
| 717 | 730 | ||
| 718 | if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) | 731 | if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) |
| 719 | core_tpg_release_virtual_lun0(se_tpg); | 732 | core_tpg_release_virtual_lun0(se_tpg); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 28b6292ff29..236e22d8cfa 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -379,6 +379,40 @@ void release_se_global(void) | |||
| 379 | se_global = NULL; | 379 | se_global = NULL; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | /* SCSI statistics table index */ | ||
| 383 | static struct scsi_index_table scsi_index_table; | ||
| 384 | |||
| 385 | /* | ||
| 386 | * Initialize the index table for allocating unique row indexes to various mib | ||
| 387 | * tables. | ||
| 388 | */ | ||
| 389 | void init_scsi_index_table(void) | ||
| 390 | { | ||
| 391 | memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); | ||
| 392 | spin_lock_init(&scsi_index_table.lock); | ||
| 393 | } | ||
| 394 | |||
| 395 | /* | ||
| 396 | * Allocate a new row index for the entry type specified | ||
| 397 | */ | ||
| 398 | u32 scsi_get_new_index(scsi_index_t type) | ||
| 399 | { | ||
| 400 | u32 new_index; | ||
| 401 | |||
| 402 | if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { | ||
| 403 | printk(KERN_ERR "Invalid index type %d\n", type); | ||
| 404 | return -EINVAL; | ||
| 405 | } | ||
| 406 | |||
| 407 | spin_lock(&scsi_index_table.lock); | ||
| 408 | new_index = ++scsi_index_table.scsi_mib_index[type]; | ||
| 409 | if (new_index == 0) | ||
| 410 | new_index = ++scsi_index_table.scsi_mib_index[type]; | ||
| 411 | spin_unlock(&scsi_index_table.lock); | ||
| 412 | |||
| 413 | return new_index; | ||
| 414 | } | ||
| 415 | |||
| 382 | void transport_init_queue_obj(struct se_queue_obj *qobj) | 416 | void transport_init_queue_obj(struct se_queue_obj *qobj) |
| 383 | { | 417 | { |
| 384 | atomic_set(&qobj->queue_cnt, 0); | 418 | atomic_set(&qobj->queue_cnt, 0); |
| @@ -437,7 +471,6 @@ struct se_session *transport_init_session(void) | |||
| 437 | } | 471 | } |
| 438 | INIT_LIST_HEAD(&se_sess->sess_list); | 472 | INIT_LIST_HEAD(&se_sess->sess_list); |
| 439 | INIT_LIST_HEAD(&se_sess->sess_acl_list); | 473 | INIT_LIST_HEAD(&se_sess->sess_acl_list); |
| 440 | atomic_set(&se_sess->mib_ref_count, 0); | ||
| 441 | 474 | ||
| 442 | return se_sess; | 475 | return se_sess; |
| 443 | } | 476 | } |
| @@ -546,12 +579,6 @@ void transport_deregister_session(struct se_session *se_sess) | |||
| 546 | transport_free_session(se_sess); | 579 | transport_free_session(se_sess); |
| 547 | return; | 580 | return; |
| 548 | } | 581 | } |
| 549 | /* | ||
| 550 | * Wait for possible reference in drivers/target/target_core_mib.c: | ||
| 551 | * scsi_att_intr_port_seq_show() | ||
| 552 | */ | ||
| 553 | while (atomic_read(&se_sess->mib_ref_count) != 0) | ||
| 554 | cpu_relax(); | ||
| 555 | 582 | ||
| 556 | spin_lock_bh(&se_tpg->session_lock); | 583 | spin_lock_bh(&se_tpg->session_lock); |
| 557 | list_del(&se_sess->sess_list); | 584 | list_del(&se_sess->sess_list); |
| @@ -574,7 +601,6 @@ void transport_deregister_session(struct se_session *se_sess) | |||
| 574 | spin_unlock_bh(&se_tpg->acl_node_lock); | 601 | spin_unlock_bh(&se_tpg->acl_node_lock); |
| 575 | 602 | ||
| 576 | core_tpg_wait_for_nacl_pr_ref(se_nacl); | 603 | core_tpg_wait_for_nacl_pr_ref(se_nacl); |
| 577 | core_tpg_wait_for_mib_ref(se_nacl); | ||
| 578 | core_free_device_list_for_node(se_nacl, se_tpg); | 604 | core_free_device_list_for_node(se_nacl, se_tpg); |
| 579 | TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, | 605 | TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, |
| 580 | se_nacl); | 606 | se_nacl); |
| @@ -4827,6 +4853,8 @@ static int transport_do_se_mem_map( | |||
| 4827 | 4853 | ||
| 4828 | return ret; | 4854 | return ret; |
| 4829 | } | 4855 | } |
| 4856 | |||
| 4857 | BUG_ON(list_empty(se_mem_list)); | ||
| 4830 | /* | 4858 | /* |
| 4831 | * This is the normal path for all normal non BIDI and BIDI-COMMAND | 4859 | * This is the normal path for all normal non BIDI and BIDI-COMMAND |
| 4832 | * WRITE payloads.. If we need to do BIDI READ passthrough for | 4860 | * WRITE payloads.. If we need to do BIDI READ passthrough for |
| @@ -5008,7 +5036,9 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd) | |||
| 5008 | struct se_mem *se_mem = NULL, *se_mem_lout = NULL; | 5036 | struct se_mem *se_mem = NULL, *se_mem_lout = NULL; |
| 5009 | u32 se_mem_cnt = 0, task_offset = 0; | 5037 | u32 se_mem_cnt = 0, task_offset = 0; |
| 5010 | 5038 | ||
| 5011 | BUG_ON(list_empty(cmd->t_task->t_mem_list)); | 5039 | if (!list_empty(T_TASK(cmd)->t_mem_list)) |
| 5040 | se_mem = list_entry(T_TASK(cmd)->t_mem_list->next, | ||
| 5041 | struct se_mem, se_list); | ||
| 5012 | 5042 | ||
| 5013 | ret = transport_do_se_mem_map(dev, task, | 5043 | ret = transport_do_se_mem_map(dev, task, |
| 5014 | cmd->t_task->t_mem_list, NULL, se_mem, | 5044 | cmd->t_task->t_mem_list, NULL, se_mem, |
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile index e6bed5f177f..d79e7e9bf9d 100644 --- a/drivers/tty/hvc/Makefile +++ b/drivers/tty/hvc/Makefile | |||
| @@ -10,4 +10,3 @@ obj-$(CONFIG_HVC_XEN) += hvc_xen.o | |||
| 10 | obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o | 10 | obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o |
| 11 | obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o | 11 | obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o |
| 12 | obj-$(CONFIG_HVCS) += hvcs.o | 12 | obj-$(CONFIG_HVCS) += hvcs.o |
| 13 | obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o | ||
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 44b8412a04e..aa2e5d3eb01 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
| @@ -2414,6 +2414,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm, | |||
| 2414 | 2414 | ||
| 2415 | gsm->initiator = c->initiator; | 2415 | gsm->initiator = c->initiator; |
| 2416 | gsm->mru = c->mru; | 2416 | gsm->mru = c->mru; |
| 2417 | gsm->mtu = c->mtu; | ||
| 2417 | gsm->encoding = c->encapsulation; | 2418 | gsm->encoding = c->encapsulation; |
| 2418 | gsm->adaption = c->adaption; | 2419 | gsm->adaption = c->adaption; |
| 2419 | gsm->n2 = c->n2; | 2420 | gsm->n2 = c->n2; |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index be0ebce36e5..de0160e3f8c 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
| @@ -262,7 +262,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status) | |||
| 262 | 262 | ||
| 263 | static void receive_chars(struct m68k_serial *info, unsigned short rx) | 263 | static void receive_chars(struct m68k_serial *info, unsigned short rx) |
| 264 | { | 264 | { |
| 265 | struct tty_struct *tty = info->port.tty; | 265 | struct tty_struct *tty = info->tty; |
| 266 | m68328_uart *uart = &uart_addr[info->line]; | 266 | m68328_uart *uart = &uart_addr[info->line]; |
| 267 | unsigned char ch, flag; | 267 | unsigned char ch, flag; |
| 268 | 268 | ||
| @@ -329,7 +329,7 @@ static void transmit_chars(struct m68k_serial *info) | |||
| 329 | goto clear_and_return; | 329 | goto clear_and_return; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | if((info->xmit_cnt <= 0) || info->port.tty->stopped) { | 332 | if((info->xmit_cnt <= 0) || info->tty->stopped) { |
| 333 | /* That's peculiar... TX ints off */ | 333 | /* That's peculiar... TX ints off */ |
| 334 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; | 334 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; |
| 335 | goto clear_and_return; | 335 | goto clear_and_return; |
| @@ -383,7 +383,7 @@ static void do_softint(struct work_struct *work) | |||
| 383 | struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue); | 383 | struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue); |
| 384 | struct tty_struct *tty; | 384 | struct tty_struct *tty; |
| 385 | 385 | ||
| 386 | tty = info->port.tty; | 386 | tty = info->tty; |
| 387 | if (!tty) | 387 | if (!tty) |
| 388 | return; | 388 | return; |
| 389 | #if 0 | 389 | #if 0 |
| @@ -407,7 +407,7 @@ static void do_serial_hangup(struct work_struct *work) | |||
| 407 | struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup); | 407 | struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup); |
| 408 | struct tty_struct *tty; | 408 | struct tty_struct *tty; |
| 409 | 409 | ||
| 410 | tty = info->port.tty; | 410 | tty = info->tty; |
| 411 | if (!tty) | 411 | if (!tty) |
| 412 | return; | 412 | return; |
| 413 | 413 | ||
| @@ -451,8 +451,8 @@ static int startup(struct m68k_serial * info) | |||
| 451 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; | 451 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; |
| 452 | #endif | 452 | #endif |
| 453 | 453 | ||
| 454 | if (info->port.tty) | 454 | if (info->tty) |
| 455 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | 455 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
| 456 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 456 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
| 457 | 457 | ||
| 458 | /* | 458 | /* |
| @@ -486,8 +486,8 @@ static void shutdown(struct m68k_serial * info) | |||
| 486 | info->xmit_buf = 0; | 486 | info->xmit_buf = 0; |
| 487 | } | 487 | } |
| 488 | 488 | ||
| 489 | if (info->port.tty) | 489 | if (info->tty) |
| 490 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 490 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
| 491 | 491 | ||
| 492 | info->flags &= ~S_INITIALIZED; | 492 | info->flags &= ~S_INITIALIZED; |
| 493 | local_irq_restore(flags); | 493 | local_irq_restore(flags); |
| @@ -553,9 +553,9 @@ static void change_speed(struct m68k_serial *info) | |||
| 553 | unsigned cflag; | 553 | unsigned cflag; |
| 554 | int i; | 554 | int i; |
| 555 | 555 | ||
| 556 | if (!info->port.tty || !info->port.tty->termios) | 556 | if (!info->tty || !info->tty->termios) |
| 557 | return; | 557 | return; |
| 558 | cflag = info->port.tty->termios->c_cflag; | 558 | cflag = info->tty->termios->c_cflag; |
| 559 | if (!(port = info->port)) | 559 | if (!(port = info->port)) |
| 560 | return; | 560 | return; |
| 561 | 561 | ||
| @@ -970,7 +970,6 @@ static void send_break(struct m68k_serial * info, unsigned int duration) | |||
| 970 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 970 | static int rs_ioctl(struct tty_struct *tty, struct file * file, |
| 971 | unsigned int cmd, unsigned long arg) | 971 | unsigned int cmd, unsigned long arg) |
| 972 | { | 972 | { |
| 973 | int error; | ||
| 974 | struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; | 973 | struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; |
| 975 | int retval; | 974 | int retval; |
| 976 | 975 | ||
| @@ -1104,7 +1103,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
| 1104 | tty_ldisc_flush(tty); | 1103 | tty_ldisc_flush(tty); |
| 1105 | tty->closing = 0; | 1104 | tty->closing = 0; |
| 1106 | info->event = 0; | 1105 | info->event = 0; |
| 1107 | info->port.tty = NULL; | 1106 | info->tty = NULL; |
| 1108 | #warning "This is not and has never been valid so fix it" | 1107 | #warning "This is not and has never been valid so fix it" |
| 1109 | #if 0 | 1108 | #if 0 |
| 1110 | if (tty->ldisc.num != ldiscs[N_TTY].num) { | 1109 | if (tty->ldisc.num != ldiscs[N_TTY].num) { |
| @@ -1142,7 +1141,7 @@ void rs_hangup(struct tty_struct *tty) | |||
| 1142 | info->event = 0; | 1141 | info->event = 0; |
| 1143 | info->count = 0; | 1142 | info->count = 0; |
| 1144 | info->flags &= ~S_NORMAL_ACTIVE; | 1143 | info->flags &= ~S_NORMAL_ACTIVE; |
| 1145 | info->port.tty = NULL; | 1144 | info->tty = NULL; |
| 1146 | wake_up_interruptible(&info->open_wait); | 1145 | wake_up_interruptible(&info->open_wait); |
| 1147 | } | 1146 | } |
| 1148 | 1147 | ||
| @@ -1261,7 +1260,7 @@ int rs_open(struct tty_struct *tty, struct file * filp) | |||
| 1261 | 1260 | ||
| 1262 | info->count++; | 1261 | info->count++; |
| 1263 | tty->driver_data = info; | 1262 | tty->driver_data = info; |
| 1264 | info->port.tty = tty; | 1263 | info->tty = tty; |
| 1265 | 1264 | ||
| 1266 | /* | 1265 | /* |
| 1267 | * Start up serial port | 1266 | * Start up serial port |
| @@ -1338,7 +1337,7 @@ rs68328_init(void) | |||
| 1338 | info = &m68k_soft[i]; | 1337 | info = &m68k_soft[i]; |
| 1339 | info->magic = SERIAL_MAGIC; | 1338 | info->magic = SERIAL_MAGIC; |
| 1340 | info->port = (int) &uart_addr[i]; | 1339 | info->port = (int) &uart_addr[i]; |
| 1341 | info->port.tty = NULL; | 1340 | info->tty = NULL; |
| 1342 | info->irq = uart_irqs[i]; | 1341 | info->irq = uart_irqs[i]; |
| 1343 | info->custom_divisor = 16; | 1342 | info->custom_divisor = 16; |
| 1344 | info->close_delay = 50; | 1343 | info->close_delay = 50; |
diff --git a/drivers/tty/serial/68360serial.c b/drivers/tty/serial/68360serial.c index 88b13356ec1..bc21eeae8fd 100644 --- a/drivers/tty/serial/68360serial.c +++ b/drivers/tty/serial/68360serial.c | |||
| @@ -2428,6 +2428,7 @@ static const struct tty_operations rs_360_ops = { | |||
| 2428 | /* .read_proc = rs_360_read_proc, */ | 2428 | /* .read_proc = rs_360_read_proc, */ |
| 2429 | .tiocmget = rs_360_tiocmget, | 2429 | .tiocmget = rs_360_tiocmget, |
| 2430 | .tiocmset = rs_360_tiocmset, | 2430 | .tiocmset = rs_360_tiocmset, |
| 2431 | .get_icount = rs_360_get_icount, | ||
| 2431 | }; | 2432 | }; |
| 2432 | 2433 | ||
| 2433 | static int __init rs_360_init(void) | 2434 | static int __init rs_360_init(void) |
diff --git a/drivers/tty/serial/bfin_5xx.c b/drivers/tty/serial/bfin_5xx.c index e381b895b04..9b1ff2b6bb3 100644 --- a/drivers/tty/serial/bfin_5xx.c +++ b/drivers/tty/serial/bfin_5xx.c | |||
| @@ -370,10 +370,8 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) | |||
| 370 | { | 370 | { |
| 371 | struct bfin_serial_port *uart = dev_id; | 371 | struct bfin_serial_port *uart = dev_id; |
| 372 | 372 | ||
| 373 | spin_lock(&uart->port.lock); | ||
| 374 | while (UART_GET_LSR(uart) & DR) | 373 | while (UART_GET_LSR(uart) & DR) |
| 375 | bfin_serial_rx_chars(uart); | 374 | bfin_serial_rx_chars(uart); |
| 376 | spin_unlock(&uart->port.lock); | ||
| 377 | 375 | ||
| 378 | return IRQ_HANDLED; | 376 | return IRQ_HANDLED; |
| 379 | } | 377 | } |
| @@ -490,9 +488,8 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
| 490 | { | 488 | { |
| 491 | int x_pos, pos; | 489 | int x_pos, pos; |
| 492 | 490 | ||
| 493 | dma_disable_irq(uart->tx_dma_channel); | 491 | dma_disable_irq_nosync(uart->rx_dma_channel); |
| 494 | dma_disable_irq(uart->rx_dma_channel); | 492 | spin_lock_bh(&uart->rx_lock); |
| 495 | spin_lock_bh(&uart->port.lock); | ||
| 496 | 493 | ||
| 497 | /* 2D DMA RX buffer ring is used. Because curr_y_count and | 494 | /* 2D DMA RX buffer ring is used. Because curr_y_count and |
| 498 | * curr_x_count can't be read as an atomic operation, | 495 | * curr_x_count can't be read as an atomic operation, |
| @@ -523,8 +520,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
| 523 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; | 520 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; |
| 524 | } | 521 | } |
| 525 | 522 | ||
| 526 | spin_unlock_bh(&uart->port.lock); | 523 | spin_unlock_bh(&uart->rx_lock); |
| 527 | dma_enable_irq(uart->tx_dma_channel); | ||
| 528 | dma_enable_irq(uart->rx_dma_channel); | 524 | dma_enable_irq(uart->rx_dma_channel); |
| 529 | 525 | ||
| 530 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 526 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
| @@ -571,7 +567,7 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) | |||
| 571 | unsigned short irqstat; | 567 | unsigned short irqstat; |
| 572 | int x_pos, pos; | 568 | int x_pos, pos; |
| 573 | 569 | ||
| 574 | spin_lock(&uart->port.lock); | 570 | spin_lock(&uart->rx_lock); |
| 575 | irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); | 571 | irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); |
| 576 | clear_dma_irqstat(uart->rx_dma_channel); | 572 | clear_dma_irqstat(uart->rx_dma_channel); |
| 577 | 573 | ||
| @@ -589,7 +585,7 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) | |||
| 589 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; | 585 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; |
| 590 | } | 586 | } |
| 591 | 587 | ||
| 592 | spin_unlock(&uart->port.lock); | 588 | spin_unlock(&uart->rx_lock); |
| 593 | 589 | ||
| 594 | return IRQ_HANDLED; | 590 | return IRQ_HANDLED; |
| 595 | } | 591 | } |
| @@ -1332,6 +1328,7 @@ static int bfin_serial_probe(struct platform_device *pdev) | |||
| 1332 | } | 1328 | } |
| 1333 | 1329 | ||
| 1334 | #ifdef CONFIG_SERIAL_BFIN_DMA | 1330 | #ifdef CONFIG_SERIAL_BFIN_DMA |
| 1331 | spin_lock_init(&uart->rx_lock); | ||
| 1335 | uart->tx_done = 1; | 1332 | uart->tx_done = 1; |
| 1336 | uart->tx_count = 0; | 1333 | uart->tx_count = 0; |
| 1337 | 1334 | ||
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index beb1afa27d8..7b951adac54 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
| @@ -601,7 +601,7 @@ static int max3100_startup(struct uart_port *port) | |||
| 601 | s->rts = 0; | 601 | s->rts = 0; |
| 602 | 602 | ||
| 603 | sprintf(b, "max3100-%d", s->minor); | 603 | sprintf(b, "max3100-%d", s->minor); |
| 604 | s->workqueue = create_freezeable_workqueue(b); | 604 | s->workqueue = create_freezable_workqueue(b); |
| 605 | if (!s->workqueue) { | 605 | if (!s->workqueue) { |
| 606 | dev_warn(&s->spi->dev, "cannot create workqueue\n"); | 606 | dev_warn(&s->spi->dev, "cannot create workqueue\n"); |
| 607 | return -EBUSY; | 607 | return -EBUSY; |
diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index 910870edf70..750b4f62731 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c | |||
| @@ -833,7 +833,7 @@ static int max3107_startup(struct uart_port *port) | |||
| 833 | struct max3107_port *s = container_of(port, struct max3107_port, port); | 833 | struct max3107_port *s = container_of(port, struct max3107_port, port); |
| 834 | 834 | ||
| 835 | /* Initialize work queue */ | 835 | /* Initialize work queue */ |
| 836 | s->workqueue = create_freezeable_workqueue("max3107"); | 836 | s->workqueue = create_freezable_workqueue("max3107"); |
| 837 | if (!s->workqueue) { | 837 | if (!s->workqueue) { |
| 838 | dev_err(&s->spi->dev, "Workqueue creation failed\n"); | 838 | dev_err(&s->spi->dev, "Workqueue creation failed\n"); |
| 839 | return -EBUSY; | 839 | return -EBUSY; |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 8e0dd254eb1..81f13958e75 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
| @@ -571,6 +571,7 @@ struct sysrq_state { | |||
| 571 | unsigned int alt_use; | 571 | unsigned int alt_use; |
| 572 | bool active; | 572 | bool active; |
| 573 | bool need_reinject; | 573 | bool need_reinject; |
| 574 | bool reinjecting; | ||
| 574 | }; | 575 | }; |
| 575 | 576 | ||
| 576 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) | 577 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) |
| @@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) | |||
| 581 | unsigned int alt_code = sysrq->alt_use; | 582 | unsigned int alt_code = sysrq->alt_use; |
| 582 | 583 | ||
| 583 | if (sysrq->need_reinject) { | 584 | if (sysrq->need_reinject) { |
| 585 | /* we do not want the assignment to be reordered */ | ||
| 586 | sysrq->reinjecting = true; | ||
| 587 | mb(); | ||
| 588 | |||
| 584 | /* Simulate press and release of Alt + SysRq */ | 589 | /* Simulate press and release of Alt + SysRq */ |
| 585 | input_inject_event(handle, EV_KEY, alt_code, 1); | 590 | input_inject_event(handle, EV_KEY, alt_code, 1); |
| 586 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); | 591 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); |
| @@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) | |||
| 589 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); | 594 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); |
| 590 | input_inject_event(handle, EV_KEY, alt_code, 0); | 595 | input_inject_event(handle, EV_KEY, alt_code, 0); |
| 591 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); | 596 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); |
| 597 | |||
| 598 | mb(); | ||
| 599 | sysrq->reinjecting = false; | ||
| 592 | } | 600 | } |
| 593 | } | 601 | } |
| 594 | 602 | ||
| @@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle, | |||
| 599 | bool was_active = sysrq->active; | 607 | bool was_active = sysrq->active; |
| 600 | bool suppress; | 608 | bool suppress; |
| 601 | 609 | ||
| 610 | /* | ||
| 611 | * Do not filter anything if we are in the process of re-injecting | ||
| 612 | * Alt+SysRq combination. | ||
| 613 | */ | ||
| 614 | if (sysrq->reinjecting) | ||
| 615 | return false; | ||
| 616 | |||
| 602 | switch (type) { | 617 | switch (type) { |
| 603 | 618 | ||
| 604 | case EV_SYN: | 619 | case EV_SYN: |
| @@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle, | |||
| 629 | sysrq->alt_use = sysrq->alt; | 644 | sysrq->alt_use = sysrq->alt; |
| 630 | /* | 645 | /* |
| 631 | * If nothing else will be pressed we'll need | 646 | * If nothing else will be pressed we'll need |
| 632 | * to * re-inject Alt-SysRq keysroke. | 647 | * to re-inject Alt-SysRq keysroke. |
| 633 | */ | 648 | */ |
| 634 | sysrq->need_reinject = true; | 649 | sysrq->need_reinject = true; |
| 635 | } | 650 | } |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d6ede989ff2..4ab49d4eebf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -1607,6 +1607,7 @@ static const struct usb_device_id acm_ids[] = { | |||
| 1607 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ | 1607 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ |
| 1608 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ | 1608 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ |
| 1609 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ | 1609 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ |
| 1610 | { NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */ | ||
| 1610 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | 1611 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ |
| 1611 | 1612 | ||
| 1612 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1613 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6a95017fa62..e935f71d7a3 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -1955,7 +1955,6 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) | |||
| 1955 | 1955 | ||
| 1956 | dev_dbg(&rhdev->dev, "usb %s%s\n", | 1956 | dev_dbg(&rhdev->dev, "usb %s%s\n", |
| 1957 | (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); | 1957 | (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); |
| 1958 | clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); | ||
| 1959 | if (!hcd->driver->bus_resume) | 1958 | if (!hcd->driver->bus_resume) |
| 1960 | return -ENOENT; | 1959 | return -ENOENT; |
| 1961 | if (hcd->state == HC_STATE_RUNNING) | 1960 | if (hcd->state == HC_STATE_RUNNING) |
| @@ -1963,6 +1962,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) | |||
| 1963 | 1962 | ||
| 1964 | hcd->state = HC_STATE_RESUMING; | 1963 | hcd->state = HC_STATE_RESUMING; |
| 1965 | status = hcd->driver->bus_resume(hcd); | 1964 | status = hcd->driver->bus_resume(hcd); |
| 1965 | clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); | ||
| 1966 | if (status == 0) { | 1966 | if (status == 0) { |
| 1967 | /* TRSMRCY = 10 msec */ | 1967 | /* TRSMRCY = 10 msec */ |
| 1968 | msleep(10); | 1968 | msleep(10); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4310cc4b1cb..d041c6826e4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -2753,6 +2753,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
| 2753 | udev->ttport = hdev->ttport; | 2753 | udev->ttport = hdev->ttport; |
| 2754 | } else if (udev->speed != USB_SPEED_HIGH | 2754 | } else if (udev->speed != USB_SPEED_HIGH |
| 2755 | && hdev->speed == USB_SPEED_HIGH) { | 2755 | && hdev->speed == USB_SPEED_HIGH) { |
| 2756 | if (!hub->tt.hub) { | ||
| 2757 | dev_err(&udev->dev, "parent hub has no TT\n"); | ||
| 2758 | retval = -EINVAL; | ||
| 2759 | goto fail; | ||
| 2760 | } | ||
| 2756 | udev->tt = &hub->tt; | 2761 | udev->tt = &hub->tt; |
| 2757 | udev->ttport = port1; | 2762 | udev->ttport = port1; |
| 2758 | } | 2763 | } |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 06bb9d4587e..d50099675f2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -546,6 +546,8 @@ config USB_GADGET_CI13XXX_MSM | |||
| 546 | ci13xxx_udc core. | 546 | ci13xxx_udc core. |
| 547 | This driver depends on OTG driver for PHY initialization, | 547 | This driver depends on OTG driver for PHY initialization, |
| 548 | clock management, powering up VBUS, and power management. | 548 | clock management, powering up VBUS, and power management. |
| 549 | This driver is not supported on boards like trout which | ||
| 550 | has an external PHY. | ||
| 549 | 551 | ||
| 550 | Say "y" to link the driver statically, or "m" to build a | 552 | Say "y" to link the driver statically, or "m" to build a |
| 551 | dynamically linked module called "ci13xxx_msm" and force all | 553 | dynamically linked module called "ci13xxx_msm" and force all |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index b5dbb2308f5..6d8e533949e 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
| @@ -293,6 +293,7 @@ | |||
| 293 | 293 | ||
| 294 | #include <linux/usb/ch9.h> | 294 | #include <linux/usb/ch9.h> |
| 295 | #include <linux/usb/gadget.h> | 295 | #include <linux/usb/gadget.h> |
| 296 | #include <linux/usb/composite.h> | ||
| 296 | 297 | ||
| 297 | #include "gadget_chips.h" | 298 | #include "gadget_chips.h" |
| 298 | 299 | ||
| @@ -2763,7 +2764,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
| 2763 | return ERR_PTR(-ENOMEM); | 2764 | return ERR_PTR(-ENOMEM); |
| 2764 | common->free_storage_on_release = 1; | 2765 | common->free_storage_on_release = 1; |
| 2765 | } else { | 2766 | } else { |
| 2766 | memset(common, 0, sizeof common); | 2767 | memset(common, 0, sizeof *common); |
| 2767 | common->free_storage_on_release = 0; | 2768 | common->free_storage_on_release = 0; |
| 2768 | } | 2769 | } |
| 2769 | 2770 | ||
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 20d43da319a..015118535f7 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
| @@ -258,7 +258,7 @@ static int pipe_buffer_setting(struct r8a66597 *r8a66597, | |||
| 258 | break; | 258 | break; |
| 259 | case R8A66597_BULK: | 259 | case R8A66597_BULK: |
| 260 | /* isochronous pipes may be used as bulk pipes */ | 260 | /* isochronous pipes may be used as bulk pipes */ |
| 261 | if (info->pipe > R8A66597_BASE_PIPENUM_BULK) | 261 | if (info->pipe >= R8A66597_BASE_PIPENUM_BULK) |
| 262 | bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK; | 262 | bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK; |
| 263 | else | 263 | else |
| 264 | bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC; | 264 | bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC; |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 24046c0f587..0e6afa260ed 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -151,6 +151,8 @@ config USB_EHCI_MSM | |||
| 151 | Qualcomm chipsets. Root Hub has inbuilt TT. | 151 | Qualcomm chipsets. Root Hub has inbuilt TT. |
| 152 | This driver depends on OTG driver for PHY initialization, | 152 | This driver depends on OTG driver for PHY initialization, |
| 153 | clock management, powering up VBUS, and power management. | 153 | clock management, powering up VBUS, and power management. |
| 154 | This driver is not supported on boards like trout which | ||
| 155 | has an external PHY. | ||
| 154 | 156 | ||
| 155 | config USB_EHCI_HCD_PPC_OF | 157 | config USB_EHCI_HCD_PPC_OF |
| 156 | bool "EHCI support for PPC USB controller on OF platform bus" | 158 | bool "EHCI support for PPC USB controller on OF platform bus" |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 2baf8a84908..a869e3c103d 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
| @@ -227,8 +227,8 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) | |||
| 227 | * mark HW unaccessible. The PM and USB cores make sure that | 227 | * mark HW unaccessible. The PM and USB cores make sure that |
| 228 | * the root hub is either suspended or stopped. | 228 | * the root hub is either suspended or stopped. |
| 229 | */ | 229 | */ |
| 230 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 231 | ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); | 230 | ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); |
| 231 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 232 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | 232 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
| 233 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); | 233 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); |
| 234 | 234 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 796ea0c8900..8a515f0d598 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -111,6 +111,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | |||
| 111 | { | 111 | { |
| 112 | int port; | 112 | int port; |
| 113 | u32 temp; | 113 | u32 temp; |
| 114 | unsigned long flags; | ||
| 114 | 115 | ||
| 115 | /* If remote wakeup is enabled for the root hub but disabled | 116 | /* If remote wakeup is enabled for the root hub but disabled |
| 116 | * for the controller, we must adjust all the port wakeup flags | 117 | * for the controller, we must adjust all the port wakeup flags |
| @@ -120,6 +121,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | |||
| 120 | if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup) | 121 | if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup) |
| 121 | return; | 122 | return; |
| 122 | 123 | ||
| 124 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 125 | |||
| 123 | /* clear phy low-power mode before changing wakeup flags */ | 126 | /* clear phy low-power mode before changing wakeup flags */ |
| 124 | if (ehci->has_hostpc) { | 127 | if (ehci->has_hostpc) { |
| 125 | port = HCS_N_PORTS(ehci->hcs_params); | 128 | port = HCS_N_PORTS(ehci->hcs_params); |
| @@ -131,7 +134,9 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | |||
| 131 | temp = ehci_readl(ehci, hostpc_reg); | 134 | temp = ehci_readl(ehci, hostpc_reg); |
| 132 | ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg); | 135 | ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg); |
| 133 | } | 136 | } |
| 137 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
| 134 | msleep(5); | 138 | msleep(5); |
| 139 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 135 | } | 140 | } |
| 136 | 141 | ||
| 137 | port = HCS_N_PORTS(ehci->hcs_params); | 142 | port = HCS_N_PORTS(ehci->hcs_params); |
| @@ -170,6 +175,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | |||
| 170 | /* Does the root hub have a port wakeup pending? */ | 175 | /* Does the root hub have a port wakeup pending? */ |
| 171 | if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) | 176 | if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) |
| 172 | usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); | 177 | usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); |
| 178 | |||
| 179 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
| 173 | } | 180 | } |
| 174 | 181 | ||
| 175 | static int ehci_bus_suspend (struct usb_hcd *hcd) | 182 | static int ehci_bus_suspend (struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 680f2ef4e59..f784ceb862a 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
| @@ -796,7 +796,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
| 796 | hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev, | 796 | hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev, |
| 797 | dev_name(&pdev->dev)); | 797 | dev_name(&pdev->dev)); |
| 798 | if (!hcd) { | 798 | if (!hcd) { |
| 799 | dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret); | 799 | dev_err(&pdev->dev, "failed to create hcd with err %d\n", ret); |
| 800 | ret = -ENOMEM; | 800 | ret = -ENOMEM; |
| 801 | goto err_create_hcd; | 801 | goto err_create_hcd; |
| 802 | } | 802 | } |
| @@ -864,7 +864,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
| 864 | 864 | ||
| 865 | ret = omap_start_ehc(omap, hcd); | 865 | ret = omap_start_ehc(omap, hcd); |
| 866 | if (ret) { | 866 | if (ret) { |
| 867 | dev_dbg(&pdev->dev, "failed to start ehci\n"); | 867 | dev_err(&pdev->dev, "failed to start ehci with err %d\n", ret); |
| 868 | goto err_start; | 868 | goto err_start; |
| 869 | } | 869 | } |
| 870 | 870 | ||
| @@ -879,7 +879,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
| 879 | 879 | ||
| 880 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 880 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 881 | if (ret) { | 881 | if (ret) { |
| 882 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); | 882 | dev_err(&pdev->dev, "failed to add hcd with err %d\n", ret); |
| 883 | goto err_add_hcd; | 883 | goto err_add_hcd; |
| 884 | } | 884 | } |
| 885 | 885 | ||
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index bed07d4aab0..07bb982e59f 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -367,8 +367,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
| 367 | * mark HW unaccessible. The PM and USB cores make sure that | 367 | * mark HW unaccessible. The PM and USB cores make sure that |
| 368 | * the root hub is either suspended or stopped. | 368 | * the root hub is either suspended or stopped. |
| 369 | */ | 369 | */ |
| 370 | spin_lock_irqsave (&ehci->lock, flags); | ||
| 371 | ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); | 370 | ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); |
| 371 | spin_lock_irqsave (&ehci->lock, flags); | ||
| 372 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | 372 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
| 373 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); | 373 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); |
| 374 | 374 | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 990f06b89ea..2e9602a10e9 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
| @@ -861,6 +861,7 @@ static int sl811h_urb_enqueue( | |||
| 861 | DBG("dev %d ep%d maxpacket %d\n", | 861 | DBG("dev %d ep%d maxpacket %d\n", |
| 862 | udev->devnum, epnum, ep->maxpacket); | 862 | udev->devnum, epnum, ep->maxpacket); |
| 863 | retval = -EINVAL; | 863 | retval = -EINVAL; |
| 864 | kfree(ep); | ||
| 864 | goto fail; | 865 | goto fail; |
| 865 | } | 866 | } |
| 866 | 867 | ||
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index eeba228eb2a..9d49d1cd7ce 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
| @@ -404,6 +404,7 @@ static int bfin_musb_init(struct musb *musb) | |||
| 404 | musb->xceiv->set_power = bfin_musb_set_power; | 404 | musb->xceiv->set_power = bfin_musb_set_power; |
| 405 | 405 | ||
| 406 | musb->isr = blackfin_interrupt; | 406 | musb->isr = blackfin_interrupt; |
| 407 | musb->double_buffer_not_ok = true; | ||
| 407 | 408 | ||
| 408 | return 0; | 409 | return 0; |
| 409 | } | 410 | } |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 07cf394e491..54a8bd1047d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -128,12 +128,7 @@ MODULE_ALIAS("platform:" MUSB_DRIVER_NAME); | |||
| 128 | 128 | ||
| 129 | static inline struct musb *dev_to_musb(struct device *dev) | 129 | static inline struct musb *dev_to_musb(struct device *dev) |
| 130 | { | 130 | { |
| 131 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
| 132 | /* usbcore insists dev->driver_data is a "struct hcd *" */ | ||
| 133 | return hcd_to_musb(dev_get_drvdata(dev)); | ||
| 134 | #else | ||
| 135 | return dev_get_drvdata(dev); | 131 | return dev_get_drvdata(dev); |
| 136 | #endif | ||
| 137 | } | 132 | } |
| 138 | 133 | ||
| 139 | /*-------------------------------------------------------------------------*/ | 134 | /*-------------------------------------------------------------------------*/ |
| @@ -1876,10 +1871,9 @@ allocate_instance(struct device *dev, | |||
| 1876 | musb = kzalloc(sizeof *musb, GFP_KERNEL); | 1871 | musb = kzalloc(sizeof *musb, GFP_KERNEL); |
| 1877 | if (!musb) | 1872 | if (!musb) |
| 1878 | return NULL; | 1873 | return NULL; |
| 1879 | dev_set_drvdata(dev, musb); | ||
| 1880 | 1874 | ||
| 1881 | #endif | 1875 | #endif |
| 1882 | 1876 | dev_set_drvdata(dev, musb); | |
| 1883 | musb->mregs = mbase; | 1877 | musb->mregs = mbase; |
| 1884 | musb->ctrl_base = mbase; | 1878 | musb->ctrl_base = mbase; |
| 1885 | musb->nIrq = -ENODEV; | 1879 | musb->nIrq = -ENODEV; |
| @@ -2191,7 +2185,7 @@ static int __init musb_probe(struct platform_device *pdev) | |||
| 2191 | void __iomem *base; | 2185 | void __iomem *base; |
| 2192 | 2186 | ||
| 2193 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2187 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2194 | if (!iomem || irq == 0) | 2188 | if (!iomem || irq <= 0) |
| 2195 | return -ENODEV; | 2189 | return -ENODEV; |
| 2196 | 2190 | ||
| 2197 | base = ioremap(iomem->start, resource_size(iomem)); | 2191 | base = ioremap(iomem->start, resource_size(iomem)); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d0c236f8e19..d74a8113ae7 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
| @@ -488,6 +488,18 @@ struct musb { | |||
| 488 | unsigned set_address:1; | 488 | unsigned set_address:1; |
| 489 | unsigned test_mode:1; | 489 | unsigned test_mode:1; |
| 490 | unsigned softconnect:1; | 490 | unsigned softconnect:1; |
| 491 | /* | ||
| 492 | * FIXME: Remove this flag. | ||
| 493 | * | ||
| 494 | * This is only added to allow Blackfin to work | ||
| 495 | * with current driver. For some unknown reason | ||
| 496 | * Blackfin doesn't work with double buffering | ||
| 497 | * and that's enabled by default. | ||
| 498 | * | ||
| 499 | * We added this flag to forcefully disable double | ||
| 500 | * buffering until we get it working. | ||
| 501 | */ | ||
| 502 | unsigned double_buffer_not_ok:1 __deprecated; | ||
| 491 | 503 | ||
| 492 | u8 address; | 504 | u8 address; |
| 493 | u8 test_mode_nr; | 505 | u8 test_mode_nr; |
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 916065ba9e7..3a97c4e2d4f 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h | |||
| @@ -169,6 +169,9 @@ struct dma_controller { | |||
| 169 | dma_addr_t dma_addr, | 169 | dma_addr_t dma_addr, |
| 170 | u32 length); | 170 | u32 length); |
| 171 | int (*channel_abort)(struct dma_channel *); | 171 | int (*channel_abort)(struct dma_channel *); |
| 172 | int (*is_compatible)(struct dma_channel *channel, | ||
| 173 | u16 maxpacket, | ||
| 174 | void *buf, u32 length); | ||
| 172 | }; | 175 | }; |
| 173 | 176 | ||
| 174 | /* called after channel_program(), may indicate a fault */ | 177 | /* called after channel_program(), may indicate a fault */ |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ed58c6c8f15..2fe304611dc 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -92,11 +92,33 @@ | |||
| 92 | 92 | ||
| 93 | /* ----------------------------------------------------------------------- */ | 93 | /* ----------------------------------------------------------------------- */ |
| 94 | 94 | ||
| 95 | #define is_buffer_mapped(req) (is_dma_capable() && \ | ||
| 96 | (req->map_state != UN_MAPPED)) | ||
| 97 | |||
| 95 | /* Maps the buffer to dma */ | 98 | /* Maps the buffer to dma */ |
| 96 | 99 | ||
| 97 | static inline void map_dma_buffer(struct musb_request *request, | 100 | static inline void map_dma_buffer(struct musb_request *request, |
| 98 | struct musb *musb) | 101 | struct musb *musb, struct musb_ep *musb_ep) |
| 99 | { | 102 | { |
| 103 | int compatible = true; | ||
| 104 | struct dma_controller *dma = musb->dma_controller; | ||
| 105 | |||
| 106 | request->map_state = UN_MAPPED; | ||
| 107 | |||
| 108 | if (!is_dma_capable() || !musb_ep->dma) | ||
| 109 | return; | ||
| 110 | |||
| 111 | /* Check if DMA engine can handle this request. | ||
| 112 | * DMA code must reject the USB request explicitly. | ||
| 113 | * Default behaviour is to map the request. | ||
| 114 | */ | ||
| 115 | if (dma->is_compatible) | ||
| 116 | compatible = dma->is_compatible(musb_ep->dma, | ||
| 117 | musb_ep->packet_sz, request->request.buf, | ||
| 118 | request->request.length); | ||
| 119 | if (!compatible) | ||
| 120 | return; | ||
| 121 | |||
| 100 | if (request->request.dma == DMA_ADDR_INVALID) { | 122 | if (request->request.dma == DMA_ADDR_INVALID) { |
| 101 | request->request.dma = dma_map_single( | 123 | request->request.dma = dma_map_single( |
| 102 | musb->controller, | 124 | musb->controller, |
| @@ -105,7 +127,7 @@ static inline void map_dma_buffer(struct musb_request *request, | |||
| 105 | request->tx | 127 | request->tx |
| 106 | ? DMA_TO_DEVICE | 128 | ? DMA_TO_DEVICE |
| 107 | : DMA_FROM_DEVICE); | 129 | : DMA_FROM_DEVICE); |
| 108 | request->mapped = 1; | 130 | request->map_state = MUSB_MAPPED; |
| 109 | } else { | 131 | } else { |
| 110 | dma_sync_single_for_device(musb->controller, | 132 | dma_sync_single_for_device(musb->controller, |
| 111 | request->request.dma, | 133 | request->request.dma, |
| @@ -113,7 +135,7 @@ static inline void map_dma_buffer(struct musb_request *request, | |||
| 113 | request->tx | 135 | request->tx |
| 114 | ? DMA_TO_DEVICE | 136 | ? DMA_TO_DEVICE |
| 115 | : DMA_FROM_DEVICE); | 137 | : DMA_FROM_DEVICE); |
| 116 | request->mapped = 0; | 138 | request->map_state = PRE_MAPPED; |
| 117 | } | 139 | } |
| 118 | } | 140 | } |
| 119 | 141 | ||
| @@ -121,11 +143,14 @@ static inline void map_dma_buffer(struct musb_request *request, | |||
| 121 | static inline void unmap_dma_buffer(struct musb_request *request, | 143 | static inline void unmap_dma_buffer(struct musb_request *request, |
| 122 | struct musb *musb) | 144 | struct musb *musb) |
| 123 | { | 145 | { |
| 146 | if (!is_buffer_mapped(request)) | ||
| 147 | return; | ||
| 148 | |||
| 124 | if (request->request.dma == DMA_ADDR_INVALID) { | 149 | if (request->request.dma == DMA_ADDR_INVALID) { |
| 125 | DBG(20, "not unmapping a never mapped buffer\n"); | 150 | DBG(20, "not unmapping a never mapped buffer\n"); |
| 126 | return; | 151 | return; |
| 127 | } | 152 | } |
| 128 | if (request->mapped) { | 153 | if (request->map_state == MUSB_MAPPED) { |
| 129 | dma_unmap_single(musb->controller, | 154 | dma_unmap_single(musb->controller, |
| 130 | request->request.dma, | 155 | request->request.dma, |
| 131 | request->request.length, | 156 | request->request.length, |
| @@ -133,16 +158,15 @@ static inline void unmap_dma_buffer(struct musb_request *request, | |||
| 133 | ? DMA_TO_DEVICE | 158 | ? DMA_TO_DEVICE |
| 134 | : DMA_FROM_DEVICE); | 159 | : DMA_FROM_DEVICE); |
| 135 | request->request.dma = DMA_ADDR_INVALID; | 160 | request->request.dma = DMA_ADDR_INVALID; |
| 136 | request->mapped = 0; | 161 | } else { /* PRE_MAPPED */ |
| 137 | } else { | ||
| 138 | dma_sync_single_for_cpu(musb->controller, | 162 | dma_sync_single_for_cpu(musb->controller, |
| 139 | request->request.dma, | 163 | request->request.dma, |
| 140 | request->request.length, | 164 | request->request.length, |
| 141 | request->tx | 165 | request->tx |
| 142 | ? DMA_TO_DEVICE | 166 | ? DMA_TO_DEVICE |
| 143 | : DMA_FROM_DEVICE); | 167 | : DMA_FROM_DEVICE); |
| 144 | |||
| 145 | } | 168 | } |
| 169 | request->map_state = UN_MAPPED; | ||
| 146 | } | 170 | } |
| 147 | 171 | ||
| 148 | /* | 172 | /* |
| @@ -172,8 +196,7 @@ __acquires(ep->musb->lock) | |||
| 172 | 196 | ||
| 173 | ep->busy = 1; | 197 | ep->busy = 1; |
| 174 | spin_unlock(&musb->lock); | 198 | spin_unlock(&musb->lock); |
| 175 | if (is_dma_capable() && ep->dma) | 199 | unmap_dma_buffer(req, musb); |
| 176 | unmap_dma_buffer(req, musb); | ||
| 177 | if (request->status == 0) | 200 | if (request->status == 0) |
| 178 | DBG(5, "%s done request %p, %d/%d\n", | 201 | DBG(5, "%s done request %p, %d/%d\n", |
| 179 | ep->end_point.name, request, | 202 | ep->end_point.name, request, |
| @@ -335,7 +358,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
| 335 | csr); | 358 | csr); |
| 336 | 359 | ||
| 337 | #ifndef CONFIG_MUSB_PIO_ONLY | 360 | #ifndef CONFIG_MUSB_PIO_ONLY |
| 338 | if (is_dma_capable() && musb_ep->dma) { | 361 | if (is_buffer_mapped(req)) { |
| 339 | struct dma_controller *c = musb->dma_controller; | 362 | struct dma_controller *c = musb->dma_controller; |
| 340 | size_t request_size; | 363 | size_t request_size; |
| 341 | 364 | ||
| @@ -436,8 +459,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
| 436 | * Unmap the dma buffer back to cpu if dma channel | 459 | * Unmap the dma buffer back to cpu if dma channel |
| 437 | * programming fails | 460 | * programming fails |
| 438 | */ | 461 | */ |
| 439 | if (is_dma_capable() && musb_ep->dma) | 462 | unmap_dma_buffer(req, musb); |
| 440 | unmap_dma_buffer(req, musb); | ||
| 441 | 463 | ||
| 442 | musb_write_fifo(musb_ep->hw_ep, fifo_count, | 464 | musb_write_fifo(musb_ep->hw_ep, fifo_count, |
| 443 | (u8 *) (request->buf + request->actual)); | 465 | (u8 *) (request->buf + request->actual)); |
| @@ -627,7 +649,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 627 | return; | 649 | return; |
| 628 | } | 650 | } |
| 629 | 651 | ||
| 630 | if (is_cppi_enabled() && musb_ep->dma) { | 652 | if (is_cppi_enabled() && is_buffer_mapped(req)) { |
| 631 | struct dma_controller *c = musb->dma_controller; | 653 | struct dma_controller *c = musb->dma_controller; |
| 632 | struct dma_channel *channel = musb_ep->dma; | 654 | struct dma_channel *channel = musb_ep->dma; |
| 633 | 655 | ||
| @@ -658,7 +680,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 658 | len = musb_readw(epio, MUSB_RXCOUNT); | 680 | len = musb_readw(epio, MUSB_RXCOUNT); |
| 659 | if (request->actual < request->length) { | 681 | if (request->actual < request->length) { |
| 660 | #ifdef CONFIG_USB_INVENTRA_DMA | 682 | #ifdef CONFIG_USB_INVENTRA_DMA |
| 661 | if (is_dma_capable() && musb_ep->dma) { | 683 | if (is_buffer_mapped(req)) { |
| 662 | struct dma_controller *c; | 684 | struct dma_controller *c; |
| 663 | struct dma_channel *channel; | 685 | struct dma_channel *channel; |
| 664 | int use_dma = 0; | 686 | int use_dma = 0; |
| @@ -742,7 +764,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 742 | fifo_count = min_t(unsigned, len, fifo_count); | 764 | fifo_count = min_t(unsigned, len, fifo_count); |
| 743 | 765 | ||
| 744 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 766 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
| 745 | if (tusb_dma_omap() && musb_ep->dma) { | 767 | if (tusb_dma_omap() && is_buffer_mapped(req)) { |
| 746 | struct dma_controller *c = musb->dma_controller; | 768 | struct dma_controller *c = musb->dma_controller; |
| 747 | struct dma_channel *channel = musb_ep->dma; | 769 | struct dma_channel *channel = musb_ep->dma; |
| 748 | u32 dma_addr = request->dma + request->actual; | 770 | u32 dma_addr = request->dma + request->actual; |
| @@ -762,7 +784,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 762 | * programming fails. This buffer is mapped if the | 784 | * programming fails. This buffer is mapped if the |
| 763 | * channel allocation is successful | 785 | * channel allocation is successful |
| 764 | */ | 786 | */ |
| 765 | if (is_dma_capable() && musb_ep->dma) { | 787 | if (is_buffer_mapped(req)) { |
| 766 | unmap_dma_buffer(req, musb); | 788 | unmap_dma_buffer(req, musb); |
| 767 | 789 | ||
| 768 | /* | 790 | /* |
| @@ -989,7 +1011,11 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
| 989 | /* Set TXMAXP with the FIFO size of the endpoint | 1011 | /* Set TXMAXP with the FIFO size of the endpoint |
| 990 | * to disable double buffering mode. | 1012 | * to disable double buffering mode. |
| 991 | */ | 1013 | */ |
| 992 | musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); | 1014 | if (musb->double_buffer_not_ok) |
| 1015 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); | ||
| 1016 | else | ||
| 1017 | musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | ||
| 1018 | | (musb_ep->hb_mult << 11)); | ||
| 993 | 1019 | ||
| 994 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; | 1020 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; |
| 995 | if (musb_readw(regs, MUSB_TXCSR) | 1021 | if (musb_readw(regs, MUSB_TXCSR) |
| @@ -1025,7 +1051,11 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
| 1025 | /* Set RXMAXP with the FIFO size of the endpoint | 1051 | /* Set RXMAXP with the FIFO size of the endpoint |
| 1026 | * to disable double buffering mode. | 1052 | * to disable double buffering mode. |
| 1027 | */ | 1053 | */ |
| 1028 | musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); | 1054 | if (musb->double_buffer_not_ok) |
| 1055 | musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_tx); | ||
| 1056 | else | ||
| 1057 | musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | ||
| 1058 | | (musb_ep->hb_mult << 11)); | ||
| 1029 | 1059 | ||
| 1030 | /* force shared fifo to OUT-only mode */ | 1060 | /* force shared fifo to OUT-only mode */ |
| 1031 | if (hw_ep->is_shared_fifo) { | 1061 | if (hw_ep->is_shared_fifo) { |
| @@ -1214,10 +1244,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, | |||
| 1214 | request->epnum = musb_ep->current_epnum; | 1244 | request->epnum = musb_ep->current_epnum; |
| 1215 | request->tx = musb_ep->is_in; | 1245 | request->tx = musb_ep->is_in; |
| 1216 | 1246 | ||
| 1217 | if (is_dma_capable() && musb_ep->dma) | 1247 | map_dma_buffer(request, musb, musb_ep); |
| 1218 | map_dma_buffer(request, musb); | ||
| 1219 | else | ||
| 1220 | request->mapped = 0; | ||
| 1221 | 1248 | ||
| 1222 | spin_lock_irqsave(&musb->lock, lockflags); | 1249 | spin_lock_irqsave(&musb->lock, lockflags); |
| 1223 | 1250 | ||
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index dec8dc00819..a55354fbccf 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h | |||
| @@ -35,13 +35,19 @@ | |||
| 35 | #ifndef __MUSB_GADGET_H | 35 | #ifndef __MUSB_GADGET_H |
| 36 | #define __MUSB_GADGET_H | 36 | #define __MUSB_GADGET_H |
| 37 | 37 | ||
| 38 | enum buffer_map_state { | ||
| 39 | UN_MAPPED = 0, | ||
| 40 | PRE_MAPPED, | ||
| 41 | MUSB_MAPPED | ||
| 42 | }; | ||
| 43 | |||
| 38 | struct musb_request { | 44 | struct musb_request { |
| 39 | struct usb_request request; | 45 | struct usb_request request; |
| 40 | struct musb_ep *ep; | 46 | struct musb_ep *ep; |
| 41 | struct musb *musb; | 47 | struct musb *musb; |
| 42 | u8 tx; /* endpoint direction */ | 48 | u8 tx; /* endpoint direction */ |
| 43 | u8 epnum; | 49 | u8 epnum; |
| 44 | u8 mapped; | 50 | enum buffer_map_state map_state; |
| 45 | }; | 51 | }; |
| 46 | 52 | ||
| 47 | static inline struct musb_request *to_musb_request(struct usb_request *req) | 53 | static inline struct musb_request *to_musb_request(struct usb_request *req) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4d5bcb4e14d..0f523d7db57 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -609,7 +609,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
| 609 | /* Set RXMAXP with the FIFO size of the endpoint | 609 | /* Set RXMAXP with the FIFO size of the endpoint |
| 610 | * to disable double buffer mode. | 610 | * to disable double buffer mode. |
| 611 | */ | 611 | */ |
| 612 | if (musb->hwvers < MUSB_HWVERS_2000) | 612 | if (musb->double_buffer_not_ok) |
| 613 | musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx); | 613 | musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx); |
| 614 | else | 614 | else |
| 615 | musb_writew(ep->regs, MUSB_RXMAXP, | 615 | musb_writew(ep->regs, MUSB_RXMAXP, |
| @@ -784,14 +784,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 784 | /* protocol/endpoint/interval/NAKlimit */ | 784 | /* protocol/endpoint/interval/NAKlimit */ |
| 785 | if (epnum) { | 785 | if (epnum) { |
| 786 | musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); | 786 | musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); |
| 787 | if (can_bulk_split(musb, qh->type)) | 787 | if (musb->double_buffer_not_ok) |
| 788 | musb_writew(epio, MUSB_TXMAXP, | 788 | musb_writew(epio, MUSB_TXMAXP, |
| 789 | packet_sz | 789 | hw_ep->max_packet_sz_tx); |
| 790 | | ((hw_ep->max_packet_sz_tx / | ||
| 791 | packet_sz) - 1) << 11); | ||
| 792 | else | 790 | else |
| 793 | musb_writew(epio, MUSB_TXMAXP, | 791 | musb_writew(epio, MUSB_TXMAXP, |
| 794 | packet_sz); | 792 | qh->maxpacket | |
| 793 | ((qh->hb_mult - 1) << 11)); | ||
| 795 | musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); | 794 | musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); |
| 796 | } else { | 795 | } else { |
| 797 | musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); | 796 | musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); |
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index f763d62f151..21056c924c7 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h | |||
| @@ -94,24 +94,33 @@ static inline void musb_write_hsdma_addr(void __iomem *mbase, | |||
| 94 | { | 94 | { |
| 95 | musb_writew(mbase, | 95 | musb_writew(mbase, |
| 96 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW), | 96 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW), |
| 97 | ((u16)((u32) dma_addr & 0xFFFF))); | 97 | dma_addr); |
| 98 | musb_writew(mbase, | 98 | musb_writew(mbase, |
| 99 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH), | 99 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH), |
| 100 | ((u16)(((u32) dma_addr >> 16) & 0xFFFF))); | 100 | (dma_addr >> 16)); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) | 103 | static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) |
| 104 | { | 104 | { |
| 105 | return musb_readl(mbase, | 105 | u32 count = musb_readw(mbase, |
| 106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); | 106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); |
| 107 | |||
| 108 | count = count << 16; | ||
| 109 | |||
| 110 | count |= musb_readw(mbase, | ||
| 111 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW)); | ||
| 112 | |||
| 113 | return count; | ||
| 107 | } | 114 | } |
| 108 | 115 | ||
| 109 | static inline void musb_write_hsdma_count(void __iomem *mbase, | 116 | static inline void musb_write_hsdma_count(void __iomem *mbase, |
| 110 | u8 bchannel, u32 len) | 117 | u8 bchannel, u32 len) |
| 111 | { | 118 | { |
| 112 | musb_writel(mbase, | 119 | musb_writew(mbase, |
| 120 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),len); | ||
| 121 | musb_writew(mbase, | ||
| 113 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), | 122 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), |
| 114 | len); | 123 | (len >> 16)); |
| 115 | } | 124 | } |
| 116 | 125 | ||
| 117 | #endif /* CONFIG_BLACKFIN */ | 126 | #endif /* CONFIG_BLACKFIN */ |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 9fb875d5f09..9ffc8237fb4 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -103,6 +103,8 @@ config USB_MSM_OTG_72K | |||
| 103 | required after resetting the hardware and power management. | 103 | required after resetting the hardware and power management. |
| 104 | This driver is required even for peripheral only or host only | 104 | This driver is required even for peripheral only or host only |
| 105 | mode configurations. | 105 | mode configurations. |
| 106 | This driver is not supported on boards like trout which | ||
| 107 | has an external PHY. | ||
| 106 | 108 | ||
| 107 | config AB8500_USB | 109 | config AB8500_USB |
| 108 | tristate "AB8500 USB Transceiver Driver" | 110 | tristate "AB8500 USB Transceiver Driver" |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4787c0cd063..f349a3629d0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -100,6 +100,7 @@ struct ftdi_sio_quirk { | |||
| 100 | static int ftdi_jtag_probe(struct usb_serial *serial); | 100 | static int ftdi_jtag_probe(struct usb_serial *serial); |
| 101 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | 101 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); |
| 102 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | 102 | static int ftdi_NDI_device_setup(struct usb_serial *serial); |
| 103 | static int ftdi_stmclite_probe(struct usb_serial *serial); | ||
| 103 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | 104 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); |
| 104 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | 105 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); |
| 105 | 106 | ||
| @@ -123,6 +124,10 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | |||
| 123 | .port_probe = ftdi_HE_TIRA1_setup, | 124 | .port_probe = ftdi_HE_TIRA1_setup, |
| 124 | }; | 125 | }; |
| 125 | 126 | ||
| 127 | static struct ftdi_sio_quirk ftdi_stmclite_quirk = { | ||
| 128 | .probe = ftdi_stmclite_probe, | ||
| 129 | }; | ||
| 130 | |||
| 126 | /* | 131 | /* |
| 127 | * The 8U232AM has the same API as the sio except for: | 132 | * The 8U232AM has the same API as the sio except for: |
| 128 | * - it can support MUCH higher baudrates; up to: | 133 | * - it can support MUCH higher baudrates; up to: |
| @@ -616,6 +621,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 616 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, | 621 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, |
| 617 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | 622 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, |
| 618 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | 623 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
| 624 | { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, | ||
| 619 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | 625 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, |
| 620 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 626 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
| 621 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 627 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
| @@ -810,6 +816,8 @@ static struct usb_device_id id_table_combined [] = { | |||
| 810 | { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, | 816 | { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, |
| 811 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), | 817 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), |
| 812 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 818 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 819 | { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), | ||
| 820 | .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, | ||
| 813 | { }, /* Optional parameter entry */ | 821 | { }, /* Optional parameter entry */ |
| 814 | { } /* Terminating entry */ | 822 | { } /* Terminating entry */ |
| 815 | }; | 823 | }; |
| @@ -1709,6 +1717,25 @@ static int ftdi_jtag_probe(struct usb_serial *serial) | |||
| 1709 | } | 1717 | } |
| 1710 | 1718 | ||
| 1711 | /* | 1719 | /* |
| 1720 | * First and second port on STMCLiteadaptors is reserved for JTAG interface | ||
| 1721 | * and the forth port for pio | ||
| 1722 | */ | ||
| 1723 | static int ftdi_stmclite_probe(struct usb_serial *serial) | ||
| 1724 | { | ||
| 1725 | struct usb_device *udev = serial->dev; | ||
| 1726 | struct usb_interface *interface = serial->interface; | ||
| 1727 | |||
| 1728 | dbg("%s", __func__); | ||
| 1729 | |||
| 1730 | if (interface == udev->actconfig->interface[2]) | ||
| 1731 | return 0; | ||
| 1732 | |||
| 1733 | dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n"); | ||
| 1734 | |||
| 1735 | return -ENODEV; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | /* | ||
| 1712 | * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. | 1739 | * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. |
| 1713 | * We have to correct it if we want to read from it. | 1740 | * We have to correct it if we want to read from it. |
| 1714 | */ | 1741 | */ |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index ed160def858..117e8e6f93c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -518,6 +518,12 @@ | |||
| 518 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | 518 | #define RATOC_PRODUCT_ID_USB60F 0xb020 |
| 519 | 519 | ||
| 520 | /* | 520 | /* |
| 521 | * Acton Research Corp. | ||
| 522 | */ | ||
| 523 | #define ACTON_VID 0x0647 /* Vendor ID */ | ||
| 524 | #define ACTON_SPECTRAPRO_PID 0x0100 | ||
| 525 | |||
| 526 | /* | ||
| 521 | * Contec products (http://www.contec.com) | 527 | * Contec products (http://www.contec.com) |
| 522 | * Submitted by Daniel Sangorrin | 528 | * Submitted by Daniel Sangorrin |
| 523 | */ | 529 | */ |
| @@ -1034,6 +1040,12 @@ | |||
| 1034 | #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ | 1040 | #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ |
| 1035 | 1041 | ||
| 1036 | /* | 1042 | /* |
| 1043 | * STMicroelectonics | ||
| 1044 | */ | ||
| 1045 | #define ST_VID 0x0483 | ||
| 1046 | #define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */ | ||
| 1047 | |||
| 1048 | /* | ||
| 1037 | * Papouch products (http://www.papouch.com/) | 1049 | * Papouch products (http://www.papouch.com/) |
| 1038 | * Submitted by Folkert van Heusden | 1050 | * Submitted by Folkert van Heusden |
| 1039 | */ | 1051 | */ |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index cd769ef24f8..3b246d93cf2 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
| @@ -2889,8 +2889,8 @@ static void load_application_firmware(struct edgeport_serial *edge_serial) | |||
| 2889 | 2889 | ||
| 2890 | dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build); | 2890 | dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build); |
| 2891 | 2891 | ||
| 2892 | edge_serial->product_info.FirmwareMajorVersion = fw->data[0]; | 2892 | edge_serial->product_info.FirmwareMajorVersion = rec->data[0]; |
| 2893 | edge_serial->product_info.FirmwareMinorVersion = fw->data[1]; | 2893 | edge_serial->product_info.FirmwareMinorVersion = rec->data[1]; |
| 2894 | edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build); | 2894 | edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build); |
| 2895 | 2895 | ||
| 2896 | for (rec = ihex_next_binrec(rec); rec; | 2896 | for (rec = ihex_next_binrec(rec); rec; |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index b2902f307b4..a910004f407 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -369,9 +369,9 @@ failed_1port: | |||
| 369 | 369 | ||
| 370 | static void __exit ti_exit(void) | 370 | static void __exit ti_exit(void) |
| 371 | { | 371 | { |
| 372 | usb_deregister(&ti_usb_driver); | ||
| 372 | usb_serial_deregister(&ti_1port_device); | 373 | usb_serial_deregister(&ti_1port_device); |
| 373 | usb_serial_deregister(&ti_2port_device); | 374 | usb_serial_deregister(&ti_2port_device); |
| 374 | usb_deregister(&ti_usb_driver); | ||
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | 377 | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 24bd5d7c3de..c1602b8c559 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -1397,6 +1397,13 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, | |||
| 1397 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1397 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 1398 | US_FL_IGNORE_RESIDUE ), | 1398 | US_FL_IGNORE_RESIDUE ), |
| 1399 | 1399 | ||
| 1400 | /* Submitted by Nick Holloway */ | ||
| 1401 | UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100, | ||
| 1402 | "VTech", | ||
| 1403 | "Kidizoom", | ||
| 1404 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 1405 | US_FL_FIX_CAPACITY ), | ||
| 1406 | |||
| 1400 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1407 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
| 1401 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1408 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
| 1402 | "Sony Ericsson", | 1409 | "Sony Ericsson", |
| @@ -1890,6 +1897,13 @@ UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, | |||
| 1890 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1897 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 1891 | US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), | 1898 | US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), |
| 1892 | 1899 | ||
| 1900 | /* Reported by Jasper Mackenzie <scarletpimpernal@hotmail.com> */ | ||
| 1901 | UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0000, | ||
| 1902 | "Coby Electronics", | ||
| 1903 | "MP3 Player", | ||
| 1904 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 1905 | US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), | ||
| 1906 | |||
| 1893 | UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, | 1907 | UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, |
| 1894 | "ST", | 1908 | "ST", |
| 1895 | "2A", | 1909 | "2A", |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 9b3ca103135..f616cefc95b 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
| @@ -128,8 +128,7 @@ static void handle_tx(struct vhost_net *net) | |||
| 128 | size_t hdr_size; | 128 | size_t hdr_size; |
| 129 | struct socket *sock; | 129 | struct socket *sock; |
| 130 | 130 | ||
| 131 | /* TODO: check that we are running from vhost_worker? | 131 | /* TODO: check that we are running from vhost_worker? */ |
| 132 | * Not sure it's worth it, it's straight-forward enough. */ | ||
| 133 | sock = rcu_dereference_check(vq->private_data, 1); | 132 | sock = rcu_dereference_check(vq->private_data, 1); |
| 134 | if (!sock) | 133 | if (!sock) |
| 135 | return; | 134 | return; |
| @@ -306,7 +305,8 @@ static void handle_rx_big(struct vhost_net *net) | |||
| 306 | size_t len, total_len = 0; | 305 | size_t len, total_len = 0; |
| 307 | int err; | 306 | int err; |
| 308 | size_t hdr_size; | 307 | size_t hdr_size; |
| 309 | struct socket *sock = rcu_dereference(vq->private_data); | 308 | /* TODO: check that we are running from vhost_worker? */ |
| 309 | struct socket *sock = rcu_dereference_check(vq->private_data, 1); | ||
| 310 | if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) | 310 | if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) |
| 311 | return; | 311 | return; |
| 312 | 312 | ||
| @@ -415,7 +415,8 @@ static void handle_rx_mergeable(struct vhost_net *net) | |||
| 415 | int err, headcount; | 415 | int err, headcount; |
| 416 | size_t vhost_hlen, sock_hlen; | 416 | size_t vhost_hlen, sock_hlen; |
| 417 | size_t vhost_len, sock_len; | 417 | size_t vhost_len, sock_len; |
| 418 | struct socket *sock = rcu_dereference(vq->private_data); | 418 | /* TODO: check that we are running from vhost_worker? */ |
| 419 | struct socket *sock = rcu_dereference_check(vq->private_data, 1); | ||
| 419 | if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) | 420 | if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue)) |
| 420 | return; | 421 | return; |
| 421 | 422 | ||
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 2af44b7b1f3..b3363ae3851 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
| @@ -173,9 +173,9 @@ static inline int vhost_has_feature(struct vhost_dev *dev, int bit) | |||
| 173 | { | 173 | { |
| 174 | unsigned acked_features; | 174 | unsigned acked_features; |
| 175 | 175 | ||
| 176 | acked_features = | 176 | /* TODO: check that we are running from vhost_worker or dev mutex is |
| 177 | rcu_dereference_index_check(dev->acked_features, | 177 | * held? */ |
| 178 | lockdep_is_held(&dev->mutex)); | 178 | acked_features = rcu_dereference_index_check(dev->acked_features, 1); |
| 179 | return acked_features & (1 << bit); | 179 | return acked_features & (1 << bit); |
| 180 | } | 180 | } |
| 181 | 181 | ||
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 3a7e9ff8a74..38e96ab9094 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c | |||
| @@ -593,19 +593,17 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev) | |||
| 593 | 593 | ||
| 594 | /* get interface & functional clock objects */ | 594 | /* get interface & functional clock objects */ |
| 595 | hdq_data->hdq_ick = clk_get(&pdev->dev, "ick"); | 595 | hdq_data->hdq_ick = clk_get(&pdev->dev, "ick"); |
| 596 | hdq_data->hdq_fck = clk_get(&pdev->dev, "fck"); | 596 | if (IS_ERR(hdq_data->hdq_ick)) { |
| 597 | dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n"); | ||
| 598 | ret = PTR_ERR(hdq_data->hdq_ick); | ||
| 599 | goto err_ick; | ||
| 600 | } | ||
| 597 | 601 | ||
| 598 | if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) { | 602 | hdq_data->hdq_fck = clk_get(&pdev->dev, "fck"); |
| 599 | dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n"); | 603 | if (IS_ERR(hdq_data->hdq_fck)) { |
| 600 | if (IS_ERR(hdq_data->hdq_ick)) { | 604 | dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n"); |
| 601 | ret = PTR_ERR(hdq_data->hdq_ick); | 605 | ret = PTR_ERR(hdq_data->hdq_fck); |
| 602 | goto err_clk; | 606 | goto err_fck; |
| 603 | } | ||
| 604 | if (IS_ERR(hdq_data->hdq_fck)) { | ||
| 605 | ret = PTR_ERR(hdq_data->hdq_fck); | ||
| 606 | clk_put(hdq_data->hdq_ick); | ||
| 607 | goto err_clk; | ||
| 608 | } | ||
| 609 | } | 607 | } |
| 610 | 608 | ||
| 611 | hdq_data->hdq_usecount = 0; | 609 | hdq_data->hdq_usecount = 0; |
| @@ -665,10 +663,12 @@ err_fnclk: | |||
| 665 | clk_disable(hdq_data->hdq_ick); | 663 | clk_disable(hdq_data->hdq_ick); |
| 666 | 664 | ||
| 667 | err_intfclk: | 665 | err_intfclk: |
| 668 | clk_put(hdq_data->hdq_ick); | ||
| 669 | clk_put(hdq_data->hdq_fck); | 666 | clk_put(hdq_data->hdq_fck); |
| 670 | 667 | ||
| 671 | err_clk: | 668 | err_fck: |
| 669 | clk_put(hdq_data->hdq_ick); | ||
| 670 | |||
| 671 | err_ick: | ||
| 672 | iounmap(hdq_data->hdq_base); | 672 | iounmap(hdq_data->hdq_base); |
| 673 | 673 | ||
| 674 | err_ioremap: | 674 | err_ioremap: |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 2e2400e7322..31649b7b672 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -862,12 +862,12 @@ config SBC_EPX_C3_WATCHDOG | |||
| 862 | 862 | ||
| 863 | # M68K Architecture | 863 | # M68K Architecture |
| 864 | 864 | ||
| 865 | config M548x_WATCHDOG | 865 | config M54xx_WATCHDOG |
| 866 | tristate "MCF548x watchdog support" | 866 | tristate "MCF54xx watchdog support" |
| 867 | depends on M548x | 867 | depends on M548x |
| 868 | help | 868 | help |
| 869 | To compile this driver as a module, choose M here: the | 869 | To compile this driver as a module, choose M here: the |
| 870 | module will be called m548x_wdt. | 870 | module will be called m54xx_wdt. |
| 871 | 871 | ||
| 872 | # MIPS Architecture | 872 | # MIPS Architecture |
| 873 | 873 | ||
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index dd776651917..20e44c4782b 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
| @@ -106,7 +106,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o | |||
| 106 | # M32R Architecture | 106 | # M32R Architecture |
| 107 | 107 | ||
| 108 | # M68K Architecture | 108 | # M68K Architecture |
| 109 | obj-$(CONFIG_M548x_WATCHDOG) += m548x_wdt.o | 109 | obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o |
| 110 | 110 | ||
| 111 | # MIPS Architecture | 111 | # MIPS Architecture |
| 112 | obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o | 112 | obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o |
diff --git a/drivers/watchdog/m548x_wdt.c b/drivers/watchdog/m54xx_wdt.c index cabbcfe1c84..4d43286074a 100644 --- a/drivers/watchdog/m548x_wdt.c +++ b/drivers/watchdog/m54xx_wdt.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * drivers/watchdog/m548x_wdt.c | 2 | * drivers/watchdog/m54xx_wdt.c |
| 3 | * | 3 | * |
| 4 | * Watchdog driver for ColdFire MCF548x processors | 4 | * Watchdog driver for ColdFire MCF547x & MCF548x processors |
| 5 | * Copyright 2010 (c) Philippe De Muyter <phdm@macqel.be> | 5 | * Copyright 2010 (c) Philippe De Muyter <phdm@macqel.be> |
| 6 | * | 6 | * |
| 7 | * Adapted from the IXP4xx watchdog driver, which carries these notices: | 7 | * Adapted from the IXP4xx watchdog driver, which carries these notices: |
| @@ -29,8 +29,8 @@ | |||
| 29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
| 30 | 30 | ||
| 31 | #include <asm/coldfire.h> | 31 | #include <asm/coldfire.h> |
| 32 | #include <asm/m548xsim.h> | 32 | #include <asm/m54xxsim.h> |
| 33 | #include <asm/m548xgpt.h> | 33 | #include <asm/m54xxgpt.h> |
| 34 | 34 | ||
| 35 | static int nowayout = WATCHDOG_NOWAYOUT; | 35 | static int nowayout = WATCHDOG_NOWAYOUT; |
| 36 | static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ | 36 | static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ |
| @@ -76,7 +76,7 @@ static void wdt_keepalive(void) | |||
| 76 | __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); | 76 | __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static int m548x_wdt_open(struct inode *inode, struct file *file) | 79 | static int m54xx_wdt_open(struct inode *inode, struct file *file) |
| 80 | { | 80 | { |
| 81 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 81 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
| 82 | return -EBUSY; | 82 | return -EBUSY; |
| @@ -86,7 +86,7 @@ static int m548x_wdt_open(struct inode *inode, struct file *file) | |||
| 86 | return nonseekable_open(inode, file); | 86 | return nonseekable_open(inode, file); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static ssize_t m548x_wdt_write(struct file *file, const char *data, | 89 | static ssize_t m54xx_wdt_write(struct file *file, const char *data, |
| 90 | size_t len, loff_t *ppos) | 90 | size_t len, loff_t *ppos) |
| 91 | { | 91 | { |
| 92 | if (len) { | 92 | if (len) { |
| @@ -112,10 +112,10 @@ static ssize_t m548x_wdt_write(struct file *file, const char *data, | |||
| 112 | static const struct watchdog_info ident = { | 112 | static const struct watchdog_info ident = { |
| 113 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 113 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
| 114 | WDIOF_KEEPALIVEPING, | 114 | WDIOF_KEEPALIVEPING, |
| 115 | .identity = "Coldfire M548x Watchdog", | 115 | .identity = "Coldfire M54xx Watchdog", |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | static long m548x_wdt_ioctl(struct file *file, unsigned int cmd, | 118 | static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, |
| 119 | unsigned long arg) | 119 | unsigned long arg) |
| 120 | { | 120 | { |
| 121 | int ret = -ENOTTY; | 121 | int ret = -ENOTTY; |
| @@ -161,7 +161,7 @@ static long m548x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
| 161 | return ret; | 161 | return ret; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static int m548x_wdt_release(struct inode *inode, struct file *file) | 164 | static int m54xx_wdt_release(struct inode *inode, struct file *file) |
| 165 | { | 165 | { |
| 166 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | 166 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
| 167 | wdt_disable(); | 167 | wdt_disable(); |
| @@ -177,45 +177,45 @@ static int m548x_wdt_release(struct inode *inode, struct file *file) | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | 179 | ||
| 180 | static const struct file_operations m548x_wdt_fops = { | 180 | static const struct file_operations m54xx_wdt_fops = { |
| 181 | .owner = THIS_MODULE, | 181 | .owner = THIS_MODULE, |
| 182 | .llseek = no_llseek, | 182 | .llseek = no_llseek, |
| 183 | .write = m548x_wdt_write, | 183 | .write = m54xx_wdt_write, |
| 184 | .unlocked_ioctl = m548x_wdt_ioctl, | 184 | .unlocked_ioctl = m54xx_wdt_ioctl, |
| 185 | .open = m548x_wdt_open, | 185 | .open = m54xx_wdt_open, |
| 186 | .release = m548x_wdt_release, | 186 | .release = m54xx_wdt_release, |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | static struct miscdevice m548x_wdt_miscdev = { | 189 | static struct miscdevice m54xx_wdt_miscdev = { |
| 190 | .minor = WATCHDOG_MINOR, | 190 | .minor = WATCHDOG_MINOR, |
| 191 | .name = "watchdog", | 191 | .name = "watchdog", |
| 192 | .fops = &m548x_wdt_fops, | 192 | .fops = &m54xx_wdt_fops, |
| 193 | }; | 193 | }; |
| 194 | 194 | ||
| 195 | static int __init m548x_wdt_init(void) | 195 | static int __init m54xx_wdt_init(void) |
| 196 | { | 196 | { |
| 197 | if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, | 197 | if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, |
| 198 | "Coldfire M548x Watchdog")) { | 198 | "Coldfire M54xx Watchdog")) { |
| 199 | printk(KERN_WARNING | 199 | printk(KERN_WARNING |
| 200 | "Coldfire M548x Watchdog : I/O region busy\n"); | 200 | "Coldfire M54xx Watchdog : I/O region busy\n"); |
| 201 | return -EBUSY; | 201 | return -EBUSY; |
| 202 | } | 202 | } |
| 203 | printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); | 203 | printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); |
| 204 | 204 | ||
| 205 | return misc_register(&m548x_wdt_miscdev); | 205 | return misc_register(&m54xx_wdt_miscdev); |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static void __exit m548x_wdt_exit(void) | 208 | static void __exit m54xx_wdt_exit(void) |
| 209 | { | 209 | { |
| 210 | misc_deregister(&m548x_wdt_miscdev); | 210 | misc_deregister(&m54xx_wdt_miscdev); |
| 211 | release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); | 211 | release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | module_init(m548x_wdt_init); | 214 | module_init(m54xx_wdt_init); |
| 215 | module_exit(m548x_wdt_exit); | 215 | module_exit(m54xx_wdt_exit); |
| 216 | 216 | ||
| 217 | MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>"); | 217 | MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>"); |
| 218 | MODULE_DESCRIPTION("Coldfire M548x Watchdog"); | 218 | MODULE_DESCRIPTION("Coldfire M54xx Watchdog"); |
| 219 | 219 | ||
| 220 | module_param(heartbeat, int, 0); | 220 | module_param(heartbeat, int, 0); |
| 221 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); | 221 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index db8c4c4ac88..24177272bcb 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
| @@ -37,11 +37,19 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; | |||
| 37 | #ifdef CONFIG_PM_SLEEP | 37 | #ifdef CONFIG_PM_SLEEP |
| 38 | static int xen_hvm_suspend(void *data) | 38 | static int xen_hvm_suspend(void *data) |
| 39 | { | 39 | { |
| 40 | int err; | ||
| 40 | struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; | 41 | struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; |
| 41 | int *cancelled = data; | 42 | int *cancelled = data; |
| 42 | 43 | ||
| 43 | BUG_ON(!irqs_disabled()); | 44 | BUG_ON(!irqs_disabled()); |
| 44 | 45 | ||
| 46 | err = sysdev_suspend(PMSG_SUSPEND); | ||
| 47 | if (err) { | ||
| 48 | printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n", | ||
| 49 | err); | ||
| 50 | return err; | ||
| 51 | } | ||
| 52 | |||
| 45 | *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); | 53 | *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); |
| 46 | 54 | ||
| 47 | xen_hvm_post_suspend(*cancelled); | 55 | xen_hvm_post_suspend(*cancelled); |
| @@ -53,6 +61,8 @@ static int xen_hvm_suspend(void *data) | |||
| 53 | xen_timer_resume(); | 61 | xen_timer_resume(); |
| 54 | } | 62 | } |
| 55 | 63 | ||
| 64 | sysdev_resume(); | ||
| 65 | |||
| 56 | return 0; | 66 | return 0; |
| 57 | } | 67 | } |
| 58 | 68 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 333a7bb4cb9..4fb8a343153 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -1215,12 +1215,6 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | |||
| 1215 | 1215 | ||
| 1216 | res = __blkdev_get(bdev, mode, 0); | 1216 | res = __blkdev_get(bdev, mode, 0); |
| 1217 | 1217 | ||
| 1218 | /* __blkdev_get() may alter read only status, check it afterwards */ | ||
| 1219 | if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) { | ||
| 1220 | __blkdev_put(bdev, mode, 0); | ||
| 1221 | res = -EACCES; | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | if (whole) { | 1218 | if (whole) { |
| 1225 | /* finish claiming */ | 1219 | /* finish claiming */ |
| 1226 | mutex_lock(&bdev->bd_mutex); | 1220 | mutex_lock(&bdev->bd_mutex); |
| @@ -1298,6 +1292,11 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, | |||
| 1298 | if (err) | 1292 | if (err) |
| 1299 | return ERR_PTR(err); | 1293 | return ERR_PTR(err); |
| 1300 | 1294 | ||
| 1295 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) { | ||
| 1296 | blkdev_put(bdev, mode); | ||
| 1297 | return ERR_PTR(-EACCES); | ||
| 1298 | } | ||
| 1299 | |||
| 1301 | return bdev; | 1300 | return bdev; |
| 1302 | } | 1301 | } |
| 1303 | EXPORT_SYMBOL(blkdev_get_by_path); | 1302 | EXPORT_SYMBOL(blkdev_get_by_path); |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 15b5ca2a260..9c949348510 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -37,6 +37,9 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
| 37 | char *value = NULL; | 37 | char *value = NULL; |
| 38 | struct posix_acl *acl; | 38 | struct posix_acl *acl; |
| 39 | 39 | ||
| 40 | if (!IS_POSIXACL(inode)) | ||
| 41 | return NULL; | ||
| 42 | |||
| 40 | acl = get_cached_acl(inode, type); | 43 | acl = get_cached_acl(inode, type); |
| 41 | if (acl != ACL_NOT_CACHED) | 44 | if (acl != ACL_NOT_CACHED) |
| 42 | return acl; | 45 | return acl; |
| @@ -84,6 +87,9 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, | |||
| 84 | struct posix_acl *acl; | 87 | struct posix_acl *acl; |
| 85 | int ret = 0; | 88 | int ret = 0; |
| 86 | 89 | ||
| 90 | if (!IS_POSIXACL(dentry->d_inode)) | ||
| 91 | return -EOPNOTSUPP; | ||
| 92 | |||
| 87 | acl = btrfs_get_acl(dentry->d_inode, type); | 93 | acl = btrfs_get_acl(dentry->d_inode, type); |
| 88 | 94 | ||
| 89 | if (IS_ERR(acl)) | 95 | if (IS_ERR(acl)) |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index f745287fbf2..4d2110eafe2 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -562,7 +562,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
| 562 | u64 em_len; | 562 | u64 em_len; |
| 563 | u64 em_start; | 563 | u64 em_start; |
| 564 | struct extent_map *em; | 564 | struct extent_map *em; |
| 565 | int ret; | 565 | int ret = -ENOMEM; |
| 566 | u32 *sums; | 566 | u32 *sums; |
| 567 | 567 | ||
| 568 | tree = &BTRFS_I(inode)->io_tree; | 568 | tree = &BTRFS_I(inode)->io_tree; |
| @@ -577,6 +577,9 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
| 577 | 577 | ||
| 578 | compressed_len = em->block_len; | 578 | compressed_len = em->block_len; |
| 579 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); | 579 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); |
| 580 | if (!cb) | ||
| 581 | goto out; | ||
| 582 | |||
| 580 | atomic_set(&cb->pending_bios, 0); | 583 | atomic_set(&cb->pending_bios, 0); |
| 581 | cb->errors = 0; | 584 | cb->errors = 0; |
| 582 | cb->inode = inode; | 585 | cb->inode = inode; |
| @@ -597,13 +600,18 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
| 597 | 600 | ||
| 598 | nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / | 601 | nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / |
| 599 | PAGE_CACHE_SIZE; | 602 | PAGE_CACHE_SIZE; |
| 600 | cb->compressed_pages = kmalloc(sizeof(struct page *) * nr_pages, | 603 | cb->compressed_pages = kzalloc(sizeof(struct page *) * nr_pages, |
| 601 | GFP_NOFS); | 604 | GFP_NOFS); |
| 605 | if (!cb->compressed_pages) | ||
| 606 | goto fail1; | ||
| 607 | |||
| 602 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 608 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; |
| 603 | 609 | ||
| 604 | for (page_index = 0; page_index < nr_pages; page_index++) { | 610 | for (page_index = 0; page_index < nr_pages; page_index++) { |
| 605 | cb->compressed_pages[page_index] = alloc_page(GFP_NOFS | | 611 | cb->compressed_pages[page_index] = alloc_page(GFP_NOFS | |
| 606 | __GFP_HIGHMEM); | 612 | __GFP_HIGHMEM); |
| 613 | if (!cb->compressed_pages[page_index]) | ||
| 614 | goto fail2; | ||
| 607 | } | 615 | } |
| 608 | cb->nr_pages = nr_pages; | 616 | cb->nr_pages = nr_pages; |
| 609 | 617 | ||
| @@ -614,6 +622,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
| 614 | cb->len = uncompressed_len; | 622 | cb->len = uncompressed_len; |
| 615 | 623 | ||
| 616 | comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); | 624 | comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); |
| 625 | if (!comp_bio) | ||
| 626 | goto fail2; | ||
| 617 | comp_bio->bi_private = cb; | 627 | comp_bio->bi_private = cb; |
| 618 | comp_bio->bi_end_io = end_compressed_bio_read; | 628 | comp_bio->bi_end_io = end_compressed_bio_read; |
| 619 | atomic_inc(&cb->pending_bios); | 629 | atomic_inc(&cb->pending_bios); |
| @@ -681,6 +691,17 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
| 681 | 691 | ||
| 682 | bio_put(comp_bio); | 692 | bio_put(comp_bio); |
| 683 | return 0; | 693 | return 0; |
| 694 | |||
| 695 | fail2: | ||
| 696 | for (page_index = 0; page_index < nr_pages; page_index++) | ||
| 697 | free_page((unsigned long)cb->compressed_pages[page_index]); | ||
| 698 | |||
| 699 | kfree(cb->compressed_pages); | ||
| 700 | fail1: | ||
| 701 | kfree(cb); | ||
| 702 | out: | ||
| 703 | free_extent_map(em); | ||
| 704 | return ret; | ||
| 684 | } | 705 | } |
| 685 | 706 | ||
| 686 | static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; | 707 | static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; |
| @@ -900,7 +921,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, | |||
| 900 | return ret; | 921 | return ret; |
| 901 | } | 922 | } |
| 902 | 923 | ||
| 903 | void __exit btrfs_exit_compress(void) | 924 | void btrfs_exit_compress(void) |
| 904 | { | 925 | { |
| 905 | free_workspaces(); | 926 | free_workspaces(); |
| 906 | } | 927 | } |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b531c36455d..e1aa8d607bc 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -359,10 +359,14 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
| 359 | 359 | ||
| 360 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 360 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
| 361 | 361 | ||
| 362 | if (page->private == EXTENT_PAGE_PRIVATE) | 362 | if (page->private == EXTENT_PAGE_PRIVATE) { |
| 363 | WARN_ON(1); | ||
| 363 | goto out; | 364 | goto out; |
| 364 | if (!page->private) | 365 | } |
| 366 | if (!page->private) { | ||
| 367 | WARN_ON(1); | ||
| 365 | goto out; | 368 | goto out; |
| 369 | } | ||
| 366 | len = page->private >> 2; | 370 | len = page->private >> 2; |
| 367 | WARN_ON(len == 0); | 371 | WARN_ON(len == 0); |
| 368 | 372 | ||
| @@ -1550,6 +1554,7 @@ static int transaction_kthread(void *arg) | |||
| 1550 | spin_unlock(&root->fs_info->new_trans_lock); | 1554 | spin_unlock(&root->fs_info->new_trans_lock); |
| 1551 | 1555 | ||
| 1552 | trans = btrfs_join_transaction(root, 1); | 1556 | trans = btrfs_join_transaction(root, 1); |
| 1557 | BUG_ON(IS_ERR(trans)); | ||
| 1553 | if (transid == trans->transid) { | 1558 | if (transid == trans->transid) { |
| 1554 | ret = btrfs_commit_transaction(trans, root); | 1559 | ret = btrfs_commit_transaction(trans, root); |
| 1555 | BUG_ON(ret); | 1560 | BUG_ON(ret); |
| @@ -2453,10 +2458,14 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
| 2453 | up_write(&root->fs_info->cleanup_work_sem); | 2458 | up_write(&root->fs_info->cleanup_work_sem); |
| 2454 | 2459 | ||
| 2455 | trans = btrfs_join_transaction(root, 1); | 2460 | trans = btrfs_join_transaction(root, 1); |
| 2461 | if (IS_ERR(trans)) | ||
| 2462 | return PTR_ERR(trans); | ||
| 2456 | ret = btrfs_commit_transaction(trans, root); | 2463 | ret = btrfs_commit_transaction(trans, root); |
| 2457 | BUG_ON(ret); | 2464 | BUG_ON(ret); |
| 2458 | /* run commit again to drop the original snapshot */ | 2465 | /* run commit again to drop the original snapshot */ |
| 2459 | trans = btrfs_join_transaction(root, 1); | 2466 | trans = btrfs_join_transaction(root, 1); |
| 2467 | if (IS_ERR(trans)) | ||
| 2468 | return PTR_ERR(trans); | ||
| 2460 | btrfs_commit_transaction(trans, root); | 2469 | btrfs_commit_transaction(trans, root); |
| 2461 | ret = btrfs_write_and_wait_transaction(NULL, root); | 2470 | ret = btrfs_write_and_wait_transaction(NULL, root); |
| 2462 | BUG_ON(ret); | 2471 | BUG_ON(ret); |
| @@ -2554,6 +2563,8 @@ int close_ctree(struct btrfs_root *root) | |||
| 2554 | kfree(fs_info->chunk_root); | 2563 | kfree(fs_info->chunk_root); |
| 2555 | kfree(fs_info->dev_root); | 2564 | kfree(fs_info->dev_root); |
| 2556 | kfree(fs_info->csum_root); | 2565 | kfree(fs_info->csum_root); |
| 2566 | kfree(fs_info); | ||
| 2567 | |||
| 2557 | return 0; | 2568 | return 0; |
| 2558 | } | 2569 | } |
| 2559 | 2570 | ||
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 9786963b07e..ff27d7a477b 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -171,6 +171,8 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
| 171 | int ret; | 171 | int ret; |
| 172 | 172 | ||
| 173 | path = btrfs_alloc_path(); | 173 | path = btrfs_alloc_path(); |
| 174 | if (!path) | ||
| 175 | return ERR_PTR(-ENOMEM); | ||
| 174 | 176 | ||
| 175 | if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | 177 | if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) { |
| 176 | key.objectid = root->root_key.objectid; | 178 | key.objectid = root->root_key.objectid; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b55269340ce..f3c96fc0143 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -320,11 +320,6 @@ static int caching_kthread(void *data) | |||
| 320 | if (!path) | 320 | if (!path) |
| 321 | return -ENOMEM; | 321 | return -ENOMEM; |
| 322 | 322 | ||
| 323 | exclude_super_stripes(extent_root, block_group); | ||
| 324 | spin_lock(&block_group->space_info->lock); | ||
| 325 | block_group->space_info->bytes_readonly += block_group->bytes_super; | ||
| 326 | spin_unlock(&block_group->space_info->lock); | ||
| 327 | |||
| 328 | last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); | 323 | last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); |
| 329 | 324 | ||
| 330 | /* | 325 | /* |
| @@ -467,8 +462,10 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
| 467 | cache->cached = BTRFS_CACHE_NO; | 462 | cache->cached = BTRFS_CACHE_NO; |
| 468 | } | 463 | } |
| 469 | spin_unlock(&cache->lock); | 464 | spin_unlock(&cache->lock); |
| 470 | if (ret == 1) | 465 | if (ret == 1) { |
| 466 | free_excluded_extents(fs_info->extent_root, cache); | ||
| 471 | return 0; | 467 | return 0; |
| 468 | } | ||
| 472 | } | 469 | } |
| 473 | 470 | ||
| 474 | if (load_cache_only) | 471 | if (load_cache_only) |
| @@ -3344,8 +3341,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
| 3344 | u64 reserved; | 3341 | u64 reserved; |
| 3345 | u64 max_reclaim; | 3342 | u64 max_reclaim; |
| 3346 | u64 reclaimed = 0; | 3343 | u64 reclaimed = 0; |
| 3344 | long time_left; | ||
| 3347 | int pause = 1; | 3345 | int pause = 1; |
| 3348 | int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; | 3346 | int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; |
| 3347 | int loops = 0; | ||
| 3349 | 3348 | ||
| 3350 | block_rsv = &root->fs_info->delalloc_block_rsv; | 3349 | block_rsv = &root->fs_info->delalloc_block_rsv; |
| 3351 | space_info = block_rsv->space_info; | 3350 | space_info = block_rsv->space_info; |
| @@ -3358,7 +3357,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
| 3358 | 3357 | ||
| 3359 | max_reclaim = min(reserved, to_reclaim); | 3358 | max_reclaim = min(reserved, to_reclaim); |
| 3360 | 3359 | ||
| 3361 | while (1) { | 3360 | while (loops < 1024) { |
| 3362 | /* have the flusher threads jump in and do some IO */ | 3361 | /* have the flusher threads jump in and do some IO */ |
| 3363 | smp_mb(); | 3362 | smp_mb(); |
| 3364 | nr_pages = min_t(unsigned long, nr_pages, | 3363 | nr_pages = min_t(unsigned long, nr_pages, |
| @@ -3366,8 +3365,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
| 3366 | writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); | 3365 | writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); |
| 3367 | 3366 | ||
| 3368 | spin_lock(&space_info->lock); | 3367 | spin_lock(&space_info->lock); |
| 3369 | if (reserved > space_info->bytes_reserved) | 3368 | if (reserved > space_info->bytes_reserved) { |
| 3369 | loops = 0; | ||
| 3370 | reclaimed += reserved - space_info->bytes_reserved; | 3370 | reclaimed += reserved - space_info->bytes_reserved; |
| 3371 | } else { | ||
| 3372 | loops++; | ||
| 3373 | } | ||
| 3371 | reserved = space_info->bytes_reserved; | 3374 | reserved = space_info->bytes_reserved; |
| 3372 | spin_unlock(&space_info->lock); | 3375 | spin_unlock(&space_info->lock); |
| 3373 | 3376 | ||
| @@ -3378,7 +3381,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
| 3378 | return -EAGAIN; | 3381 | return -EAGAIN; |
| 3379 | 3382 | ||
| 3380 | __set_current_state(TASK_INTERRUPTIBLE); | 3383 | __set_current_state(TASK_INTERRUPTIBLE); |
| 3381 | schedule_timeout(pause); | 3384 | time_left = schedule_timeout(pause); |
| 3385 | |||
| 3386 | /* We were interrupted, exit */ | ||
| 3387 | if (time_left) | ||
| 3388 | break; | ||
| 3389 | |||
| 3382 | pause <<= 1; | 3390 | pause <<= 1; |
| 3383 | if (pause > HZ / 10) | 3391 | if (pause > HZ / 10) |
| 3384 | pause = HZ / 10; | 3392 | pause = HZ / 10; |
| @@ -3588,8 +3596,20 @@ void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv, | |||
| 3588 | 3596 | ||
| 3589 | if (num_bytes > 0) { | 3597 | if (num_bytes > 0) { |
| 3590 | if (dest) { | 3598 | if (dest) { |
| 3591 | block_rsv_add_bytes(dest, num_bytes, 0); | 3599 | spin_lock(&dest->lock); |
| 3592 | } else { | 3600 | if (!dest->full) { |
| 3601 | u64 bytes_to_add; | ||
| 3602 | |||
| 3603 | bytes_to_add = dest->size - dest->reserved; | ||
| 3604 | bytes_to_add = min(num_bytes, bytes_to_add); | ||
| 3605 | dest->reserved += bytes_to_add; | ||
| 3606 | if (dest->reserved >= dest->size) | ||
| 3607 | dest->full = 1; | ||
| 3608 | num_bytes -= bytes_to_add; | ||
| 3609 | } | ||
| 3610 | spin_unlock(&dest->lock); | ||
| 3611 | } | ||
| 3612 | if (num_bytes) { | ||
| 3593 | spin_lock(&space_info->lock); | 3613 | spin_lock(&space_info->lock); |
| 3594 | space_info->bytes_reserved -= num_bytes; | 3614 | space_info->bytes_reserved -= num_bytes; |
| 3595 | spin_unlock(&space_info->lock); | 3615 | spin_unlock(&space_info->lock); |
| @@ -4012,6 +4032,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) | |||
| 4012 | 4032 | ||
| 4013 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 4033 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
| 4014 | atomic_dec(&BTRFS_I(inode)->outstanding_extents); | 4034 | atomic_dec(&BTRFS_I(inode)->outstanding_extents); |
| 4035 | WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0); | ||
| 4015 | 4036 | ||
| 4016 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 4037 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
| 4017 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); | 4038 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents); |
| @@ -5633,6 +5654,7 @@ use_block_rsv(struct btrfs_trans_handle *trans, | |||
| 5633 | struct btrfs_root *root, u32 blocksize) | 5654 | struct btrfs_root *root, u32 blocksize) |
| 5634 | { | 5655 | { |
| 5635 | struct btrfs_block_rsv *block_rsv; | 5656 | struct btrfs_block_rsv *block_rsv; |
| 5657 | struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; | ||
| 5636 | int ret; | 5658 | int ret; |
| 5637 | 5659 | ||
| 5638 | block_rsv = get_block_rsv(trans, root); | 5660 | block_rsv = get_block_rsv(trans, root); |
| @@ -5640,14 +5662,39 @@ use_block_rsv(struct btrfs_trans_handle *trans, | |||
| 5640 | if (block_rsv->size == 0) { | 5662 | if (block_rsv->size == 0) { |
| 5641 | ret = reserve_metadata_bytes(trans, root, block_rsv, | 5663 | ret = reserve_metadata_bytes(trans, root, block_rsv, |
| 5642 | blocksize, 0); | 5664 | blocksize, 0); |
| 5643 | if (ret) | 5665 | /* |
| 5666 | * If we couldn't reserve metadata bytes try and use some from | ||
| 5667 | * the global reserve. | ||
| 5668 | */ | ||
| 5669 | if (ret && block_rsv != global_rsv) { | ||
| 5670 | ret = block_rsv_use_bytes(global_rsv, blocksize); | ||
| 5671 | if (!ret) | ||
| 5672 | return global_rsv; | ||
| 5673 | return ERR_PTR(ret); | ||
| 5674 | } else if (ret) { | ||
| 5644 | return ERR_PTR(ret); | 5675 | return ERR_PTR(ret); |
| 5676 | } | ||
| 5645 | return block_rsv; | 5677 | return block_rsv; |
| 5646 | } | 5678 | } |
| 5647 | 5679 | ||
| 5648 | ret = block_rsv_use_bytes(block_rsv, blocksize); | 5680 | ret = block_rsv_use_bytes(block_rsv, blocksize); |
| 5649 | if (!ret) | 5681 | if (!ret) |
| 5650 | return block_rsv; | 5682 | return block_rsv; |
| 5683 | if (ret) { | ||
| 5684 | WARN_ON(1); | ||
| 5685 | ret = reserve_metadata_bytes(trans, root, block_rsv, blocksize, | ||
| 5686 | 0); | ||
| 5687 | if (!ret) { | ||
| 5688 | spin_lock(&block_rsv->lock); | ||
| 5689 | block_rsv->size += blocksize; | ||
| 5690 | spin_unlock(&block_rsv->lock); | ||
| 5691 | return block_rsv; | ||
| 5692 | } else if (ret && block_rsv != global_rsv) { | ||
| 5693 | ret = block_rsv_use_bytes(global_rsv, blocksize); | ||
| 5694 | if (!ret) | ||
| 5695 | return global_rsv; | ||
| 5696 | } | ||
| 5697 | } | ||
| 5651 | 5698 | ||
| 5652 | return ERR_PTR(-ENOSPC); | 5699 | return ERR_PTR(-ENOSPC); |
| 5653 | } | 5700 | } |
| @@ -6221,6 +6268,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
| 6221 | BUG_ON(!wc); | 6268 | BUG_ON(!wc); |
| 6222 | 6269 | ||
| 6223 | trans = btrfs_start_transaction(tree_root, 0); | 6270 | trans = btrfs_start_transaction(tree_root, 0); |
| 6271 | BUG_ON(IS_ERR(trans)); | ||
| 6272 | |||
| 6224 | if (block_rsv) | 6273 | if (block_rsv) |
| 6225 | trans->block_rsv = block_rsv; | 6274 | trans->block_rsv = block_rsv; |
| 6226 | 6275 | ||
| @@ -6318,6 +6367,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
| 6318 | 6367 | ||
| 6319 | btrfs_end_transaction_throttle(trans, tree_root); | 6368 | btrfs_end_transaction_throttle(trans, tree_root); |
| 6320 | trans = btrfs_start_transaction(tree_root, 0); | 6369 | trans = btrfs_start_transaction(tree_root, 0); |
| 6370 | BUG_ON(IS_ERR(trans)); | ||
| 6321 | if (block_rsv) | 6371 | if (block_rsv) |
| 6322 | trans->block_rsv = block_rsv; | 6372 | trans->block_rsv = block_rsv; |
| 6323 | } | 6373 | } |
| @@ -6446,6 +6496,8 @@ static noinline int relocate_inode_pages(struct inode *inode, u64 start, | |||
| 6446 | int ret = 0; | 6496 | int ret = 0; |
| 6447 | 6497 | ||
| 6448 | ra = kzalloc(sizeof(*ra), GFP_NOFS); | 6498 | ra = kzalloc(sizeof(*ra), GFP_NOFS); |
| 6499 | if (!ra) | ||
| 6500 | return -ENOMEM; | ||
| 6449 | 6501 | ||
| 6450 | mutex_lock(&inode->i_mutex); | 6502 | mutex_lock(&inode->i_mutex); |
| 6451 | first_index = start >> PAGE_CACHE_SHIFT; | 6503 | first_index = start >> PAGE_CACHE_SHIFT; |
| @@ -6531,7 +6583,7 @@ static noinline int relocate_data_extent(struct inode *reloc_inode, | |||
| 6531 | u64 end = start + extent_key->offset - 1; | 6583 | u64 end = start + extent_key->offset - 1; |
| 6532 | 6584 | ||
| 6533 | em = alloc_extent_map(GFP_NOFS); | 6585 | em = alloc_extent_map(GFP_NOFS); |
| 6534 | BUG_ON(!em || IS_ERR(em)); | 6586 | BUG_ON(!em); |
| 6535 | 6587 | ||
| 6536 | em->start = start; | 6588 | em->start = start; |
| 6537 | em->len = extent_key->offset; | 6589 | em->len = extent_key->offset; |
| @@ -7477,7 +7529,7 @@ int btrfs_drop_dead_reloc_roots(struct btrfs_root *root) | |||
| 7477 | BUG_ON(reloc_root->commit_root != NULL); | 7529 | BUG_ON(reloc_root->commit_root != NULL); |
| 7478 | while (1) { | 7530 | while (1) { |
| 7479 | trans = btrfs_join_transaction(root, 1); | 7531 | trans = btrfs_join_transaction(root, 1); |
| 7480 | BUG_ON(!trans); | 7532 | BUG_ON(IS_ERR(trans)); |
| 7481 | 7533 | ||
| 7482 | mutex_lock(&root->fs_info->drop_mutex); | 7534 | mutex_lock(&root->fs_info->drop_mutex); |
| 7483 | ret = btrfs_drop_snapshot(trans, reloc_root); | 7535 | ret = btrfs_drop_snapshot(trans, reloc_root); |
| @@ -7535,7 +7587,7 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root) | |||
| 7535 | 7587 | ||
| 7536 | if (found) { | 7588 | if (found) { |
| 7537 | trans = btrfs_start_transaction(root, 1); | 7589 | trans = btrfs_start_transaction(root, 1); |
| 7538 | BUG_ON(!trans); | 7590 | BUG_ON(IS_ERR(trans)); |
| 7539 | ret = btrfs_commit_transaction(trans, root); | 7591 | ret = btrfs_commit_transaction(trans, root); |
| 7540 | BUG_ON(ret); | 7592 | BUG_ON(ret); |
| 7541 | } | 7593 | } |
| @@ -7779,7 +7831,7 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, | |||
| 7779 | 7831 | ||
| 7780 | 7832 | ||
| 7781 | trans = btrfs_start_transaction(extent_root, 1); | 7833 | trans = btrfs_start_transaction(extent_root, 1); |
| 7782 | BUG_ON(!trans); | 7834 | BUG_ON(IS_ERR(trans)); |
| 7783 | 7835 | ||
| 7784 | if (extent_key->objectid == 0) { | 7836 | if (extent_key->objectid == 0) { |
| 7785 | ret = del_extent_zero(trans, extent_root, path, extent_key); | 7837 | ret = del_extent_zero(trans, extent_root, path, extent_key); |
| @@ -8270,6 +8322,13 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
| 8270 | if (block_group->cached == BTRFS_CACHE_STARTED) | 8322 | if (block_group->cached == BTRFS_CACHE_STARTED) |
| 8271 | wait_block_group_cache_done(block_group); | 8323 | wait_block_group_cache_done(block_group); |
| 8272 | 8324 | ||
| 8325 | /* | ||
| 8326 | * We haven't cached this block group, which means we could | ||
| 8327 | * possibly have excluded extents on this block group. | ||
| 8328 | */ | ||
| 8329 | if (block_group->cached == BTRFS_CACHE_NO) | ||
| 8330 | free_excluded_extents(info->extent_root, block_group); | ||
| 8331 | |||
| 8273 | btrfs_remove_free_space_cache(block_group); | 8332 | btrfs_remove_free_space_cache(block_group); |
| 8274 | btrfs_put_block_group(block_group); | 8333 | btrfs_put_block_group(block_group); |
| 8275 | 8334 | ||
| @@ -8385,6 +8444,13 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 8385 | cache->sectorsize = root->sectorsize; | 8444 | cache->sectorsize = root->sectorsize; |
| 8386 | 8445 | ||
| 8387 | /* | 8446 | /* |
| 8447 | * We need to exclude the super stripes now so that the space | ||
| 8448 | * info has super bytes accounted for, otherwise we'll think | ||
| 8449 | * we have more space than we actually do. | ||
| 8450 | */ | ||
| 8451 | exclude_super_stripes(root, cache); | ||
| 8452 | |||
| 8453 | /* | ||
| 8388 | * check for two cases, either we are full, and therefore | 8454 | * check for two cases, either we are full, and therefore |
| 8389 | * don't need to bother with the caching work since we won't | 8455 | * don't need to bother with the caching work since we won't |
| 8390 | * find any space, or we are empty, and we can just add all | 8456 | * find any space, or we are empty, and we can just add all |
| @@ -8392,12 +8458,10 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 8392 | * time, particularly in the full case. | 8458 | * time, particularly in the full case. |
| 8393 | */ | 8459 | */ |
| 8394 | if (found_key.offset == btrfs_block_group_used(&cache->item)) { | 8460 | if (found_key.offset == btrfs_block_group_used(&cache->item)) { |
| 8395 | exclude_super_stripes(root, cache); | ||
| 8396 | cache->last_byte_to_unpin = (u64)-1; | 8461 | cache->last_byte_to_unpin = (u64)-1; |
| 8397 | cache->cached = BTRFS_CACHE_FINISHED; | 8462 | cache->cached = BTRFS_CACHE_FINISHED; |
| 8398 | free_excluded_extents(root, cache); | 8463 | free_excluded_extents(root, cache); |
| 8399 | } else if (btrfs_block_group_used(&cache->item) == 0) { | 8464 | } else if (btrfs_block_group_used(&cache->item) == 0) { |
| 8400 | exclude_super_stripes(root, cache); | ||
| 8401 | cache->last_byte_to_unpin = (u64)-1; | 8465 | cache->last_byte_to_unpin = (u64)-1; |
| 8402 | cache->cached = BTRFS_CACHE_FINISHED; | 8466 | cache->cached = BTRFS_CACHE_FINISHED; |
| 8403 | add_new_free_space(cache, root->fs_info, | 8467 | add_new_free_space(cache, root->fs_info, |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2e993cf1766..92ac5192c51 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -1865,7 +1865,7 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num, | |||
| 1865 | bio_get(bio); | 1865 | bio_get(bio); |
| 1866 | 1866 | ||
| 1867 | if (tree->ops && tree->ops->submit_bio_hook) | 1867 | if (tree->ops && tree->ops->submit_bio_hook) |
| 1868 | tree->ops->submit_bio_hook(page->mapping->host, rw, bio, | 1868 | ret = tree->ops->submit_bio_hook(page->mapping->host, rw, bio, |
| 1869 | mirror_num, bio_flags, start); | 1869 | mirror_num, bio_flags, start); |
| 1870 | else | 1870 | else |
| 1871 | submit_bio(rw, bio); | 1871 | submit_bio(rw, bio); |
| @@ -1920,6 +1920,8 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, | |||
| 1920 | nr = bio_get_nr_vecs(bdev); | 1920 | nr = bio_get_nr_vecs(bdev); |
| 1921 | 1921 | ||
| 1922 | bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); | 1922 | bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); |
| 1923 | if (!bio) | ||
| 1924 | return -ENOMEM; | ||
| 1923 | 1925 | ||
| 1924 | bio_add_page(bio, page, page_size, offset); | 1926 | bio_add_page(bio, page, page_size, offset); |
| 1925 | bio->bi_end_io = end_io_func; | 1927 | bio->bi_end_io = end_io_func; |
| @@ -1944,6 +1946,7 @@ void set_page_extent_mapped(struct page *page) | |||
| 1944 | 1946 | ||
| 1945 | static void set_page_extent_head(struct page *page, unsigned long len) | 1947 | static void set_page_extent_head(struct page *page, unsigned long len) |
| 1946 | { | 1948 | { |
| 1949 | WARN_ON(!PagePrivate(page)); | ||
| 1947 | set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); | 1950 | set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); |
| 1948 | } | 1951 | } |
| 1949 | 1952 | ||
| @@ -2126,7 +2129,7 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page, | |||
| 2126 | ret = __extent_read_full_page(tree, page, get_extent, &bio, 0, | 2129 | ret = __extent_read_full_page(tree, page, get_extent, &bio, 0, |
| 2127 | &bio_flags); | 2130 | &bio_flags); |
| 2128 | if (bio) | 2131 | if (bio) |
| 2129 | submit_one_bio(READ, bio, 0, bio_flags); | 2132 | ret = submit_one_bio(READ, bio, 0, bio_flags); |
| 2130 | return ret; | 2133 | return ret; |
| 2131 | } | 2134 | } |
| 2132 | 2135 | ||
| @@ -2819,9 +2822,17 @@ int try_release_extent_state(struct extent_map_tree *map, | |||
| 2819 | * at this point we can safely clear everything except the | 2822 | * at this point we can safely clear everything except the |
| 2820 | * locked bit and the nodatasum bit | 2823 | * locked bit and the nodatasum bit |
| 2821 | */ | 2824 | */ |
| 2822 | clear_extent_bit(tree, start, end, | 2825 | ret = clear_extent_bit(tree, start, end, |
| 2823 | ~(EXTENT_LOCKED | EXTENT_NODATASUM), | 2826 | ~(EXTENT_LOCKED | EXTENT_NODATASUM), |
| 2824 | 0, 0, NULL, mask); | 2827 | 0, 0, NULL, mask); |
| 2828 | |||
| 2829 | /* if clear_extent_bit failed for enomem reasons, | ||
| 2830 | * we can't allow the release to continue. | ||
| 2831 | */ | ||
| 2832 | if (ret < 0) | ||
| 2833 | ret = 0; | ||
| 2834 | else | ||
| 2835 | ret = 1; | ||
| 2825 | } | 2836 | } |
| 2826 | return ret; | 2837 | return ret; |
| 2827 | } | 2838 | } |
| @@ -3192,7 +3203,13 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 3192 | } | 3203 | } |
| 3193 | if (!PageUptodate(p)) | 3204 | if (!PageUptodate(p)) |
| 3194 | uptodate = 0; | 3205 | uptodate = 0; |
| 3195 | unlock_page(p); | 3206 | |
| 3207 | /* | ||
| 3208 | * see below about how we avoid a nasty race with release page | ||
| 3209 | * and why we unlock later | ||
| 3210 | */ | ||
| 3211 | if (i != 0) | ||
| 3212 | unlock_page(p); | ||
| 3196 | } | 3213 | } |
| 3197 | if (uptodate) | 3214 | if (uptodate) |
| 3198 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); | 3215 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
| @@ -3216,9 +3233,26 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 3216 | atomic_inc(&eb->refs); | 3233 | atomic_inc(&eb->refs); |
| 3217 | spin_unlock(&tree->buffer_lock); | 3234 | spin_unlock(&tree->buffer_lock); |
| 3218 | radix_tree_preload_end(); | 3235 | radix_tree_preload_end(); |
| 3236 | |||
| 3237 | /* | ||
| 3238 | * there is a race where release page may have | ||
| 3239 | * tried to find this extent buffer in the radix | ||
| 3240 | * but failed. It will tell the VM it is safe to | ||
| 3241 | * reclaim the, and it will clear the page private bit. | ||
| 3242 | * We must make sure to set the page private bit properly | ||
| 3243 | * after the extent buffer is in the radix tree so | ||
| 3244 | * it doesn't get lost | ||
| 3245 | */ | ||
| 3246 | set_page_extent_mapped(eb->first_page); | ||
| 3247 | set_page_extent_head(eb->first_page, eb->len); | ||
| 3248 | if (!page0) | ||
| 3249 | unlock_page(eb->first_page); | ||
| 3219 | return eb; | 3250 | return eb; |
| 3220 | 3251 | ||
| 3221 | free_eb: | 3252 | free_eb: |
| 3253 | if (eb->first_page && !page0) | ||
| 3254 | unlock_page(eb->first_page); | ||
| 3255 | |||
| 3222 | if (!atomic_dec_and_test(&eb->refs)) | 3256 | if (!atomic_dec_and_test(&eb->refs)) |
| 3223 | return exists; | 3257 | return exists; |
| 3224 | btrfs_release_extent_buffer(eb); | 3258 | btrfs_release_extent_buffer(eb); |
| @@ -3269,10 +3303,11 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree, | |||
| 3269 | continue; | 3303 | continue; |
| 3270 | 3304 | ||
| 3271 | lock_page(page); | 3305 | lock_page(page); |
| 3306 | WARN_ON(!PagePrivate(page)); | ||
| 3307 | |||
| 3308 | set_page_extent_mapped(page); | ||
| 3272 | if (i == 0) | 3309 | if (i == 0) |
| 3273 | set_page_extent_head(page, eb->len); | 3310 | set_page_extent_head(page, eb->len); |
| 3274 | else | ||
| 3275 | set_page_private(page, EXTENT_PAGE_PRIVATE); | ||
| 3276 | 3311 | ||
| 3277 | clear_page_dirty_for_io(page); | 3312 | clear_page_dirty_for_io(page); |
| 3278 | spin_lock_irq(&page->mapping->tree_lock); | 3313 | spin_lock_irq(&page->mapping->tree_lock); |
| @@ -3462,6 +3497,13 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, | |||
| 3462 | 3497 | ||
| 3463 | for (i = start_i; i < num_pages; i++) { | 3498 | for (i = start_i; i < num_pages; i++) { |
| 3464 | page = extent_buffer_page(eb, i); | 3499 | page = extent_buffer_page(eb, i); |
| 3500 | |||
| 3501 | WARN_ON(!PagePrivate(page)); | ||
| 3502 | |||
| 3503 | set_page_extent_mapped(page); | ||
| 3504 | if (i == 0) | ||
| 3505 | set_page_extent_head(page, eb->len); | ||
| 3506 | |||
| 3465 | if (inc_all_pages) | 3507 | if (inc_all_pages) |
| 3466 | page_cache_get(page); | 3508 | page_cache_get(page); |
| 3467 | if (!PageUptodate(page)) { | 3509 | if (!PageUptodate(page)) { |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index b0e1fce1253..2b6c12e983b 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -51,8 +51,8 @@ struct extent_map *alloc_extent_map(gfp_t mask) | |||
| 51 | { | 51 | { |
| 52 | struct extent_map *em; | 52 | struct extent_map *em; |
| 53 | em = kmem_cache_alloc(extent_map_cache, mask); | 53 | em = kmem_cache_alloc(extent_map_cache, mask); |
| 54 | if (!em || IS_ERR(em)) | 54 | if (!em) |
| 55 | return em; | 55 | return NULL; |
| 56 | em->in_tree = 0; | 56 | em->in_tree = 0; |
| 57 | em->flags = 0; | 57 | em->flags = 0; |
| 58 | em->compress_type = BTRFS_COMPRESS_NONE; | 58 | em->compress_type = BTRFS_COMPRESS_NONE; |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index a562a250ae7..4f19a3e1bf3 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
| @@ -536,6 +536,8 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
| 536 | root = root->fs_info->csum_root; | 536 | root = root->fs_info->csum_root; |
| 537 | 537 | ||
| 538 | path = btrfs_alloc_path(); | 538 | path = btrfs_alloc_path(); |
| 539 | if (!path) | ||
| 540 | return -ENOMEM; | ||
| 539 | 541 | ||
| 540 | while (1) { | 542 | while (1) { |
| 541 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; | 543 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; |
| @@ -548,7 +550,10 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
| 548 | if (path->slots[0] == 0) | 550 | if (path->slots[0] == 0) |
| 549 | goto out; | 551 | goto out; |
| 550 | path->slots[0]--; | 552 | path->slots[0]--; |
| 553 | } else if (ret < 0) { | ||
| 554 | goto out; | ||
| 551 | } | 555 | } |
| 556 | |||
| 552 | leaf = path->nodes[0]; | 557 | leaf = path->nodes[0]; |
| 553 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | 558 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
| 554 | 559 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c800d58f301..7084140d594 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -186,6 +186,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 186 | split = alloc_extent_map(GFP_NOFS); | 186 | split = alloc_extent_map(GFP_NOFS); |
| 187 | if (!split2) | 187 | if (!split2) |
| 188 | split2 = alloc_extent_map(GFP_NOFS); | 188 | split2 = alloc_extent_map(GFP_NOFS); |
| 189 | BUG_ON(!split || !split2); | ||
| 189 | 190 | ||
| 190 | write_lock(&em_tree->lock); | 191 | write_lock(&em_tree->lock); |
| 191 | em = lookup_extent_mapping(em_tree, start, len); | 192 | em = lookup_extent_mapping(em_tree, start, len); |
| @@ -793,8 +794,12 @@ again: | |||
| 793 | for (i = 0; i < num_pages; i++) { | 794 | for (i = 0; i < num_pages; i++) { |
| 794 | pages[i] = grab_cache_page(inode->i_mapping, index + i); | 795 | pages[i] = grab_cache_page(inode->i_mapping, index + i); |
| 795 | if (!pages[i]) { | 796 | if (!pages[i]) { |
| 796 | err = -ENOMEM; | 797 | int c; |
| 797 | BUG_ON(1); | 798 | for (c = i - 1; c >= 0; c--) { |
| 799 | unlock_page(pages[c]); | ||
| 800 | page_cache_release(pages[c]); | ||
| 801 | } | ||
| 802 | return -ENOMEM; | ||
| 798 | } | 803 | } |
| 799 | wait_on_page_writeback(pages[i]); | 804 | wait_on_page_writeback(pages[i]); |
| 800 | } | 805 | } |
| @@ -946,6 +951,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 946 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / | 951 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / |
| 947 | (sizeof(struct page *))); | 952 | (sizeof(struct page *))); |
| 948 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); | 953 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); |
| 954 | if (!pages) { | ||
| 955 | ret = -ENOMEM; | ||
| 956 | goto out; | ||
| 957 | } | ||
| 949 | 958 | ||
| 950 | /* generic_write_checks can change our pos */ | 959 | /* generic_write_checks can change our pos */ |
| 951 | start_pos = pos; | 960 | start_pos = pos; |
| @@ -984,8 +993,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 984 | size_t write_bytes = min(iov_iter_count(&i), | 993 | size_t write_bytes = min(iov_iter_count(&i), |
| 985 | nrptrs * (size_t)PAGE_CACHE_SIZE - | 994 | nrptrs * (size_t)PAGE_CACHE_SIZE - |
| 986 | offset); | 995 | offset); |
| 987 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> | 996 | size_t num_pages = (write_bytes + offset + |
| 988 | PAGE_CACHE_SHIFT; | 997 | PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
| 989 | 998 | ||
| 990 | WARN_ON(num_pages > nrptrs); | 999 | WARN_ON(num_pages > nrptrs); |
| 991 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 1000 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
| @@ -1015,8 +1024,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 1015 | 1024 | ||
| 1016 | copied = btrfs_copy_from_user(pos, num_pages, | 1025 | copied = btrfs_copy_from_user(pos, num_pages, |
| 1017 | write_bytes, pages, &i); | 1026 | write_bytes, pages, &i); |
| 1018 | dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> | 1027 | dirty_pages = (copied + offset + PAGE_CACHE_SIZE - 1) >> |
| 1019 | PAGE_CACHE_SHIFT; | 1028 | PAGE_CACHE_SHIFT; |
| 1020 | 1029 | ||
| 1021 | if (num_pages > dirty_pages) { | 1030 | if (num_pages > dirty_pages) { |
| 1022 | if (copied > 0) | 1031 | if (copied > 0) |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 60d68426695..a0390657451 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -987,11 +987,18 @@ tree_search_offset(struct btrfs_block_group_cache *block_group, | |||
| 987 | return entry; | 987 | return entry; |
| 988 | } | 988 | } |
| 989 | 989 | ||
| 990 | static void unlink_free_space(struct btrfs_block_group_cache *block_group, | 990 | static inline void |
| 991 | struct btrfs_free_space *info) | 991 | __unlink_free_space(struct btrfs_block_group_cache *block_group, |
| 992 | struct btrfs_free_space *info) | ||
| 992 | { | 993 | { |
| 993 | rb_erase(&info->offset_index, &block_group->free_space_offset); | 994 | rb_erase(&info->offset_index, &block_group->free_space_offset); |
| 994 | block_group->free_extents--; | 995 | block_group->free_extents--; |
| 996 | } | ||
| 997 | |||
| 998 | static void unlink_free_space(struct btrfs_block_group_cache *block_group, | ||
| 999 | struct btrfs_free_space *info) | ||
| 1000 | { | ||
| 1001 | __unlink_free_space(block_group, info); | ||
| 995 | block_group->free_space -= info->bytes; | 1002 | block_group->free_space -= info->bytes; |
| 996 | } | 1003 | } |
| 997 | 1004 | ||
| @@ -1016,14 +1023,18 @@ static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) | |||
| 1016 | u64 max_bytes; | 1023 | u64 max_bytes; |
| 1017 | u64 bitmap_bytes; | 1024 | u64 bitmap_bytes; |
| 1018 | u64 extent_bytes; | 1025 | u64 extent_bytes; |
| 1026 | u64 size = block_group->key.offset; | ||
| 1019 | 1027 | ||
| 1020 | /* | 1028 | /* |
| 1021 | * The goal is to keep the total amount of memory used per 1gb of space | 1029 | * The goal is to keep the total amount of memory used per 1gb of space |
| 1022 | * at or below 32k, so we need to adjust how much memory we allow to be | 1030 | * at or below 32k, so we need to adjust how much memory we allow to be |
| 1023 | * used by extent based free space tracking | 1031 | * used by extent based free space tracking |
| 1024 | */ | 1032 | */ |
| 1025 | max_bytes = MAX_CACHE_BYTES_PER_GIG * | 1033 | if (size < 1024 * 1024 * 1024) |
| 1026 | (div64_u64(block_group->key.offset, 1024 * 1024 * 1024)); | 1034 | max_bytes = MAX_CACHE_BYTES_PER_GIG; |
| 1035 | else | ||
| 1036 | max_bytes = MAX_CACHE_BYTES_PER_GIG * | ||
| 1037 | div64_u64(size, 1024 * 1024 * 1024); | ||
| 1027 | 1038 | ||
| 1028 | /* | 1039 | /* |
| 1029 | * we want to account for 1 more bitmap than what we have so we can make | 1040 | * we want to account for 1 more bitmap than what we have so we can make |
| @@ -1171,6 +1182,16 @@ static void add_new_bitmap(struct btrfs_block_group_cache *block_group, | |||
| 1171 | recalculate_thresholds(block_group); | 1182 | recalculate_thresholds(block_group); |
| 1172 | } | 1183 | } |
| 1173 | 1184 | ||
| 1185 | static void free_bitmap(struct btrfs_block_group_cache *block_group, | ||
| 1186 | struct btrfs_free_space *bitmap_info) | ||
| 1187 | { | ||
| 1188 | unlink_free_space(block_group, bitmap_info); | ||
| 1189 | kfree(bitmap_info->bitmap); | ||
| 1190 | kfree(bitmap_info); | ||
| 1191 | block_group->total_bitmaps--; | ||
| 1192 | recalculate_thresholds(block_group); | ||
| 1193 | } | ||
| 1194 | |||
| 1174 | static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_group, | 1195 | static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_group, |
| 1175 | struct btrfs_free_space *bitmap_info, | 1196 | struct btrfs_free_space *bitmap_info, |
| 1176 | u64 *offset, u64 *bytes) | 1197 | u64 *offset, u64 *bytes) |
| @@ -1195,6 +1216,7 @@ again: | |||
| 1195 | */ | 1216 | */ |
| 1196 | search_start = *offset; | 1217 | search_start = *offset; |
| 1197 | search_bytes = *bytes; | 1218 | search_bytes = *bytes; |
| 1219 | search_bytes = min(search_bytes, end - search_start + 1); | ||
| 1198 | ret = search_bitmap(block_group, bitmap_info, &search_start, | 1220 | ret = search_bitmap(block_group, bitmap_info, &search_start, |
| 1199 | &search_bytes); | 1221 | &search_bytes); |
| 1200 | BUG_ON(ret < 0 || search_start != *offset); | 1222 | BUG_ON(ret < 0 || search_start != *offset); |
| @@ -1211,13 +1233,8 @@ again: | |||
| 1211 | 1233 | ||
| 1212 | if (*bytes) { | 1234 | if (*bytes) { |
| 1213 | struct rb_node *next = rb_next(&bitmap_info->offset_index); | 1235 | struct rb_node *next = rb_next(&bitmap_info->offset_index); |
| 1214 | if (!bitmap_info->bytes) { | 1236 | if (!bitmap_info->bytes) |
| 1215 | unlink_free_space(block_group, bitmap_info); | 1237 | free_bitmap(block_group, bitmap_info); |
| 1216 | kfree(bitmap_info->bitmap); | ||
| 1217 | kfree(bitmap_info); | ||
| 1218 | block_group->total_bitmaps--; | ||
| 1219 | recalculate_thresholds(block_group); | ||
| 1220 | } | ||
| 1221 | 1238 | ||
| 1222 | /* | 1239 | /* |
| 1223 | * no entry after this bitmap, but we still have bytes to | 1240 | * no entry after this bitmap, but we still have bytes to |
| @@ -1250,13 +1267,8 @@ again: | |||
| 1250 | return -EAGAIN; | 1267 | return -EAGAIN; |
| 1251 | 1268 | ||
| 1252 | goto again; | 1269 | goto again; |
| 1253 | } else if (!bitmap_info->bytes) { | 1270 | } else if (!bitmap_info->bytes) |
| 1254 | unlink_free_space(block_group, bitmap_info); | 1271 | free_bitmap(block_group, bitmap_info); |
| 1255 | kfree(bitmap_info->bitmap); | ||
| 1256 | kfree(bitmap_info); | ||
| 1257 | block_group->total_bitmaps--; | ||
| 1258 | recalculate_thresholds(block_group); | ||
| 1259 | } | ||
| 1260 | 1272 | ||
| 1261 | return 0; | 1273 | return 0; |
| 1262 | } | 1274 | } |
| @@ -1359,22 +1371,14 @@ out: | |||
| 1359 | return ret; | 1371 | return ret; |
| 1360 | } | 1372 | } |
| 1361 | 1373 | ||
| 1362 | int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, | 1374 | bool try_merge_free_space(struct btrfs_block_group_cache *block_group, |
| 1363 | u64 offset, u64 bytes) | 1375 | struct btrfs_free_space *info, bool update_stat) |
| 1364 | { | 1376 | { |
| 1365 | struct btrfs_free_space *right_info = NULL; | 1377 | struct btrfs_free_space *left_info; |
| 1366 | struct btrfs_free_space *left_info = NULL; | 1378 | struct btrfs_free_space *right_info; |
| 1367 | struct btrfs_free_space *info = NULL; | 1379 | bool merged = false; |
| 1368 | int ret = 0; | 1380 | u64 offset = info->offset; |
| 1369 | 1381 | u64 bytes = info->bytes; | |
| 1370 | info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); | ||
| 1371 | if (!info) | ||
| 1372 | return -ENOMEM; | ||
| 1373 | |||
| 1374 | info->offset = offset; | ||
| 1375 | info->bytes = bytes; | ||
| 1376 | |||
| 1377 | spin_lock(&block_group->tree_lock); | ||
| 1378 | 1382 | ||
| 1379 | /* | 1383 | /* |
| 1380 | * first we want to see if there is free space adjacent to the range we | 1384 | * first we want to see if there is free space adjacent to the range we |
| @@ -1388,37 +1392,62 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, | |||
| 1388 | else | 1392 | else |
| 1389 | left_info = tree_search_offset(block_group, offset - 1, 0, 0); | 1393 | left_info = tree_search_offset(block_group, offset - 1, 0, 0); |
| 1390 | 1394 | ||
| 1391 | /* | ||
| 1392 | * If there was no extent directly to the left or right of this new | ||
| 1393 | * extent then we know we're going to have to allocate a new extent, so | ||
| 1394 | * before we do that see if we need to drop this into a bitmap | ||
| 1395 | */ | ||
| 1396 | if ((!left_info || left_info->bitmap) && | ||
| 1397 | (!right_info || right_info->bitmap)) { | ||
| 1398 | ret = insert_into_bitmap(block_group, info); | ||
| 1399 | |||
| 1400 | if (ret < 0) { | ||
| 1401 | goto out; | ||
| 1402 | } else if (ret) { | ||
| 1403 | ret = 0; | ||
| 1404 | goto out; | ||
| 1405 | } | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | if (right_info && !right_info->bitmap) { | 1395 | if (right_info && !right_info->bitmap) { |
| 1409 | unlink_free_space(block_group, right_info); | 1396 | if (update_stat) |
| 1397 | unlink_free_space(block_group, right_info); | ||
| 1398 | else | ||
| 1399 | __unlink_free_space(block_group, right_info); | ||
| 1410 | info->bytes += right_info->bytes; | 1400 | info->bytes += right_info->bytes; |
| 1411 | kfree(right_info); | 1401 | kfree(right_info); |
| 1402 | merged = true; | ||
| 1412 | } | 1403 | } |
| 1413 | 1404 | ||
| 1414 | if (left_info && !left_info->bitmap && | 1405 | if (left_info && !left_info->bitmap && |
| 1415 | left_info->offset + left_info->bytes == offset) { | 1406 | left_info->offset + left_info->bytes == offset) { |
| 1416 | unlink_free_space(block_group, left_info); | 1407 | if (update_stat) |
| 1408 | unlink_free_space(block_group, left_info); | ||
| 1409 | else | ||
| 1410 | __unlink_free_space(block_group, left_info); | ||
| 1417 | info->offset = left_info->offset; | 1411 | info->offset = left_info->offset; |
| 1418 | info->bytes += left_info->bytes; | 1412 | info->bytes += left_info->bytes; |
| 1419 | kfree(left_info); | 1413 | kfree(left_info); |
| 1414 | merged = true; | ||
| 1420 | } | 1415 | } |
| 1421 | 1416 | ||
| 1417 | return merged; | ||
| 1418 | } | ||
| 1419 | |||
| 1420 | int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, | ||
| 1421 | u64 offset, u64 bytes) | ||
| 1422 | { | ||
| 1423 | struct btrfs_free_space *info; | ||
| 1424 | int ret = 0; | ||
| 1425 | |||
| 1426 | info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); | ||
| 1427 | if (!info) | ||
| 1428 | return -ENOMEM; | ||
| 1429 | |||
| 1430 | info->offset = offset; | ||
| 1431 | info->bytes = bytes; | ||
| 1432 | |||
| 1433 | spin_lock(&block_group->tree_lock); | ||
| 1434 | |||
| 1435 | if (try_merge_free_space(block_group, info, true)) | ||
| 1436 | goto link; | ||
| 1437 | |||
| 1438 | /* | ||
| 1439 | * There was no extent directly to the left or right of this new | ||
| 1440 | * extent then we know we're going to have to allocate a new extent, so | ||
| 1441 | * before we do that see if we need to drop this into a bitmap | ||
| 1442 | */ | ||
| 1443 | ret = insert_into_bitmap(block_group, info); | ||
| 1444 | if (ret < 0) { | ||
| 1445 | goto out; | ||
| 1446 | } else if (ret) { | ||
| 1447 | ret = 0; | ||
| 1448 | goto out; | ||
| 1449 | } | ||
| 1450 | link: | ||
| 1422 | ret = link_free_space(block_group, info); | 1451 | ret = link_free_space(block_group, info); |
| 1423 | if (ret) | 1452 | if (ret) |
| 1424 | kfree(info); | 1453 | kfree(info); |
| @@ -1621,6 +1650,7 @@ __btrfs_return_cluster_to_free_space( | |||
| 1621 | node = rb_next(&entry->offset_index); | 1650 | node = rb_next(&entry->offset_index); |
| 1622 | rb_erase(&entry->offset_index, &cluster->root); | 1651 | rb_erase(&entry->offset_index, &cluster->root); |
| 1623 | BUG_ON(entry->bitmap); | 1652 | BUG_ON(entry->bitmap); |
| 1653 | try_merge_free_space(block_group, entry, false); | ||
| 1624 | tree_insert_offset(&block_group->free_space_offset, | 1654 | tree_insert_offset(&block_group->free_space_offset, |
| 1625 | entry->offset, &entry->offset_index, 0); | 1655 | entry->offset, &entry->offset_index, 0); |
| 1626 | } | 1656 | } |
| @@ -1685,13 +1715,8 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
| 1685 | ret = offset; | 1715 | ret = offset; |
| 1686 | if (entry->bitmap) { | 1716 | if (entry->bitmap) { |
| 1687 | bitmap_clear_bits(block_group, entry, offset, bytes); | 1717 | bitmap_clear_bits(block_group, entry, offset, bytes); |
| 1688 | if (!entry->bytes) { | 1718 | if (!entry->bytes) |
| 1689 | unlink_free_space(block_group, entry); | 1719 | free_bitmap(block_group, entry); |
| 1690 | kfree(entry->bitmap); | ||
| 1691 | kfree(entry); | ||
| 1692 | block_group->total_bitmaps--; | ||
| 1693 | recalculate_thresholds(block_group); | ||
| 1694 | } | ||
| 1695 | } else { | 1720 | } else { |
| 1696 | unlink_free_space(block_group, entry); | 1721 | unlink_free_space(block_group, entry); |
| 1697 | entry->offset += bytes; | 1722 | entry->offset += bytes; |
| @@ -1789,6 +1814,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | |||
| 1789 | 1814 | ||
| 1790 | ret = search_start; | 1815 | ret = search_start; |
| 1791 | bitmap_clear_bits(block_group, entry, ret, bytes); | 1816 | bitmap_clear_bits(block_group, entry, ret, bytes); |
| 1817 | if (entry->bytes == 0) | ||
| 1818 | free_bitmap(block_group, entry); | ||
| 1792 | out: | 1819 | out: |
| 1793 | spin_unlock(&cluster->lock); | 1820 | spin_unlock(&cluster->lock); |
| 1794 | spin_unlock(&block_group->tree_lock); | 1821 | spin_unlock(&block_group->tree_lock); |
| @@ -1842,15 +1869,26 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | |||
| 1842 | entry->offset += bytes; | 1869 | entry->offset += bytes; |
| 1843 | entry->bytes -= bytes; | 1870 | entry->bytes -= bytes; |
| 1844 | 1871 | ||
| 1845 | if (entry->bytes == 0) { | 1872 | if (entry->bytes == 0) |
| 1846 | rb_erase(&entry->offset_index, &cluster->root); | 1873 | rb_erase(&entry->offset_index, &cluster->root); |
| 1847 | kfree(entry); | ||
| 1848 | } | ||
| 1849 | break; | 1874 | break; |
| 1850 | } | 1875 | } |
| 1851 | out: | 1876 | out: |
| 1852 | spin_unlock(&cluster->lock); | 1877 | spin_unlock(&cluster->lock); |
| 1853 | 1878 | ||
| 1879 | if (!ret) | ||
| 1880 | return 0; | ||
| 1881 | |||
| 1882 | spin_lock(&block_group->tree_lock); | ||
| 1883 | |||
| 1884 | block_group->free_space -= bytes; | ||
| 1885 | if (entry->bytes == 0) { | ||
| 1886 | block_group->free_extents--; | ||
| 1887 | kfree(entry); | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | spin_unlock(&block_group->tree_lock); | ||
| 1891 | |||
| 1854 | return ret; | 1892 | return ret; |
| 1855 | } | 1893 | } |
| 1856 | 1894 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 160b55b3e13..fb9bd7832b6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -416,7 +416,7 @@ again: | |||
| 416 | } | 416 | } |
| 417 | if (start == 0) { | 417 | if (start == 0) { |
| 418 | trans = btrfs_join_transaction(root, 1); | 418 | trans = btrfs_join_transaction(root, 1); |
| 419 | BUG_ON(!trans); | 419 | BUG_ON(IS_ERR(trans)); |
| 420 | btrfs_set_trans_block_group(trans, inode); | 420 | btrfs_set_trans_block_group(trans, inode); |
| 421 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 421 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 422 | 422 | ||
| @@ -612,6 +612,7 @@ retry: | |||
| 612 | GFP_NOFS); | 612 | GFP_NOFS); |
| 613 | 613 | ||
| 614 | trans = btrfs_join_transaction(root, 1); | 614 | trans = btrfs_join_transaction(root, 1); |
| 615 | BUG_ON(IS_ERR(trans)); | ||
| 615 | ret = btrfs_reserve_extent(trans, root, | 616 | ret = btrfs_reserve_extent(trans, root, |
| 616 | async_extent->compressed_size, | 617 | async_extent->compressed_size, |
| 617 | async_extent->compressed_size, | 618 | async_extent->compressed_size, |
| @@ -643,6 +644,7 @@ retry: | |||
| 643 | async_extent->ram_size - 1, 0); | 644 | async_extent->ram_size - 1, 0); |
| 644 | 645 | ||
| 645 | em = alloc_extent_map(GFP_NOFS); | 646 | em = alloc_extent_map(GFP_NOFS); |
| 647 | BUG_ON(!em); | ||
| 646 | em->start = async_extent->start; | 648 | em->start = async_extent->start; |
| 647 | em->len = async_extent->ram_size; | 649 | em->len = async_extent->ram_size; |
| 648 | em->orig_start = em->start; | 650 | em->orig_start = em->start; |
| @@ -771,7 +773,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 771 | 773 | ||
| 772 | BUG_ON(root == root->fs_info->tree_root); | 774 | BUG_ON(root == root->fs_info->tree_root); |
| 773 | trans = btrfs_join_transaction(root, 1); | 775 | trans = btrfs_join_transaction(root, 1); |
| 774 | BUG_ON(!trans); | 776 | BUG_ON(IS_ERR(trans)); |
| 775 | btrfs_set_trans_block_group(trans, inode); | 777 | btrfs_set_trans_block_group(trans, inode); |
| 776 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 778 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 777 | 779 | ||
| @@ -819,6 +821,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 819 | BUG_ON(ret); | 821 | BUG_ON(ret); |
| 820 | 822 | ||
| 821 | em = alloc_extent_map(GFP_NOFS); | 823 | em = alloc_extent_map(GFP_NOFS); |
| 824 | BUG_ON(!em); | ||
| 822 | em->start = start; | 825 | em->start = start; |
| 823 | em->orig_start = em->start; | 826 | em->orig_start = em->start; |
| 824 | ram_size = ins.offset; | 827 | ram_size = ins.offset; |
| @@ -1049,7 +1052,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
| 1049 | } else { | 1052 | } else { |
| 1050 | trans = btrfs_join_transaction(root, 1); | 1053 | trans = btrfs_join_transaction(root, 1); |
| 1051 | } | 1054 | } |
| 1052 | BUG_ON(!trans); | 1055 | BUG_ON(IS_ERR(trans)); |
| 1053 | 1056 | ||
| 1054 | cow_start = (u64)-1; | 1057 | cow_start = (u64)-1; |
| 1055 | cur_offset = start; | 1058 | cur_offset = start; |
| @@ -1168,6 +1171,7 @@ out_check: | |||
| 1168 | struct extent_map_tree *em_tree; | 1171 | struct extent_map_tree *em_tree; |
| 1169 | em_tree = &BTRFS_I(inode)->extent_tree; | 1172 | em_tree = &BTRFS_I(inode)->extent_tree; |
| 1170 | em = alloc_extent_map(GFP_NOFS); | 1173 | em = alloc_extent_map(GFP_NOFS); |
| 1174 | BUG_ON(!em); | ||
| 1171 | em->start = cur_offset; | 1175 | em->start = cur_offset; |
| 1172 | em->orig_start = em->start; | 1176 | em->orig_start = em->start; |
| 1173 | em->len = num_bytes; | 1177 | em->len = num_bytes; |
| @@ -1557,6 +1561,7 @@ out: | |||
| 1557 | out_page: | 1561 | out_page: |
| 1558 | unlock_page(page); | 1562 | unlock_page(page); |
| 1559 | page_cache_release(page); | 1563 | page_cache_release(page); |
| 1564 | kfree(fixup); | ||
| 1560 | } | 1565 | } |
| 1561 | 1566 | ||
| 1562 | /* | 1567 | /* |
| @@ -1703,7 +1708,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1703 | trans = btrfs_join_transaction_nolock(root, 1); | 1708 | trans = btrfs_join_transaction_nolock(root, 1); |
| 1704 | else | 1709 | else |
| 1705 | trans = btrfs_join_transaction(root, 1); | 1710 | trans = btrfs_join_transaction(root, 1); |
| 1706 | BUG_ON(!trans); | 1711 | BUG_ON(IS_ERR(trans)); |
| 1707 | btrfs_set_trans_block_group(trans, inode); | 1712 | btrfs_set_trans_block_group(trans, inode); |
| 1708 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1713 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 1709 | ret = btrfs_update_inode(trans, root, inode); | 1714 | ret = btrfs_update_inode(trans, root, inode); |
| @@ -1720,6 +1725,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1720 | trans = btrfs_join_transaction_nolock(root, 1); | 1725 | trans = btrfs_join_transaction_nolock(root, 1); |
| 1721 | else | 1726 | else |
| 1722 | trans = btrfs_join_transaction(root, 1); | 1727 | trans = btrfs_join_transaction(root, 1); |
| 1728 | BUG_ON(IS_ERR(trans)); | ||
| 1723 | btrfs_set_trans_block_group(trans, inode); | 1729 | btrfs_set_trans_block_group(trans, inode); |
| 1724 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1730 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 1725 | 1731 | ||
| @@ -2354,6 +2360,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2354 | */ | 2360 | */ |
| 2355 | if (is_bad_inode(inode)) { | 2361 | if (is_bad_inode(inode)) { |
| 2356 | trans = btrfs_start_transaction(root, 0); | 2362 | trans = btrfs_start_transaction(root, 0); |
| 2363 | BUG_ON(IS_ERR(trans)); | ||
| 2357 | btrfs_orphan_del(trans, inode); | 2364 | btrfs_orphan_del(trans, inode); |
| 2358 | btrfs_end_transaction(trans, root); | 2365 | btrfs_end_transaction(trans, root); |
| 2359 | iput(inode); | 2366 | iput(inode); |
| @@ -2381,6 +2388,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2381 | 2388 | ||
| 2382 | if (root->orphan_block_rsv || root->orphan_item_inserted) { | 2389 | if (root->orphan_block_rsv || root->orphan_item_inserted) { |
| 2383 | trans = btrfs_join_transaction(root, 1); | 2390 | trans = btrfs_join_transaction(root, 1); |
| 2391 | BUG_ON(IS_ERR(trans)); | ||
| 2384 | btrfs_end_transaction(trans, root); | 2392 | btrfs_end_transaction(trans, root); |
| 2385 | } | 2393 | } |
| 2386 | 2394 | ||
| @@ -2641,7 +2649,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | |||
| 2641 | path = btrfs_alloc_path(); | 2649 | path = btrfs_alloc_path(); |
| 2642 | if (!path) { | 2650 | if (!path) { |
| 2643 | ret = -ENOMEM; | 2651 | ret = -ENOMEM; |
| 2644 | goto err; | 2652 | goto out; |
| 2645 | } | 2653 | } |
| 2646 | 2654 | ||
| 2647 | path->leave_spinning = 1; | 2655 | path->leave_spinning = 1; |
| @@ -2714,9 +2722,10 @@ static int check_path_shared(struct btrfs_root *root, | |||
| 2714 | struct extent_buffer *eb; | 2722 | struct extent_buffer *eb; |
| 2715 | int level; | 2723 | int level; |
| 2716 | u64 refs = 1; | 2724 | u64 refs = 1; |
| 2717 | int uninitialized_var(ret); | ||
| 2718 | 2725 | ||
| 2719 | for (level = 0; level < BTRFS_MAX_LEVEL; level++) { | 2726 | for (level = 0; level < BTRFS_MAX_LEVEL; level++) { |
| 2727 | int ret; | ||
| 2728 | |||
| 2720 | if (!path->nodes[level]) | 2729 | if (!path->nodes[level]) |
| 2721 | break; | 2730 | break; |
| 2722 | eb = path->nodes[level]; | 2731 | eb = path->nodes[level]; |
| @@ -2727,7 +2736,7 @@ static int check_path_shared(struct btrfs_root *root, | |||
| 2727 | if (refs > 1) | 2736 | if (refs > 1) |
| 2728 | return 1; | 2737 | return 1; |
| 2729 | } | 2738 | } |
| 2730 | return ret; /* XXX callers? */ | 2739 | return 0; |
| 2731 | } | 2740 | } |
| 2732 | 2741 | ||
| 2733 | /* | 2742 | /* |
| @@ -4134,7 +4143,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 4134 | } | 4143 | } |
| 4135 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); | 4144 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); |
| 4136 | 4145 | ||
| 4137 | if (root != sub_root) { | 4146 | if (!IS_ERR(inode) && root != sub_root) { |
| 4138 | down_read(&root->fs_info->cleanup_work_sem); | 4147 | down_read(&root->fs_info->cleanup_work_sem); |
| 4139 | if (!(inode->i_sb->s_flags & MS_RDONLY)) | 4148 | if (!(inode->i_sb->s_flags & MS_RDONLY)) |
| 4140 | btrfs_orphan_cleanup(sub_root); | 4149 | btrfs_orphan_cleanup(sub_root); |
| @@ -4347,6 +4356,8 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 4347 | trans = btrfs_join_transaction_nolock(root, 1); | 4356 | trans = btrfs_join_transaction_nolock(root, 1); |
| 4348 | else | 4357 | else |
| 4349 | trans = btrfs_join_transaction(root, 1); | 4358 | trans = btrfs_join_transaction(root, 1); |
| 4359 | if (IS_ERR(trans)) | ||
| 4360 | return PTR_ERR(trans); | ||
| 4350 | btrfs_set_trans_block_group(trans, inode); | 4361 | btrfs_set_trans_block_group(trans, inode); |
| 4351 | if (nolock) | 4362 | if (nolock) |
| 4352 | ret = btrfs_end_transaction_nolock(trans, root); | 4363 | ret = btrfs_end_transaction_nolock(trans, root); |
| @@ -4372,6 +4383,7 @@ void btrfs_dirty_inode(struct inode *inode) | |||
| 4372 | return; | 4383 | return; |
| 4373 | 4384 | ||
| 4374 | trans = btrfs_join_transaction(root, 1); | 4385 | trans = btrfs_join_transaction(root, 1); |
| 4386 | BUG_ON(IS_ERR(trans)); | ||
| 4375 | btrfs_set_trans_block_group(trans, inode); | 4387 | btrfs_set_trans_block_group(trans, inode); |
| 4376 | 4388 | ||
| 4377 | ret = btrfs_update_inode(trans, root, inode); | 4389 | ret = btrfs_update_inode(trans, root, inode); |
| @@ -5176,6 +5188,8 @@ again: | |||
| 5176 | em = NULL; | 5188 | em = NULL; |
| 5177 | btrfs_release_path(root, path); | 5189 | btrfs_release_path(root, path); |
| 5178 | trans = btrfs_join_transaction(root, 1); | 5190 | trans = btrfs_join_transaction(root, 1); |
| 5191 | if (IS_ERR(trans)) | ||
| 5192 | return ERR_CAST(trans); | ||
| 5179 | goto again; | 5193 | goto again; |
| 5180 | } | 5194 | } |
| 5181 | map = kmap(page); | 5195 | map = kmap(page); |
| @@ -5280,8 +5294,8 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
| 5280 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | 5294 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); |
| 5281 | 5295 | ||
| 5282 | trans = btrfs_join_transaction(root, 0); | 5296 | trans = btrfs_join_transaction(root, 0); |
| 5283 | if (!trans) | 5297 | if (IS_ERR(trans)) |
| 5284 | return ERR_PTR(-ENOMEM); | 5298 | return ERR_CAST(trans); |
| 5285 | 5299 | ||
| 5286 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 5300 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 5287 | 5301 | ||
| @@ -5505,7 +5519,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
| 5505 | * while we look for nocow cross refs | 5519 | * while we look for nocow cross refs |
| 5506 | */ | 5520 | */ |
| 5507 | trans = btrfs_join_transaction(root, 0); | 5521 | trans = btrfs_join_transaction(root, 0); |
| 5508 | if (!trans) | 5522 | if (IS_ERR(trans)) |
| 5509 | goto must_cow; | 5523 | goto must_cow; |
| 5510 | 5524 | ||
| 5511 | if (can_nocow_odirect(trans, inode, start, len) == 1) { | 5525 | if (can_nocow_odirect(trans, inode, start, len) == 1) { |
| @@ -5640,7 +5654,7 @@ again: | |||
| 5640 | BUG_ON(!ordered); | 5654 | BUG_ON(!ordered); |
| 5641 | 5655 | ||
| 5642 | trans = btrfs_join_transaction(root, 1); | 5656 | trans = btrfs_join_transaction(root, 1); |
| 5643 | if (!trans) { | 5657 | if (IS_ERR(trans)) { |
| 5644 | err = -ENOMEM; | 5658 | err = -ENOMEM; |
| 5645 | goto out; | 5659 | goto out; |
| 5646 | } | 5660 | } |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a506a22b522..be2d4f6aaa5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -203,7 +203,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
| 203 | 203 | ||
| 204 | 204 | ||
| 205 | trans = btrfs_join_transaction(root, 1); | 205 | trans = btrfs_join_transaction(root, 1); |
| 206 | BUG_ON(!trans); | 206 | BUG_ON(IS_ERR(trans)); |
| 207 | 207 | ||
| 208 | ret = btrfs_update_inode(trans, root, inode); | 208 | ret = btrfs_update_inode(trans, root, inode); |
| 209 | BUG_ON(ret); | 209 | BUG_ON(ret); |
| @@ -907,6 +907,10 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
| 907 | 907 | ||
| 908 | if (new_size > old_size) { | 908 | if (new_size > old_size) { |
| 909 | trans = btrfs_start_transaction(root, 0); | 909 | trans = btrfs_start_transaction(root, 0); |
| 910 | if (IS_ERR(trans)) { | ||
| 911 | ret = PTR_ERR(trans); | ||
| 912 | goto out_unlock; | ||
| 913 | } | ||
| 910 | ret = btrfs_grow_device(trans, device, new_size); | 914 | ret = btrfs_grow_device(trans, device, new_size); |
| 911 | btrfs_commit_transaction(trans, root); | 915 | btrfs_commit_transaction(trans, root); |
| 912 | } else { | 916 | } else { |
| @@ -1898,7 +1902,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1898 | 1902 | ||
| 1899 | memcpy(&new_key, &key, sizeof(new_key)); | 1903 | memcpy(&new_key, &key, sizeof(new_key)); |
| 1900 | new_key.objectid = inode->i_ino; | 1904 | new_key.objectid = inode->i_ino; |
| 1901 | new_key.offset = key.offset + destoff - off; | 1905 | if (off <= key.offset) |
| 1906 | new_key.offset = key.offset + destoff - off; | ||
| 1907 | else | ||
| 1908 | new_key.offset = destoff; | ||
| 1902 | 1909 | ||
| 1903 | trans = btrfs_start_transaction(root, 1); | 1910 | trans = btrfs_start_transaction(root, 1); |
| 1904 | if (IS_ERR(trans)) { | 1911 | if (IS_ERR(trans)) { |
| @@ -2082,7 +2089,7 @@ static long btrfs_ioctl_trans_start(struct file *file) | |||
| 2082 | 2089 | ||
| 2083 | ret = -ENOMEM; | 2090 | ret = -ENOMEM; |
| 2084 | trans = btrfs_start_ioctl_transaction(root, 0); | 2091 | trans = btrfs_start_ioctl_transaction(root, 0); |
| 2085 | if (!trans) | 2092 | if (IS_ERR(trans)) |
| 2086 | goto out_drop; | 2093 | goto out_drop; |
| 2087 | 2094 | ||
| 2088 | file->private_data = trans; | 2095 | file->private_data = trans; |
| @@ -2138,9 +2145,9 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
| 2138 | path->leave_spinning = 1; | 2145 | path->leave_spinning = 1; |
| 2139 | 2146 | ||
| 2140 | trans = btrfs_start_transaction(root, 1); | 2147 | trans = btrfs_start_transaction(root, 1); |
| 2141 | if (!trans) { | 2148 | if (IS_ERR(trans)) { |
| 2142 | btrfs_free_path(path); | 2149 | btrfs_free_path(path); |
| 2143 | return -ENOMEM; | 2150 | return PTR_ERR(trans); |
| 2144 | } | 2151 | } |
| 2145 | 2152 | ||
| 2146 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 2153 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); |
| @@ -2201,7 +2208,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
| 2201 | int num_types = 4; | 2208 | int num_types = 4; |
| 2202 | int alloc_size; | 2209 | int alloc_size; |
| 2203 | int ret = 0; | 2210 | int ret = 0; |
| 2204 | int slot_count = 0; | 2211 | u64 slot_count = 0; |
| 2205 | int i, c; | 2212 | int i, c; |
| 2206 | 2213 | ||
| 2207 | if (copy_from_user(&space_args, | 2214 | if (copy_from_user(&space_args, |
| @@ -2240,7 +2247,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
| 2240 | goto out; | 2247 | goto out; |
| 2241 | } | 2248 | } |
| 2242 | 2249 | ||
| 2243 | slot_count = min_t(int, space_args.space_slots, slot_count); | 2250 | slot_count = min_t(u64, space_args.space_slots, slot_count); |
| 2244 | 2251 | ||
| 2245 | alloc_size = sizeof(*dest) * slot_count; | 2252 | alloc_size = sizeof(*dest) * slot_count; |
| 2246 | 2253 | ||
| @@ -2260,6 +2267,9 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
| 2260 | for (i = 0; i < num_types; i++) { | 2267 | for (i = 0; i < num_types; i++) { |
| 2261 | struct btrfs_space_info *tmp; | 2268 | struct btrfs_space_info *tmp; |
| 2262 | 2269 | ||
| 2270 | if (!slot_count) | ||
| 2271 | break; | ||
| 2272 | |||
| 2263 | info = NULL; | 2273 | info = NULL; |
| 2264 | rcu_read_lock(); | 2274 | rcu_read_lock(); |
| 2265 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, | 2275 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, |
| @@ -2281,7 +2291,10 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
| 2281 | memcpy(dest, &space, sizeof(space)); | 2291 | memcpy(dest, &space, sizeof(space)); |
| 2282 | dest++; | 2292 | dest++; |
| 2283 | space_args.total_spaces++; | 2293 | space_args.total_spaces++; |
| 2294 | slot_count--; | ||
| 2284 | } | 2295 | } |
| 2296 | if (!slot_count) | ||
| 2297 | break; | ||
| 2285 | } | 2298 | } |
| 2286 | up_read(&info->groups_sem); | 2299 | up_read(&info->groups_sem); |
| 2287 | } | 2300 | } |
| @@ -2334,6 +2347,8 @@ static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp | |||
| 2334 | u64 transid; | 2347 | u64 transid; |
| 2335 | 2348 | ||
| 2336 | trans = btrfs_start_transaction(root, 0); | 2349 | trans = btrfs_start_transaction(root, 0); |
| 2350 | if (IS_ERR(trans)) | ||
| 2351 | return PTR_ERR(trans); | ||
| 2337 | transid = trans->transid; | 2352 | transid = trans->transid; |
| 2338 | btrfs_commit_transaction_async(trans, root, 0); | 2353 | btrfs_commit_transaction_async(trans, root, 0); |
| 2339 | 2354 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 2b61e1ddcd9..083a5547737 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -141,7 +141,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, | |||
| 141 | u64 file_offset) | 141 | u64 file_offset) |
| 142 | { | 142 | { |
| 143 | struct rb_root *root = &tree->tree; | 143 | struct rb_root *root = &tree->tree; |
| 144 | struct rb_node *prev; | 144 | struct rb_node *prev = NULL; |
| 145 | struct rb_node *ret; | 145 | struct rb_node *ret; |
| 146 | struct btrfs_ordered_extent *entry; | 146 | struct btrfs_ordered_extent *entry; |
| 147 | 147 | ||
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 0d126be22b6..fb2605d998e 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
| @@ -260,6 +260,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
| 260 | #else | 260 | #else |
| 261 | BUG(); | 261 | BUG(); |
| 262 | #endif | 262 | #endif |
| 263 | break; | ||
| 263 | case BTRFS_BLOCK_GROUP_ITEM_KEY: | 264 | case BTRFS_BLOCK_GROUP_ITEM_KEY: |
| 264 | bi = btrfs_item_ptr(l, i, | 265 | bi = btrfs_item_ptr(l, i, |
| 265 | struct btrfs_block_group_item); | 266 | struct btrfs_block_group_item); |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 045c9c2b2d7..0825e4ed944 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -1157,6 +1157,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, | |||
| 1157 | new_node->bytenr = dest->node->start; | 1157 | new_node->bytenr = dest->node->start; |
| 1158 | new_node->level = node->level; | 1158 | new_node->level = node->level; |
| 1159 | new_node->lowest = node->lowest; | 1159 | new_node->lowest = node->lowest; |
| 1160 | new_node->checked = 1; | ||
| 1160 | new_node->root = dest; | 1161 | new_node->root = dest; |
| 1161 | 1162 | ||
| 1162 | if (!node->lowest) { | 1163 | if (!node->lowest) { |
| @@ -2028,6 +2029,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
| 2028 | 2029 | ||
| 2029 | while (1) { | 2030 | while (1) { |
| 2030 | trans = btrfs_start_transaction(root, 0); | 2031 | trans = btrfs_start_transaction(root, 0); |
| 2032 | BUG_ON(IS_ERR(trans)); | ||
| 2031 | trans->block_rsv = rc->block_rsv; | 2033 | trans->block_rsv = rc->block_rsv; |
| 2032 | 2034 | ||
| 2033 | ret = btrfs_block_rsv_check(trans, root, rc->block_rsv, | 2035 | ret = btrfs_block_rsv_check(trans, root, rc->block_rsv, |
| @@ -2147,6 +2149,12 @@ again: | |||
| 2147 | } | 2149 | } |
| 2148 | 2150 | ||
| 2149 | trans = btrfs_join_transaction(rc->extent_root, 1); | 2151 | trans = btrfs_join_transaction(rc->extent_root, 1); |
| 2152 | if (IS_ERR(trans)) { | ||
| 2153 | if (!err) | ||
| 2154 | btrfs_block_rsv_release(rc->extent_root, | ||
| 2155 | rc->block_rsv, num_bytes); | ||
| 2156 | return PTR_ERR(trans); | ||
| 2157 | } | ||
| 2150 | 2158 | ||
| 2151 | if (!err) { | 2159 | if (!err) { |
| 2152 | if (num_bytes != rc->merging_rsv_size) { | 2160 | if (num_bytes != rc->merging_rsv_size) { |
| @@ -3222,6 +3230,7 @@ truncate: | |||
| 3222 | trans = btrfs_join_transaction(root, 0); | 3230 | trans = btrfs_join_transaction(root, 0); |
| 3223 | if (IS_ERR(trans)) { | 3231 | if (IS_ERR(trans)) { |
| 3224 | btrfs_free_path(path); | 3232 | btrfs_free_path(path); |
| 3233 | ret = PTR_ERR(trans); | ||
| 3225 | goto out; | 3234 | goto out; |
| 3226 | } | 3235 | } |
| 3227 | 3236 | ||
| @@ -3628,6 +3637,7 @@ int prepare_to_relocate(struct reloc_control *rc) | |||
| 3628 | set_reloc_control(rc); | 3637 | set_reloc_control(rc); |
| 3629 | 3638 | ||
| 3630 | trans = btrfs_join_transaction(rc->extent_root, 1); | 3639 | trans = btrfs_join_transaction(rc->extent_root, 1); |
| 3640 | BUG_ON(IS_ERR(trans)); | ||
| 3631 | btrfs_commit_transaction(trans, rc->extent_root); | 3641 | btrfs_commit_transaction(trans, rc->extent_root); |
| 3632 | return 0; | 3642 | return 0; |
| 3633 | } | 3643 | } |
| @@ -3657,6 +3667,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
| 3657 | 3667 | ||
| 3658 | while (1) { | 3668 | while (1) { |
| 3659 | trans = btrfs_start_transaction(rc->extent_root, 0); | 3669 | trans = btrfs_start_transaction(rc->extent_root, 0); |
| 3670 | BUG_ON(IS_ERR(trans)); | ||
| 3660 | 3671 | ||
| 3661 | if (update_backref_cache(trans, &rc->backref_cache)) { | 3672 | if (update_backref_cache(trans, &rc->backref_cache)) { |
| 3662 | btrfs_end_transaction(trans, rc->extent_root); | 3673 | btrfs_end_transaction(trans, rc->extent_root); |
| @@ -3804,7 +3815,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
| 3804 | 3815 | ||
| 3805 | /* get rid of pinned extents */ | 3816 | /* get rid of pinned extents */ |
| 3806 | trans = btrfs_join_transaction(rc->extent_root, 1); | 3817 | trans = btrfs_join_transaction(rc->extent_root, 1); |
| 3807 | btrfs_commit_transaction(trans, rc->extent_root); | 3818 | if (IS_ERR(trans)) |
| 3819 | err = PTR_ERR(trans); | ||
| 3820 | else | ||
| 3821 | btrfs_commit_transaction(trans, rc->extent_root); | ||
| 3808 | out_free: | 3822 | out_free: |
| 3809 | btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); | 3823 | btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); |
| 3810 | btrfs_free_path(path); | 3824 | btrfs_free_path(path); |
| @@ -4022,6 +4036,7 @@ static noinline_for_stack int mark_garbage_root(struct btrfs_root *root) | |||
| 4022 | int ret; | 4036 | int ret; |
| 4023 | 4037 | ||
| 4024 | trans = btrfs_start_transaction(root->fs_info->tree_root, 0); | 4038 | trans = btrfs_start_transaction(root->fs_info->tree_root, 0); |
| 4039 | BUG_ON(IS_ERR(trans)); | ||
| 4025 | 4040 | ||
| 4026 | memset(&root->root_item.drop_progress, 0, | 4041 | memset(&root->root_item.drop_progress, 0, |
| 4027 | sizeof(root->root_item.drop_progress)); | 4042 | sizeof(root->root_item.drop_progress)); |
| @@ -4125,6 +4140,11 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
| 4125 | set_reloc_control(rc); | 4140 | set_reloc_control(rc); |
| 4126 | 4141 | ||
| 4127 | trans = btrfs_join_transaction(rc->extent_root, 1); | 4142 | trans = btrfs_join_transaction(rc->extent_root, 1); |
| 4143 | if (IS_ERR(trans)) { | ||
| 4144 | unset_reloc_control(rc); | ||
| 4145 | err = PTR_ERR(trans); | ||
| 4146 | goto out_free; | ||
| 4147 | } | ||
| 4128 | 4148 | ||
| 4129 | rc->merge_reloc_tree = 1; | 4149 | rc->merge_reloc_tree = 1; |
| 4130 | 4150 | ||
| @@ -4154,9 +4174,13 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
| 4154 | unset_reloc_control(rc); | 4174 | unset_reloc_control(rc); |
| 4155 | 4175 | ||
| 4156 | trans = btrfs_join_transaction(rc->extent_root, 1); | 4176 | trans = btrfs_join_transaction(rc->extent_root, 1); |
| 4157 | btrfs_commit_transaction(trans, rc->extent_root); | 4177 | if (IS_ERR(trans)) |
| 4158 | out: | 4178 | err = PTR_ERR(trans); |
| 4179 | else | ||
| 4180 | btrfs_commit_transaction(trans, rc->extent_root); | ||
| 4181 | out_free: | ||
| 4159 | kfree(rc); | 4182 | kfree(rc); |
| 4183 | out: | ||
| 4160 | while (!list_empty(&reloc_roots)) { | 4184 | while (!list_empty(&reloc_roots)) { |
| 4161 | reloc_root = list_entry(reloc_roots.next, | 4185 | reloc_root = list_entry(reloc_roots.next, |
| 4162 | struct btrfs_root, root_list); | 4186 | struct btrfs_root, root_list); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b2130c46fdb..a004008f7d2 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -383,7 +383,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 383 | struct btrfs_fs_devices **fs_devices) | 383 | struct btrfs_fs_devices **fs_devices) |
| 384 | { | 384 | { |
| 385 | substring_t args[MAX_OPT_ARGS]; | 385 | substring_t args[MAX_OPT_ARGS]; |
| 386 | char *opts, *p; | 386 | char *opts, *orig, *p; |
| 387 | int error = 0; | 387 | int error = 0; |
| 388 | int intarg; | 388 | int intarg; |
| 389 | 389 | ||
| @@ -397,6 +397,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 397 | opts = kstrdup(options, GFP_KERNEL); | 397 | opts = kstrdup(options, GFP_KERNEL); |
| 398 | if (!opts) | 398 | if (!opts) |
| 399 | return -ENOMEM; | 399 | return -ENOMEM; |
| 400 | orig = opts; | ||
| 400 | 401 | ||
| 401 | while ((p = strsep(&opts, ",")) != NULL) { | 402 | while ((p = strsep(&opts, ",")) != NULL) { |
| 402 | int token; | 403 | int token; |
| @@ -432,7 +433,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 432 | } | 433 | } |
| 433 | 434 | ||
| 434 | out_free_opts: | 435 | out_free_opts: |
| 435 | kfree(opts); | 436 | kfree(orig); |
| 436 | out: | 437 | out: |
| 437 | /* | 438 | /* |
| 438 | * If no subvolume name is specified we use the default one. Allocate | 439 | * If no subvolume name is specified we use the default one. Allocate |
| @@ -623,6 +624,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
| 623 | btrfs_wait_ordered_extents(root, 0, 0); | 624 | btrfs_wait_ordered_extents(root, 0, 0); |
| 624 | 625 | ||
| 625 | trans = btrfs_start_transaction(root, 0); | 626 | trans = btrfs_start_transaction(root, 0); |
| 627 | if (IS_ERR(trans)) | ||
| 628 | return PTR_ERR(trans); | ||
| 626 | ret = btrfs_commit_transaction(trans, root); | 629 | ret = btrfs_commit_transaction(trans, root); |
| 627 | return ret; | 630 | return ret; |
| 628 | } | 631 | } |
| @@ -761,6 +764,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 761 | } | 764 | } |
| 762 | 765 | ||
| 763 | btrfs_close_devices(fs_devices); | 766 | btrfs_close_devices(fs_devices); |
| 767 | kfree(fs_info); | ||
| 768 | kfree(tree_root); | ||
| 764 | } else { | 769 | } else { |
| 765 | char b[BDEVNAME_SIZE]; | 770 | char b[BDEVNAME_SIZE]; |
| 766 | 771 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index bae5c7b8bbe..3d73c8d93bb 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -1161,6 +1161,11 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
| 1161 | INIT_DELAYED_WORK(&ac->work, do_async_commit); | 1161 | INIT_DELAYED_WORK(&ac->work, do_async_commit); |
| 1162 | ac->root = root; | 1162 | ac->root = root; |
| 1163 | ac->newtrans = btrfs_join_transaction(root, 0); | 1163 | ac->newtrans = btrfs_join_transaction(root, 0); |
| 1164 | if (IS_ERR(ac->newtrans)) { | ||
| 1165 | int err = PTR_ERR(ac->newtrans); | ||
| 1166 | kfree(ac); | ||
| 1167 | return err; | ||
| 1168 | } | ||
| 1164 | 1169 | ||
| 1165 | /* take transaction reference */ | 1170 | /* take transaction reference */ |
| 1166 | mutex_lock(&root->fs_info->trans_mutex); | 1171 | mutex_lock(&root->fs_info->trans_mutex); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 054744ac571..a4bbb854dfd 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -338,6 +338,12 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
| 338 | } | 338 | } |
| 339 | dst_copy = kmalloc(item_size, GFP_NOFS); | 339 | dst_copy = kmalloc(item_size, GFP_NOFS); |
| 340 | src_copy = kmalloc(item_size, GFP_NOFS); | 340 | src_copy = kmalloc(item_size, GFP_NOFS); |
| 341 | if (!dst_copy || !src_copy) { | ||
| 342 | btrfs_release_path(root, path); | ||
| 343 | kfree(dst_copy); | ||
| 344 | kfree(src_copy); | ||
| 345 | return -ENOMEM; | ||
| 346 | } | ||
| 341 | 347 | ||
| 342 | read_extent_buffer(eb, src_copy, src_ptr, item_size); | 348 | read_extent_buffer(eb, src_copy, src_ptr, item_size); |
| 343 | 349 | ||
| @@ -665,6 +671,9 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, | |||
| 665 | btrfs_dir_item_key_to_cpu(leaf, di, &location); | 671 | btrfs_dir_item_key_to_cpu(leaf, di, &location); |
| 666 | name_len = btrfs_dir_name_len(leaf, di); | 672 | name_len = btrfs_dir_name_len(leaf, di); |
| 667 | name = kmalloc(name_len, GFP_NOFS); | 673 | name = kmalloc(name_len, GFP_NOFS); |
| 674 | if (!name) | ||
| 675 | return -ENOMEM; | ||
| 676 | |||
| 668 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); | 677 | read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); |
| 669 | btrfs_release_path(root, path); | 678 | btrfs_release_path(root, path); |
| 670 | 679 | ||
| @@ -744,6 +753,9 @@ static noinline int backref_in_log(struct btrfs_root *log, | |||
| 744 | int match = 0; | 753 | int match = 0; |
| 745 | 754 | ||
| 746 | path = btrfs_alloc_path(); | 755 | path = btrfs_alloc_path(); |
| 756 | if (!path) | ||
| 757 | return -ENOMEM; | ||
| 758 | |||
| 747 | ret = btrfs_search_slot(NULL, log, key, path, 0, 0); | 759 | ret = btrfs_search_slot(NULL, log, key, path, 0, 0); |
| 748 | if (ret != 0) | 760 | if (ret != 0) |
| 749 | goto out; | 761 | goto out; |
| @@ -967,6 +979,8 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, | |||
| 967 | key.offset = (u64)-1; | 979 | key.offset = (u64)-1; |
| 968 | 980 | ||
| 969 | path = btrfs_alloc_path(); | 981 | path = btrfs_alloc_path(); |
| 982 | if (!path) | ||
| 983 | return -ENOMEM; | ||
| 970 | 984 | ||
| 971 | while (1) { | 985 | while (1) { |
| 972 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 986 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| @@ -1178,6 +1192,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, | |||
| 1178 | 1192 | ||
| 1179 | name_len = btrfs_dir_name_len(eb, di); | 1193 | name_len = btrfs_dir_name_len(eb, di); |
| 1180 | name = kmalloc(name_len, GFP_NOFS); | 1194 | name = kmalloc(name_len, GFP_NOFS); |
| 1195 | if (!name) | ||
| 1196 | return -ENOMEM; | ||
| 1197 | |||
| 1181 | log_type = btrfs_dir_type(eb, di); | 1198 | log_type = btrfs_dir_type(eb, di); |
| 1182 | read_extent_buffer(eb, name, (unsigned long)(di + 1), | 1199 | read_extent_buffer(eb, name, (unsigned long)(di + 1), |
| 1183 | name_len); | 1200 | name_len); |
| @@ -1692,6 +1709,8 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
| 1692 | root_owner = btrfs_header_owner(parent); | 1709 | root_owner = btrfs_header_owner(parent); |
| 1693 | 1710 | ||
| 1694 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); | 1711 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); |
| 1712 | if (!next) | ||
| 1713 | return -ENOMEM; | ||
| 1695 | 1714 | ||
| 1696 | if (*level == 1) { | 1715 | if (*level == 1) { |
| 1697 | wc->process_func(root, next, wc, ptr_gen); | 1716 | wc->process_func(root, next, wc, ptr_gen); |
| @@ -2032,6 +2051,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2032 | wait_log_commit(trans, log_root_tree, | 2051 | wait_log_commit(trans, log_root_tree, |
| 2033 | log_root_tree->log_transid); | 2052 | log_root_tree->log_transid); |
| 2034 | mutex_unlock(&log_root_tree->log_mutex); | 2053 | mutex_unlock(&log_root_tree->log_mutex); |
| 2054 | ret = 0; | ||
| 2035 | goto out; | 2055 | goto out; |
| 2036 | } | 2056 | } |
| 2037 | atomic_set(&log_root_tree->log_commit[index2], 1); | 2057 | atomic_set(&log_root_tree->log_commit[index2], 1); |
| @@ -2096,7 +2116,7 @@ out: | |||
| 2096 | smp_mb(); | 2116 | smp_mb(); |
| 2097 | if (waitqueue_active(&root->log_commit_wait[index1])) | 2117 | if (waitqueue_active(&root->log_commit_wait[index1])) |
| 2098 | wake_up(&root->log_commit_wait[index1]); | 2118 | wake_up(&root->log_commit_wait[index1]); |
| 2099 | return 0; | 2119 | return ret; |
| 2100 | } | 2120 | } |
| 2101 | 2121 | ||
| 2102 | static void free_log_tree(struct btrfs_trans_handle *trans, | 2122 | static void free_log_tree(struct btrfs_trans_handle *trans, |
| @@ -2194,6 +2214,9 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, | |||
| 2194 | 2214 | ||
| 2195 | log = root->log_root; | 2215 | log = root->log_root; |
| 2196 | path = btrfs_alloc_path(); | 2216 | path = btrfs_alloc_path(); |
| 2217 | if (!path) | ||
| 2218 | return -ENOMEM; | ||
| 2219 | |||
| 2197 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, | 2220 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, |
| 2198 | name, name_len, -1); | 2221 | name, name_len, -1); |
| 2199 | if (IS_ERR(di)) { | 2222 | if (IS_ERR(di)) { |
| @@ -2594,6 +2617,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, | |||
| 2594 | 2617 | ||
| 2595 | ins_data = kmalloc(nr * sizeof(struct btrfs_key) + | 2618 | ins_data = kmalloc(nr * sizeof(struct btrfs_key) + |
| 2596 | nr * sizeof(u32), GFP_NOFS); | 2619 | nr * sizeof(u32), GFP_NOFS); |
| 2620 | if (!ins_data) | ||
| 2621 | return -ENOMEM; | ||
| 2622 | |||
| 2597 | ins_sizes = (u32 *)ins_data; | 2623 | ins_sizes = (u32 *)ins_data; |
| 2598 | ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32)); | 2624 | ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32)); |
| 2599 | 2625 | ||
| @@ -2725,7 +2751,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
| 2725 | log = root->log_root; | 2751 | log = root->log_root; |
| 2726 | 2752 | ||
| 2727 | path = btrfs_alloc_path(); | 2753 | path = btrfs_alloc_path(); |
| 2754 | if (!path) | ||
| 2755 | return -ENOMEM; | ||
| 2728 | dst_path = btrfs_alloc_path(); | 2756 | dst_path = btrfs_alloc_path(); |
| 2757 | if (!dst_path) { | ||
| 2758 | btrfs_free_path(path); | ||
| 2759 | return -ENOMEM; | ||
| 2760 | } | ||
| 2729 | 2761 | ||
| 2730 | min_key.objectid = inode->i_ino; | 2762 | min_key.objectid = inode->i_ino; |
| 2731 | min_key.type = BTRFS_INODE_ITEM_KEY; | 2763 | min_key.type = BTRFS_INODE_ITEM_KEY; |
| @@ -3080,6 +3112,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) | |||
| 3080 | BUG_ON(!path); | 3112 | BUG_ON(!path); |
| 3081 | 3113 | ||
| 3082 | trans = btrfs_start_transaction(fs_info->tree_root, 0); | 3114 | trans = btrfs_start_transaction(fs_info->tree_root, 0); |
| 3115 | BUG_ON(IS_ERR(trans)); | ||
| 3083 | 3116 | ||
| 3084 | wc.trans = trans; | 3117 | wc.trans = trans; |
| 3085 | wc.pin = 1; | 3118 | wc.pin = 1; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d158530233b..af7dbca1527 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -1213,6 +1213,10 @@ static int btrfs_rm_dev_item(struct btrfs_root *root, | |||
| 1213 | return -ENOMEM; | 1213 | return -ENOMEM; |
| 1214 | 1214 | ||
| 1215 | trans = btrfs_start_transaction(root, 0); | 1215 | trans = btrfs_start_transaction(root, 0); |
| 1216 | if (IS_ERR(trans)) { | ||
| 1217 | btrfs_free_path(path); | ||
| 1218 | return PTR_ERR(trans); | ||
| 1219 | } | ||
| 1216 | key.objectid = BTRFS_DEV_ITEMS_OBJECTID; | 1220 | key.objectid = BTRFS_DEV_ITEMS_OBJECTID; |
| 1217 | key.type = BTRFS_DEV_ITEM_KEY; | 1221 | key.type = BTRFS_DEV_ITEM_KEY; |
| 1218 | key.offset = device->devid; | 1222 | key.offset = device->devid; |
| @@ -1601,11 +1605,19 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1601 | 1605 | ||
| 1602 | ret = find_next_devid(root, &device->devid); | 1606 | ret = find_next_devid(root, &device->devid); |
| 1603 | if (ret) { | 1607 | if (ret) { |
| 1608 | kfree(device->name); | ||
| 1604 | kfree(device); | 1609 | kfree(device); |
| 1605 | goto error; | 1610 | goto error; |
| 1606 | } | 1611 | } |
| 1607 | 1612 | ||
| 1608 | trans = btrfs_start_transaction(root, 0); | 1613 | trans = btrfs_start_transaction(root, 0); |
| 1614 | if (IS_ERR(trans)) { | ||
| 1615 | kfree(device->name); | ||
| 1616 | kfree(device); | ||
| 1617 | ret = PTR_ERR(trans); | ||
| 1618 | goto error; | ||
| 1619 | } | ||
| 1620 | |||
| 1609 | lock_chunks(root); | 1621 | lock_chunks(root); |
| 1610 | 1622 | ||
| 1611 | device->writeable = 1; | 1623 | device->writeable = 1; |
| @@ -1873,7 +1885,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, | |||
| 1873 | return ret; | 1885 | return ret; |
| 1874 | 1886 | ||
| 1875 | trans = btrfs_start_transaction(root, 0); | 1887 | trans = btrfs_start_transaction(root, 0); |
| 1876 | BUG_ON(!trans); | 1888 | BUG_ON(IS_ERR(trans)); |
| 1877 | 1889 | ||
| 1878 | lock_chunks(root); | 1890 | lock_chunks(root); |
| 1879 | 1891 | ||
| @@ -2047,7 +2059,7 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
| 2047 | BUG_ON(ret); | 2059 | BUG_ON(ret); |
| 2048 | 2060 | ||
| 2049 | trans = btrfs_start_transaction(dev_root, 0); | 2061 | trans = btrfs_start_transaction(dev_root, 0); |
| 2050 | BUG_ON(!trans); | 2062 | BUG_ON(IS_ERR(trans)); |
| 2051 | 2063 | ||
| 2052 | ret = btrfs_grow_device(trans, device, old_size); | 2064 | ret = btrfs_grow_device(trans, device, old_size); |
| 2053 | BUG_ON(ret); | 2065 | BUG_ON(ret); |
| @@ -2213,6 +2225,11 @@ again: | |||
| 2213 | 2225 | ||
| 2214 | /* Shrinking succeeded, else we would be at "done". */ | 2226 | /* Shrinking succeeded, else we would be at "done". */ |
| 2215 | trans = btrfs_start_transaction(root, 0); | 2227 | trans = btrfs_start_transaction(root, 0); |
| 2228 | if (IS_ERR(trans)) { | ||
| 2229 | ret = PTR_ERR(trans); | ||
| 2230 | goto done; | ||
| 2231 | } | ||
| 2232 | |||
| 2216 | lock_chunks(root); | 2233 | lock_chunks(root); |
| 2217 | 2234 | ||
| 2218 | device->disk_total_bytes = new_size; | 2235 | device->disk_total_bytes = new_size; |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 1e7636b145a..beeebf19423 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -372,6 +372,10 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 372 | 372 | ||
| 373 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | 373 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), |
| 374 | GFP_KERNEL); | 374 | GFP_KERNEL); |
| 375 | if (!ppace) { | ||
| 376 | cERROR(1, "DACL memory allocation error"); | ||
| 377 | return; | ||
| 378 | } | ||
| 375 | 379 | ||
| 376 | for (i = 0; i < num_aces; ++i) { | 380 | for (i = 0; i < num_aces; ++i) { |
| 377 | ppace[i] = (struct cifs_ace *) (acl_base + acl_size); | 381 | ppace[i] = (struct cifs_ace *) (acl_base + acl_size); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index edd5b29b53c..17afb0fbcae 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -188,6 +188,8 @@ struct TCP_Server_Info { | |||
| 188 | /* multiplexed reads or writes */ | 188 | /* multiplexed reads or writes */ |
| 189 | unsigned int maxBuf; /* maxBuf specifies the maximum */ | 189 | unsigned int maxBuf; /* maxBuf specifies the maximum */ |
| 190 | /* message size the server can send or receive for non-raw SMBs */ | 190 | /* message size the server can send or receive for non-raw SMBs */ |
| 191 | /* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */ | ||
| 192 | /* when socket is setup (and during reconnect) before NegProt sent */ | ||
| 191 | unsigned int max_rw; /* maxRw specifies the maximum */ | 193 | unsigned int max_rw; /* maxRw specifies the maximum */ |
| 192 | /* message size the server can send or receive for */ | 194 | /* message size the server can send or receive for */ |
| 193 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ | 195 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ |
| @@ -652,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, | |||
| 652 | #define MID_REQUEST_SUBMITTED 2 | 654 | #define MID_REQUEST_SUBMITTED 2 |
| 653 | #define MID_RESPONSE_RECEIVED 4 | 655 | #define MID_RESPONSE_RECEIVED 4 |
| 654 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ | 656 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ |
| 655 | #define MID_NO_RESP_NEEDED 0x10 | 657 | #define MID_RESPONSE_MALFORMED 0x10 |
| 656 | 658 | ||
| 657 | /* Types of response buffer returned from SendReceive2 */ | 659 | /* Types of response buffer returned from SendReceive2 */ |
| 658 | #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ | 660 | #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 46c66ed01af..904aa47e351 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -136,9 +136,6 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) | |||
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | if (ses->status == CifsExiting) | ||
| 140 | return -EIO; | ||
| 141 | |||
| 142 | /* | 139 | /* |
| 143 | * Give demultiplex thread up to 10 seconds to reconnect, should be | 140 | * Give demultiplex thread up to 10 seconds to reconnect, should be |
| 144 | * greater than cifs socket timeout which is 7 seconds | 141 | * greater than cifs socket timeout which is 7 seconds |
| @@ -156,7 +153,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) | |||
| 156 | * retrying until process is killed or server comes | 153 | * retrying until process is killed or server comes |
| 157 | * back on-line | 154 | * back on-line |
| 158 | */ | 155 | */ |
| 159 | if (!tcon->retry || ses->status == CifsExiting) { | 156 | if (!tcon->retry) { |
| 160 | cFYI(1, "gave up waiting on reconnect in smb_init"); | 157 | cFYI(1, "gave up waiting on reconnect in smb_init"); |
| 161 | return -EHOSTDOWN; | 158 | return -EHOSTDOWN; |
| 162 | } | 159 | } |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 47d8ff62368..8d6c17ab593 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -337,8 +337,13 @@ cifs_echo_request(struct work_struct *work) | |||
| 337 | struct TCP_Server_Info *server = container_of(work, | 337 | struct TCP_Server_Info *server = container_of(work, |
| 338 | struct TCP_Server_Info, echo.work); | 338 | struct TCP_Server_Info, echo.work); |
| 339 | 339 | ||
| 340 | /* no need to ping if we got a response recently */ | 340 | /* |
| 341 | if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) | 341 | * We cannot send an echo until the NEGOTIATE_PROTOCOL request is |
| 342 | * done, which is indicated by maxBuf != 0. Also, no need to ping if | ||
| 343 | * we got a response recently | ||
| 344 | */ | ||
| 345 | if (server->maxBuf == 0 || | ||
| 346 | time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) | ||
| 342 | goto requeue_echo; | 347 | goto requeue_echo; |
| 343 | 348 | ||
| 344 | rc = CIFSSMBEcho(server); | 349 | rc = CIFSSMBEcho(server); |
| @@ -578,14 +583,23 @@ incomplete_rcv: | |||
| 578 | else if (reconnect == 1) | 583 | else if (reconnect == 1) |
| 579 | continue; | 584 | continue; |
| 580 | 585 | ||
| 581 | length += 4; /* account for rfc1002 hdr */ | 586 | total_read += 4; /* account for rfc1002 hdr */ |
| 582 | 587 | ||
| 588 | dump_smb(smb_buffer, total_read); | ||
| 583 | 589 | ||
| 584 | dump_smb(smb_buffer, length); | 590 | /* |
| 585 | if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { | 591 | * We know that we received enough to get to the MID as we |
| 586 | cifs_dump_mem("Bad SMB: ", smb_buffer, 48); | 592 | * checked the pdu_length earlier. Now check to see |
| 587 | continue; | 593 | * if the rest of the header is OK. We borrow the length |
| 588 | } | 594 | * var for the rest of the loop to avoid a new stack var. |
| 595 | * | ||
| 596 | * 48 bytes is enough to display the header and a little bit | ||
| 597 | * into the payload for debugging purposes. | ||
| 598 | */ | ||
| 599 | length = checkSMB(smb_buffer, smb_buffer->Mid, total_read); | ||
| 600 | if (length != 0) | ||
| 601 | cifs_dump_mem("Bad SMB: ", smb_buffer, | ||
| 602 | min_t(unsigned int, total_read, 48)); | ||
| 589 | 603 | ||
| 590 | mid_entry = NULL; | 604 | mid_entry = NULL; |
| 591 | server->lstrp = jiffies; | 605 | server->lstrp = jiffies; |
| @@ -597,7 +611,8 @@ incomplete_rcv: | |||
| 597 | if ((mid_entry->mid == smb_buffer->Mid) && | 611 | if ((mid_entry->mid == smb_buffer->Mid) && |
| 598 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && | 612 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && |
| 599 | (mid_entry->command == smb_buffer->Command)) { | 613 | (mid_entry->command == smb_buffer->Command)) { |
| 600 | if (check2ndT2(smb_buffer,server->maxBuf) > 0) { | 614 | if (length == 0 && |
| 615 | check2ndT2(smb_buffer, server->maxBuf) > 0) { | ||
| 601 | /* We have a multipart transact2 resp */ | 616 | /* We have a multipart transact2 resp */ |
| 602 | isMultiRsp = true; | 617 | isMultiRsp = true; |
| 603 | if (mid_entry->resp_buf) { | 618 | if (mid_entry->resp_buf) { |
| @@ -632,12 +647,17 @@ incomplete_rcv: | |||
| 632 | mid_entry->resp_buf = smb_buffer; | 647 | mid_entry->resp_buf = smb_buffer; |
| 633 | mid_entry->largeBuf = isLargeBuf; | 648 | mid_entry->largeBuf = isLargeBuf; |
| 634 | multi_t2_fnd: | 649 | multi_t2_fnd: |
| 635 | mid_entry->midState = MID_RESPONSE_RECEIVED; | 650 | if (length == 0) |
| 636 | list_del_init(&mid_entry->qhead); | 651 | mid_entry->midState = |
| 637 | mid_entry->callback(mid_entry); | 652 | MID_RESPONSE_RECEIVED; |
| 653 | else | ||
| 654 | mid_entry->midState = | ||
| 655 | MID_RESPONSE_MALFORMED; | ||
| 638 | #ifdef CONFIG_CIFS_STATS2 | 656 | #ifdef CONFIG_CIFS_STATS2 |
| 639 | mid_entry->when_received = jiffies; | 657 | mid_entry->when_received = jiffies; |
| 640 | #endif | 658 | #endif |
| 659 | list_del_init(&mid_entry->qhead); | ||
| 660 | mid_entry->callback(mid_entry); | ||
| 641 | break; | 661 | break; |
| 642 | } | 662 | } |
| 643 | mid_entry = NULL; | 663 | mid_entry = NULL; |
| @@ -653,6 +673,9 @@ multi_t2_fnd: | |||
| 653 | else | 673 | else |
| 654 | smallbuf = NULL; | 674 | smallbuf = NULL; |
| 655 | } | 675 | } |
| 676 | } else if (length != 0) { | ||
| 677 | /* response sanity checks failed */ | ||
| 678 | continue; | ||
| 656 | } else if (!is_valid_oplock_break(smb_buffer, server) && | 679 | } else if (!is_valid_oplock_break(smb_buffer, server) && |
| 657 | !isMultiRsp) { | 680 | !isMultiRsp) { |
| 658 | cERROR(1, "No task to wake, unknown frame received! " | 681 | cERROR(1, "No task to wake, unknown frame received! " |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 74c0a282d01..e964b1cd5dd 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -1662,10 +1662,10 @@ static ssize_t | |||
| 1662 | cifs_iovec_write(struct file *file, const struct iovec *iov, | 1662 | cifs_iovec_write(struct file *file, const struct iovec *iov, |
| 1663 | unsigned long nr_segs, loff_t *poffset) | 1663 | unsigned long nr_segs, loff_t *poffset) |
| 1664 | { | 1664 | { |
| 1665 | size_t total_written = 0; | 1665 | unsigned int written; |
| 1666 | unsigned int written = 0; | 1666 | unsigned long num_pages, npages, i; |
| 1667 | unsigned long num_pages, npages; | 1667 | size_t copied, len, cur_len; |
| 1668 | size_t copied, len, cur_len, i; | 1668 | ssize_t total_written = 0; |
| 1669 | struct kvec *to_send; | 1669 | struct kvec *to_send; |
| 1670 | struct page **pages; | 1670 | struct page **pages; |
| 1671 | struct iov_iter it; | 1671 | struct iov_iter it; |
| @@ -1821,7 +1821,8 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, | |||
| 1821 | { | 1821 | { |
| 1822 | int rc; | 1822 | int rc; |
| 1823 | int xid; | 1823 | int xid; |
| 1824 | unsigned int total_read, bytes_read = 0; | 1824 | ssize_t total_read; |
| 1825 | unsigned int bytes_read = 0; | ||
| 1825 | size_t len, cur_len; | 1826 | size_t len, cur_len; |
| 1826 | int iov_offset = 0; | 1827 | int iov_offset = 0; |
| 1827 | struct cifs_sb_info *cifs_sb; | 1828 | struct cifs_sb_info *cifs_sb; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index b8c5e2eb43d..46d8756f2b2 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -359,6 +359,10 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, | |||
| 359 | if (rc) | 359 | if (rc) |
| 360 | return rc; | 360 | return rc; |
| 361 | 361 | ||
| 362 | /* enable signing if server requires it */ | ||
| 363 | if (server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
| 364 | in_buf->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | ||
| 365 | |||
| 362 | mutex_lock(&server->srv_mutex); | 366 | mutex_lock(&server->srv_mutex); |
| 363 | mid = AllocMidQEntry(in_buf, server); | 367 | mid = AllocMidQEntry(in_buf, server); |
| 364 | if (mid == NULL) { | 368 | if (mid == NULL) { |
| @@ -453,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) | |||
| 453 | case MID_RETRY_NEEDED: | 457 | case MID_RETRY_NEEDED: |
| 454 | rc = -EAGAIN; | 458 | rc = -EAGAIN; |
| 455 | break; | 459 | break; |
| 460 | case MID_RESPONSE_MALFORMED: | ||
| 461 | rc = -EIO; | ||
| 462 | break; | ||
| 456 | default: | 463 | default: |
| 457 | cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, | 464 | cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, |
| 458 | mid->mid, mid->midState); | 465 | mid->mid, mid->midState); |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 9c64ae9e4c1..2d8c87b951c 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
| @@ -1468,15 +1468,13 @@ static void work_stop(void) | |||
| 1468 | 1468 | ||
| 1469 | static int work_start(void) | 1469 | static int work_start(void) |
| 1470 | { | 1470 | { |
| 1471 | recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM | | 1471 | recv_workqueue = create_singlethread_workqueue("dlm_recv"); |
| 1472 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | ||
| 1473 | if (!recv_workqueue) { | 1472 | if (!recv_workqueue) { |
| 1474 | log_print("can't start dlm_recv"); | 1473 | log_print("can't start dlm_recv"); |
| 1475 | return -ENOMEM; | 1474 | return -ENOMEM; |
| 1476 | } | 1475 | } |
| 1477 | 1476 | ||
| 1478 | send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM | | 1477 | send_workqueue = create_singlethread_workqueue("dlm_send"); |
| 1479 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | ||
| 1480 | if (!send_workqueue) { | 1478 | if (!send_workqueue) { |
| 1481 | log_print("can't start dlm_send"); | 1479 | log_print("can't start dlm_send"); |
| 1482 | destroy_workqueue(recv_workqueue); | 1480 | destroy_workqueue(recv_workqueue); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0c8d97b56f3..3aa0b72b3b9 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -848,6 +848,7 @@ struct ext4_inode_info { | |||
| 848 | atomic_t i_ioend_count; /* Number of outstanding io_end structs */ | 848 | atomic_t i_ioend_count; /* Number of outstanding io_end structs */ |
| 849 | /* current io_end structure for async DIO write*/ | 849 | /* current io_end structure for async DIO write*/ |
| 850 | ext4_io_end_t *cur_aio_dio; | 850 | ext4_io_end_t *cur_aio_dio; |
| 851 | atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */ | ||
| 851 | 852 | ||
| 852 | spinlock_t i_block_reservation_lock; | 853 | spinlock_t i_block_reservation_lock; |
| 853 | 854 | ||
| @@ -2119,6 +2120,15 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh) | |||
| 2119 | 2120 | ||
| 2120 | #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) | 2121 | #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) |
| 2121 | 2122 | ||
| 2123 | /* For ioend & aio unwritten conversion wait queues */ | ||
| 2124 | #define EXT4_WQ_HASH_SZ 37 | ||
| 2125 | #define ext4_ioend_wq(v) (&ext4__ioend_wq[((unsigned long)(v)) %\ | ||
| 2126 | EXT4_WQ_HASH_SZ]) | ||
| 2127 | #define ext4_aio_mutex(v) (&ext4__aio_mutex[((unsigned long)(v)) %\ | ||
| 2128 | EXT4_WQ_HASH_SZ]) | ||
| 2129 | extern wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ]; | ||
| 2130 | extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ]; | ||
| 2131 | |||
| 2122 | #endif /* __KERNEL__ */ | 2132 | #endif /* __KERNEL__ */ |
| 2123 | 2133 | ||
| 2124 | #endif /* _EXT4_H */ | 2134 | #endif /* _EXT4_H */ |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 63a75810b7c..ccce8a7e94e 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -3174,9 +3174,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
| 3174 | * that this IO needs to convertion to written when IO is | 3174 | * that this IO needs to convertion to written when IO is |
| 3175 | * completed | 3175 | * completed |
| 3176 | */ | 3176 | */ |
| 3177 | if (io) | 3177 | if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) { |
| 3178 | io->flag = EXT4_IO_END_UNWRITTEN; | 3178 | io->flag = EXT4_IO_END_UNWRITTEN; |
| 3179 | else | 3179 | atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
| 3180 | } else | ||
| 3180 | ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); | 3181 | ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); |
| 3181 | if (ext4_should_dioread_nolock(inode)) | 3182 | if (ext4_should_dioread_nolock(inode)) |
| 3182 | map->m_flags |= EXT4_MAP_UNINIT; | 3183 | map->m_flags |= EXT4_MAP_UNINIT; |
| @@ -3463,9 +3464,10 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3463 | * that we need to perform convertion when IO is done. | 3464 | * that we need to perform convertion when IO is done. |
| 3464 | */ | 3465 | */ |
| 3465 | if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { | 3466 | if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { |
| 3466 | if (io) | 3467 | if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) { |
| 3467 | io->flag = EXT4_IO_END_UNWRITTEN; | 3468 | io->flag = EXT4_IO_END_UNWRITTEN; |
| 3468 | else | 3469 | atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
| 3470 | } else | ||
| 3469 | ext4_set_inode_state(inode, | 3471 | ext4_set_inode_state(inode, |
| 3470 | EXT4_STATE_DIO_UNWRITTEN); | 3472 | EXT4_STATE_DIO_UNWRITTEN); |
| 3471 | } | 3473 | } |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 2e8322c8aa8..7b80d543b89 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
| @@ -55,11 +55,47 @@ static int ext4_release_file(struct inode *inode, struct file *filp) | |||
| 55 | return 0; | 55 | return 0; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void ext4_aiodio_wait(struct inode *inode) | ||
| 59 | { | ||
| 60 | wait_queue_head_t *wq = ext4_ioend_wq(inode); | ||
| 61 | |||
| 62 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0)); | ||
| 63 | } | ||
| 64 | |||
| 65 | /* | ||
| 66 | * This tests whether the IO in question is block-aligned or not. | ||
| 67 | * Ext4 utilizes unwritten extents when hole-filling during direct IO, and they | ||
| 68 | * are converted to written only after the IO is complete. Until they are | ||
| 69 | * mapped, these blocks appear as holes, so dio_zero_block() will assume that | ||
| 70 | * it needs to zero out portions of the start and/or end block. If 2 AIO | ||
| 71 | * threads are at work on the same unwritten block, they must be synchronized | ||
| 72 | * or one thread will zero the other's data, causing corruption. | ||
| 73 | */ | ||
| 74 | static int | ||
| 75 | ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, | ||
| 76 | unsigned long nr_segs, loff_t pos) | ||
| 77 | { | ||
| 78 | struct super_block *sb = inode->i_sb; | ||
| 79 | int blockmask = sb->s_blocksize - 1; | ||
| 80 | size_t count = iov_length(iov, nr_segs); | ||
| 81 | loff_t final_size = pos + count; | ||
| 82 | |||
| 83 | if (pos >= inode->i_size) | ||
| 84 | return 0; | ||
| 85 | |||
| 86 | if ((pos & blockmask) || (final_size & blockmask)) | ||
| 87 | return 1; | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 58 | static ssize_t | 92 | static ssize_t |
| 59 | ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | 93 | ext4_file_write(struct kiocb *iocb, const struct iovec *iov, |
| 60 | unsigned long nr_segs, loff_t pos) | 94 | unsigned long nr_segs, loff_t pos) |
| 61 | { | 95 | { |
| 62 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; | 96 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
| 97 | int unaligned_aio = 0; | ||
| 98 | int ret; | ||
| 63 | 99 | ||
| 64 | /* | 100 | /* |
| 65 | * If we have encountered a bitmap-format file, the size limit | 101 | * If we have encountered a bitmap-format file, the size limit |
| @@ -78,9 +114,31 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 78 | nr_segs = iov_shorten((struct iovec *)iov, nr_segs, | 114 | nr_segs = iov_shorten((struct iovec *)iov, nr_segs, |
| 79 | sbi->s_bitmap_maxbytes - pos); | 115 | sbi->s_bitmap_maxbytes - pos); |
| 80 | } | 116 | } |
| 117 | } else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) && | ||
| 118 | !is_sync_kiocb(iocb))) { | ||
| 119 | unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos); | ||
| 81 | } | 120 | } |
| 82 | 121 | ||
| 83 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 122 | /* Unaligned direct AIO must be serialized; see comment above */ |
| 123 | if (unaligned_aio) { | ||
| 124 | static unsigned long unaligned_warn_time; | ||
| 125 | |||
| 126 | /* Warn about this once per day */ | ||
| 127 | if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ)) | ||
| 128 | ext4_msg(inode->i_sb, KERN_WARNING, | ||
| 129 | "Unaligned AIO/DIO on inode %ld by %s; " | ||
| 130 | "performance will be poor.", | ||
| 131 | inode->i_ino, current->comm); | ||
| 132 | mutex_lock(ext4_aio_mutex(inode)); | ||
| 133 | ext4_aiodio_wait(inode); | ||
| 134 | } | ||
| 135 | |||
| 136 | ret = generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
| 137 | |||
| 138 | if (unaligned_aio) | ||
| 139 | mutex_unlock(ext4_aio_mutex(inode)); | ||
| 140 | |||
| 141 | return ret; | ||
| 84 | } | 142 | } |
| 85 | 143 | ||
| 86 | static const struct vm_operations_struct ext4_file_vm_ops = { | 144 | static const struct vm_operations_struct ext4_file_vm_ops = { |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 851f49b2f9d..d1fe09aea73 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -342,10 +342,15 @@ static struct kmem_cache *ext4_free_ext_cachep; | |||
| 342 | /* We create slab caches for groupinfo data structures based on the | 342 | /* We create slab caches for groupinfo data structures based on the |
| 343 | * superblock block size. There will be one per mounted filesystem for | 343 | * superblock block size. There will be one per mounted filesystem for |
| 344 | * each unique s_blocksize_bits */ | 344 | * each unique s_blocksize_bits */ |
| 345 | #define NR_GRPINFO_CACHES \ | 345 | #define NR_GRPINFO_CACHES 8 |
| 346 | (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE + 1) | ||
| 347 | static struct kmem_cache *ext4_groupinfo_caches[NR_GRPINFO_CACHES]; | 346 | static struct kmem_cache *ext4_groupinfo_caches[NR_GRPINFO_CACHES]; |
| 348 | 347 | ||
| 348 | static const char *ext4_groupinfo_slab_names[NR_GRPINFO_CACHES] = { | ||
| 349 | "ext4_groupinfo_1k", "ext4_groupinfo_2k", "ext4_groupinfo_4k", | ||
| 350 | "ext4_groupinfo_8k", "ext4_groupinfo_16k", "ext4_groupinfo_32k", | ||
| 351 | "ext4_groupinfo_64k", "ext4_groupinfo_128k" | ||
| 352 | }; | ||
| 353 | |||
| 349 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | 354 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, |
| 350 | ext4_group_t group); | 355 | ext4_group_t group); |
| 351 | static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | 356 | static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, |
| @@ -2414,6 +2419,55 @@ err_freesgi: | |||
| 2414 | return -ENOMEM; | 2419 | return -ENOMEM; |
| 2415 | } | 2420 | } |
| 2416 | 2421 | ||
| 2422 | static void ext4_groupinfo_destroy_slabs(void) | ||
| 2423 | { | ||
| 2424 | int i; | ||
| 2425 | |||
| 2426 | for (i = 0; i < NR_GRPINFO_CACHES; i++) { | ||
| 2427 | if (ext4_groupinfo_caches[i]) | ||
| 2428 | kmem_cache_destroy(ext4_groupinfo_caches[i]); | ||
| 2429 | ext4_groupinfo_caches[i] = NULL; | ||
| 2430 | } | ||
| 2431 | } | ||
| 2432 | |||
| 2433 | static int ext4_groupinfo_create_slab(size_t size) | ||
| 2434 | { | ||
| 2435 | static DEFINE_MUTEX(ext4_grpinfo_slab_create_mutex); | ||
| 2436 | int slab_size; | ||
| 2437 | int blocksize_bits = order_base_2(size); | ||
| 2438 | int cache_index = blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE; | ||
| 2439 | struct kmem_cache *cachep; | ||
| 2440 | |||
| 2441 | if (cache_index >= NR_GRPINFO_CACHES) | ||
| 2442 | return -EINVAL; | ||
| 2443 | |||
| 2444 | if (unlikely(cache_index < 0)) | ||
| 2445 | cache_index = 0; | ||
| 2446 | |||
| 2447 | mutex_lock(&ext4_grpinfo_slab_create_mutex); | ||
| 2448 | if (ext4_groupinfo_caches[cache_index]) { | ||
| 2449 | mutex_unlock(&ext4_grpinfo_slab_create_mutex); | ||
| 2450 | return 0; /* Already created */ | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | slab_size = offsetof(struct ext4_group_info, | ||
| 2454 | bb_counters[blocksize_bits + 2]); | ||
| 2455 | |||
| 2456 | cachep = kmem_cache_create(ext4_groupinfo_slab_names[cache_index], | ||
| 2457 | slab_size, 0, SLAB_RECLAIM_ACCOUNT, | ||
| 2458 | NULL); | ||
| 2459 | |||
| 2460 | mutex_unlock(&ext4_grpinfo_slab_create_mutex); | ||
| 2461 | if (!cachep) { | ||
| 2462 | printk(KERN_EMERG "EXT4: no memory for groupinfo slab cache\n"); | ||
| 2463 | return -ENOMEM; | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | ext4_groupinfo_caches[cache_index] = cachep; | ||
| 2467 | |||
| 2468 | return 0; | ||
| 2469 | } | ||
| 2470 | |||
| 2417 | int ext4_mb_init(struct super_block *sb, int needs_recovery) | 2471 | int ext4_mb_init(struct super_block *sb, int needs_recovery) |
| 2418 | { | 2472 | { |
| 2419 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2473 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| @@ -2421,9 +2475,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
| 2421 | unsigned offset; | 2475 | unsigned offset; |
| 2422 | unsigned max; | 2476 | unsigned max; |
| 2423 | int ret; | 2477 | int ret; |
| 2424 | int cache_index; | ||
| 2425 | struct kmem_cache *cachep; | ||
| 2426 | char *namep = NULL; | ||
| 2427 | 2478 | ||
| 2428 | i = (sb->s_blocksize_bits + 2) * sizeof(*sbi->s_mb_offsets); | 2479 | i = (sb->s_blocksize_bits + 2) * sizeof(*sbi->s_mb_offsets); |
| 2429 | 2480 | ||
| @@ -2440,30 +2491,9 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
| 2440 | goto out; | 2491 | goto out; |
| 2441 | } | 2492 | } |
| 2442 | 2493 | ||
| 2443 | cache_index = sb->s_blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE; | 2494 | ret = ext4_groupinfo_create_slab(sb->s_blocksize); |
| 2444 | cachep = ext4_groupinfo_caches[cache_index]; | 2495 | if (ret < 0) |
| 2445 | if (!cachep) { | 2496 | goto out; |
| 2446 | char name[32]; | ||
| 2447 | int len = offsetof(struct ext4_group_info, | ||
| 2448 | bb_counters[sb->s_blocksize_bits + 2]); | ||
| 2449 | |||
| 2450 | sprintf(name, "ext4_groupinfo_%d", sb->s_blocksize_bits); | ||
| 2451 | namep = kstrdup(name, GFP_KERNEL); | ||
| 2452 | if (!namep) { | ||
| 2453 | ret = -ENOMEM; | ||
| 2454 | goto out; | ||
| 2455 | } | ||
| 2456 | |||
| 2457 | /* Need to free the kmem_cache_name() when we | ||
| 2458 | * destroy the slab */ | ||
| 2459 | cachep = kmem_cache_create(namep, len, 0, | ||
| 2460 | SLAB_RECLAIM_ACCOUNT, NULL); | ||
| 2461 | if (!cachep) { | ||
| 2462 | ret = -ENOMEM; | ||
| 2463 | goto out; | ||
| 2464 | } | ||
| 2465 | ext4_groupinfo_caches[cache_index] = cachep; | ||
| 2466 | } | ||
| 2467 | 2497 | ||
| 2468 | /* order 0 is regular bitmap */ | 2498 | /* order 0 is regular bitmap */ |
| 2469 | sbi->s_mb_maxs[0] = sb->s_blocksize << 3; | 2499 | sbi->s_mb_maxs[0] = sb->s_blocksize << 3; |
| @@ -2520,7 +2550,6 @@ out: | |||
| 2520 | if (ret) { | 2550 | if (ret) { |
| 2521 | kfree(sbi->s_mb_offsets); | 2551 | kfree(sbi->s_mb_offsets); |
| 2522 | kfree(sbi->s_mb_maxs); | 2552 | kfree(sbi->s_mb_maxs); |
| 2523 | kfree(namep); | ||
| 2524 | } | 2553 | } |
| 2525 | return ret; | 2554 | return ret; |
| 2526 | } | 2555 | } |
| @@ -2734,7 +2763,6 @@ int __init ext4_init_mballoc(void) | |||
| 2734 | 2763 | ||
| 2735 | void ext4_exit_mballoc(void) | 2764 | void ext4_exit_mballoc(void) |
| 2736 | { | 2765 | { |
| 2737 | int i; | ||
| 2738 | /* | 2766 | /* |
| 2739 | * Wait for completion of call_rcu()'s on ext4_pspace_cachep | 2767 | * Wait for completion of call_rcu()'s on ext4_pspace_cachep |
| 2740 | * before destroying the slab cache. | 2768 | * before destroying the slab cache. |
| @@ -2743,15 +2771,7 @@ void ext4_exit_mballoc(void) | |||
| 2743 | kmem_cache_destroy(ext4_pspace_cachep); | 2771 | kmem_cache_destroy(ext4_pspace_cachep); |
| 2744 | kmem_cache_destroy(ext4_ac_cachep); | 2772 | kmem_cache_destroy(ext4_ac_cachep); |
| 2745 | kmem_cache_destroy(ext4_free_ext_cachep); | 2773 | kmem_cache_destroy(ext4_free_ext_cachep); |
| 2746 | 2774 | ext4_groupinfo_destroy_slabs(); | |
| 2747 | for (i = 0; i < NR_GRPINFO_CACHES; i++) { | ||
| 2748 | struct kmem_cache *cachep = ext4_groupinfo_caches[i]; | ||
| 2749 | if (cachep) { | ||
| 2750 | char *name = (char *)kmem_cache_name(cachep); | ||
| 2751 | kmem_cache_destroy(cachep); | ||
| 2752 | kfree(name); | ||
| 2753 | } | ||
| 2754 | } | ||
| 2755 | ext4_remove_debugfs_entry(); | 2775 | ext4_remove_debugfs_entry(); |
| 2756 | } | 2776 | } |
| 2757 | 2777 | ||
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 7270dcfca92..955cc309142 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
| @@ -32,14 +32,8 @@ | |||
| 32 | 32 | ||
| 33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; | 33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; |
| 34 | 34 | ||
| 35 | #define WQ_HASH_SZ 37 | ||
| 36 | #define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ]) | ||
| 37 | static wait_queue_head_t ioend_wq[WQ_HASH_SZ]; | ||
| 38 | |||
| 39 | int __init ext4_init_pageio(void) | 35 | int __init ext4_init_pageio(void) |
| 40 | { | 36 | { |
| 41 | int i; | ||
| 42 | |||
| 43 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); | 37 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); |
| 44 | if (io_page_cachep == NULL) | 38 | if (io_page_cachep == NULL) |
| 45 | return -ENOMEM; | 39 | return -ENOMEM; |
| @@ -48,9 +42,6 @@ int __init ext4_init_pageio(void) | |||
| 48 | kmem_cache_destroy(io_page_cachep); | 42 | kmem_cache_destroy(io_page_cachep); |
| 49 | return -ENOMEM; | 43 | return -ENOMEM; |
| 50 | } | 44 | } |
| 51 | for (i = 0; i < WQ_HASH_SZ; i++) | ||
| 52 | init_waitqueue_head(&ioend_wq[i]); | ||
| 53 | |||
| 54 | return 0; | 45 | return 0; |
| 55 | } | 46 | } |
| 56 | 47 | ||
| @@ -62,7 +53,7 @@ void ext4_exit_pageio(void) | |||
| 62 | 53 | ||
| 63 | void ext4_ioend_wait(struct inode *inode) | 54 | void ext4_ioend_wait(struct inode *inode) |
| 64 | { | 55 | { |
| 65 | wait_queue_head_t *wq = to_ioend_wq(inode); | 56 | wait_queue_head_t *wq = ext4_ioend_wq(inode); |
| 66 | 57 | ||
| 67 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); | 58 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); |
| 68 | } | 59 | } |
| @@ -87,7 +78,7 @@ void ext4_free_io_end(ext4_io_end_t *io) | |||
| 87 | for (i = 0; i < io->num_io_pages; i++) | 78 | for (i = 0; i < io->num_io_pages; i++) |
| 88 | put_io_page(io->pages[i]); | 79 | put_io_page(io->pages[i]); |
| 89 | io->num_io_pages = 0; | 80 | io->num_io_pages = 0; |
| 90 | wq = to_ioend_wq(io->inode); | 81 | wq = ext4_ioend_wq(io->inode); |
| 91 | if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) && | 82 | if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) && |
| 92 | waitqueue_active(wq)) | 83 | waitqueue_active(wq)) |
| 93 | wake_up_all(wq); | 84 | wake_up_all(wq); |
| @@ -102,6 +93,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io) | |||
| 102 | struct inode *inode = io->inode; | 93 | struct inode *inode = io->inode; |
| 103 | loff_t offset = io->offset; | 94 | loff_t offset = io->offset; |
| 104 | ssize_t size = io->size; | 95 | ssize_t size = io->size; |
| 96 | wait_queue_head_t *wq; | ||
| 105 | int ret = 0; | 97 | int ret = 0; |
| 106 | 98 | ||
| 107 | ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p," | 99 | ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p," |
| @@ -126,7 +118,16 @@ int ext4_end_io_nolock(ext4_io_end_t *io) | |||
| 126 | if (io->iocb) | 118 | if (io->iocb) |
| 127 | aio_complete(io->iocb, io->result, 0); | 119 | aio_complete(io->iocb, io->result, 0); |
| 128 | /* clear the DIO AIO unwritten flag */ | 120 | /* clear the DIO AIO unwritten flag */ |
| 129 | io->flag &= ~EXT4_IO_END_UNWRITTEN; | 121 | if (io->flag & EXT4_IO_END_UNWRITTEN) { |
| 122 | io->flag &= ~EXT4_IO_END_UNWRITTEN; | ||
| 123 | /* Wake up anyone waiting on unwritten extent conversion */ | ||
| 124 | wq = ext4_ioend_wq(io->inode); | ||
| 125 | if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten) && | ||
| 126 | waitqueue_active(wq)) { | ||
| 127 | wake_up_all(wq); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 130 | return ret; | 131 | return ret; |
| 131 | } | 132 | } |
| 132 | 133 | ||
| @@ -190,6 +191,7 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
| 190 | struct inode *inode; | 191 | struct inode *inode; |
| 191 | unsigned long flags; | 192 | unsigned long flags; |
| 192 | int i; | 193 | int i; |
| 194 | sector_t bi_sector = bio->bi_sector; | ||
| 193 | 195 | ||
| 194 | BUG_ON(!io_end); | 196 | BUG_ON(!io_end); |
| 195 | bio->bi_private = NULL; | 197 | bio->bi_private = NULL; |
| @@ -207,9 +209,7 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
| 207 | if (error) | 209 | if (error) |
| 208 | SetPageError(page); | 210 | SetPageError(page); |
| 209 | BUG_ON(!head); | 211 | BUG_ON(!head); |
| 210 | if (head->b_size == PAGE_CACHE_SIZE) | 212 | if (head->b_size != PAGE_CACHE_SIZE) { |
| 211 | clear_buffer_dirty(head); | ||
| 212 | else { | ||
| 213 | loff_t offset; | 213 | loff_t offset; |
| 214 | loff_t io_end_offset = io_end->offset + io_end->size; | 214 | loff_t io_end_offset = io_end->offset + io_end->size; |
| 215 | 215 | ||
| @@ -221,7 +221,6 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
| 221 | if (error) | 221 | if (error) |
| 222 | buffer_io_error(bh); | 222 | buffer_io_error(bh); |
| 223 | 223 | ||
| 224 | clear_buffer_dirty(bh); | ||
| 225 | } | 224 | } |
| 226 | if (buffer_delay(bh)) | 225 | if (buffer_delay(bh)) |
| 227 | partial_write = 1; | 226 | partial_write = 1; |
| @@ -257,7 +256,7 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
| 257 | (unsigned long long) io_end->offset, | 256 | (unsigned long long) io_end->offset, |
| 258 | (long) io_end->size, | 257 | (long) io_end->size, |
| 259 | (unsigned long long) | 258 | (unsigned long long) |
| 260 | bio->bi_sector >> (inode->i_blkbits - 9)); | 259 | bi_sector >> (inode->i_blkbits - 9)); |
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | /* Add the io_end to per-inode completed io list*/ | 262 | /* Add the io_end to per-inode completed io list*/ |
| @@ -380,6 +379,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
| 380 | 379 | ||
| 381 | blocksize = 1 << inode->i_blkbits; | 380 | blocksize = 1 << inode->i_blkbits; |
| 382 | 381 | ||
| 382 | BUG_ON(!PageLocked(page)); | ||
| 383 | BUG_ON(PageWriteback(page)); | 383 | BUG_ON(PageWriteback(page)); |
| 384 | set_page_writeback(page); | 384 | set_page_writeback(page); |
| 385 | ClearPageError(page); | 385 | ClearPageError(page); |
| @@ -397,12 +397,14 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
| 397 | for (bh = head = page_buffers(page), block_start = 0; | 397 | for (bh = head = page_buffers(page), block_start = 0; |
| 398 | bh != head || !block_start; | 398 | bh != head || !block_start; |
| 399 | block_start = block_end, bh = bh->b_this_page) { | 399 | block_start = block_end, bh = bh->b_this_page) { |
| 400 | |||
| 400 | block_end = block_start + blocksize; | 401 | block_end = block_start + blocksize; |
| 401 | if (block_start >= len) { | 402 | if (block_start >= len) { |
| 402 | clear_buffer_dirty(bh); | 403 | clear_buffer_dirty(bh); |
| 403 | set_buffer_uptodate(bh); | 404 | set_buffer_uptodate(bh); |
| 404 | continue; | 405 | continue; |
| 405 | } | 406 | } |
| 407 | clear_buffer_dirty(bh); | ||
| 406 | ret = io_submit_add_bh(io, io_page, inode, wbc, bh); | 408 | ret = io_submit_add_bh(io, io_page, inode, wbc, bh); |
| 407 | if (ret) { | 409 | if (ret) { |
| 408 | /* | 410 | /* |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 48ce561fafa..f6a318f836b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -77,6 +77,7 @@ static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags, | |||
| 77 | const char *dev_name, void *data); | 77 | const char *dev_name, void *data); |
| 78 | static void ext4_destroy_lazyinit_thread(void); | 78 | static void ext4_destroy_lazyinit_thread(void); |
| 79 | static void ext4_unregister_li_request(struct super_block *sb); | 79 | static void ext4_unregister_li_request(struct super_block *sb); |
| 80 | static void ext4_clear_request_list(void); | ||
| 80 | 81 | ||
| 81 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | 82 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |
| 82 | static struct file_system_type ext3_fs_type = { | 83 | static struct file_system_type ext3_fs_type = { |
| @@ -832,6 +833,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
| 832 | ei->i_sync_tid = 0; | 833 | ei->i_sync_tid = 0; |
| 833 | ei->i_datasync_tid = 0; | 834 | ei->i_datasync_tid = 0; |
| 834 | atomic_set(&ei->i_ioend_count, 0); | 835 | atomic_set(&ei->i_ioend_count, 0); |
| 836 | atomic_set(&ei->i_aiodio_unwritten, 0); | ||
| 835 | 837 | ||
| 836 | return &ei->vfs_inode; | 838 | return &ei->vfs_inode; |
| 837 | } | 839 | } |
| @@ -2716,6 +2718,8 @@ static void ext4_unregister_li_request(struct super_block *sb) | |||
| 2716 | mutex_unlock(&ext4_li_info->li_list_mtx); | 2718 | mutex_unlock(&ext4_li_info->li_list_mtx); |
| 2717 | } | 2719 | } |
| 2718 | 2720 | ||
| 2721 | static struct task_struct *ext4_lazyinit_task; | ||
| 2722 | |||
| 2719 | /* | 2723 | /* |
| 2720 | * This is the function where ext4lazyinit thread lives. It walks | 2724 | * This is the function where ext4lazyinit thread lives. It walks |
| 2721 | * through the request list searching for next scheduled filesystem. | 2725 | * through the request list searching for next scheduled filesystem. |
| @@ -2784,6 +2788,10 @@ cont_thread: | |||
| 2784 | if (time_before(jiffies, next_wakeup)) | 2788 | if (time_before(jiffies, next_wakeup)) |
| 2785 | schedule(); | 2789 | schedule(); |
| 2786 | finish_wait(&eli->li_wait_daemon, &wait); | 2790 | finish_wait(&eli->li_wait_daemon, &wait); |
| 2791 | if (kthread_should_stop()) { | ||
| 2792 | ext4_clear_request_list(); | ||
| 2793 | goto exit_thread; | ||
| 2794 | } | ||
| 2787 | } | 2795 | } |
| 2788 | 2796 | ||
| 2789 | exit_thread: | 2797 | exit_thread: |
| @@ -2808,6 +2816,7 @@ exit_thread: | |||
| 2808 | wake_up(&eli->li_wait_task); | 2816 | wake_up(&eli->li_wait_task); |
| 2809 | 2817 | ||
| 2810 | kfree(ext4_li_info); | 2818 | kfree(ext4_li_info); |
| 2819 | ext4_lazyinit_task = NULL; | ||
| 2811 | ext4_li_info = NULL; | 2820 | ext4_li_info = NULL; |
| 2812 | mutex_unlock(&ext4_li_mtx); | 2821 | mutex_unlock(&ext4_li_mtx); |
| 2813 | 2822 | ||
| @@ -2830,11 +2839,10 @@ static void ext4_clear_request_list(void) | |||
| 2830 | 2839 | ||
| 2831 | static int ext4_run_lazyinit_thread(void) | 2840 | static int ext4_run_lazyinit_thread(void) |
| 2832 | { | 2841 | { |
| 2833 | struct task_struct *t; | 2842 | ext4_lazyinit_task = kthread_run(ext4_lazyinit_thread, |
| 2834 | 2843 | ext4_li_info, "ext4lazyinit"); | |
| 2835 | t = kthread_run(ext4_lazyinit_thread, ext4_li_info, "ext4lazyinit"); | 2844 | if (IS_ERR(ext4_lazyinit_task)) { |
| 2836 | if (IS_ERR(t)) { | 2845 | int err = PTR_ERR(ext4_lazyinit_task); |
| 2837 | int err = PTR_ERR(t); | ||
| 2838 | ext4_clear_request_list(); | 2846 | ext4_clear_request_list(); |
| 2839 | del_timer_sync(&ext4_li_info->li_timer); | 2847 | del_timer_sync(&ext4_li_info->li_timer); |
| 2840 | kfree(ext4_li_info); | 2848 | kfree(ext4_li_info); |
| @@ -2985,16 +2993,10 @@ static void ext4_destroy_lazyinit_thread(void) | |||
| 2985 | * If thread exited earlier | 2993 | * If thread exited earlier |
| 2986 | * there's nothing to be done. | 2994 | * there's nothing to be done. |
| 2987 | */ | 2995 | */ |
| 2988 | if (!ext4_li_info) | 2996 | if (!ext4_li_info || !ext4_lazyinit_task) |
| 2989 | return; | 2997 | return; |
| 2990 | 2998 | ||
| 2991 | ext4_clear_request_list(); | 2999 | kthread_stop(ext4_lazyinit_task); |
| 2992 | |||
| 2993 | while (ext4_li_info->li_task) { | ||
| 2994 | wake_up(&ext4_li_info->li_wait_daemon); | ||
| 2995 | wait_event(ext4_li_info->li_wait_task, | ||
| 2996 | ext4_li_info->li_task == NULL); | ||
| 2997 | } | ||
| 2998 | } | 3000 | } |
| 2999 | 3001 | ||
| 3000 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 3002 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
| @@ -4768,7 +4770,7 @@ static struct file_system_type ext4_fs_type = { | |||
| 4768 | .fs_flags = FS_REQUIRES_DEV, | 4770 | .fs_flags = FS_REQUIRES_DEV, |
| 4769 | }; | 4771 | }; |
| 4770 | 4772 | ||
| 4771 | int __init ext4_init_feat_adverts(void) | 4773 | static int __init ext4_init_feat_adverts(void) |
| 4772 | { | 4774 | { |
| 4773 | struct ext4_features *ef; | 4775 | struct ext4_features *ef; |
| 4774 | int ret = -ENOMEM; | 4776 | int ret = -ENOMEM; |
| @@ -4792,23 +4794,44 @@ out: | |||
| 4792 | return ret; | 4794 | return ret; |
| 4793 | } | 4795 | } |
| 4794 | 4796 | ||
| 4797 | static void ext4_exit_feat_adverts(void) | ||
| 4798 | { | ||
| 4799 | kobject_put(&ext4_feat->f_kobj); | ||
| 4800 | wait_for_completion(&ext4_feat->f_kobj_unregister); | ||
| 4801 | kfree(ext4_feat); | ||
| 4802 | } | ||
| 4803 | |||
| 4804 | /* Shared across all ext4 file systems */ | ||
| 4805 | wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ]; | ||
| 4806 | struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ]; | ||
| 4807 | |||
| 4795 | static int __init ext4_init_fs(void) | 4808 | static int __init ext4_init_fs(void) |
| 4796 | { | 4809 | { |
| 4797 | int err; | 4810 | int i, err; |
| 4798 | 4811 | ||
| 4799 | ext4_check_flag_values(); | 4812 | ext4_check_flag_values(); |
| 4813 | |||
| 4814 | for (i = 0; i < EXT4_WQ_HASH_SZ; i++) { | ||
| 4815 | mutex_init(&ext4__aio_mutex[i]); | ||
| 4816 | init_waitqueue_head(&ext4__ioend_wq[i]); | ||
| 4817 | } | ||
| 4818 | |||
| 4800 | err = ext4_init_pageio(); | 4819 | err = ext4_init_pageio(); |
| 4801 | if (err) | 4820 | if (err) |
| 4802 | return err; | 4821 | return err; |
| 4803 | err = ext4_init_system_zone(); | 4822 | err = ext4_init_system_zone(); |
| 4804 | if (err) | 4823 | if (err) |
| 4805 | goto out5; | 4824 | goto out7; |
| 4806 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); | 4825 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); |
| 4807 | if (!ext4_kset) | 4826 | if (!ext4_kset) |
| 4808 | goto out4; | 4827 | goto out6; |
| 4809 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); | 4828 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); |
| 4829 | if (!ext4_proc_root) | ||
| 4830 | goto out5; | ||
| 4810 | 4831 | ||
| 4811 | err = ext4_init_feat_adverts(); | 4832 | err = ext4_init_feat_adverts(); |
| 4833 | if (err) | ||
| 4834 | goto out4; | ||
| 4812 | 4835 | ||
| 4813 | err = ext4_init_mballoc(); | 4836 | err = ext4_init_mballoc(); |
| 4814 | if (err) | 4837 | if (err) |
| @@ -4838,12 +4861,14 @@ out1: | |||
| 4838 | out2: | 4861 | out2: |
| 4839 | ext4_exit_mballoc(); | 4862 | ext4_exit_mballoc(); |
| 4840 | out3: | 4863 | out3: |
| 4841 | kfree(ext4_feat); | 4864 | ext4_exit_feat_adverts(); |
| 4865 | out4: | ||
| 4842 | remove_proc_entry("fs/ext4", NULL); | 4866 | remove_proc_entry("fs/ext4", NULL); |
| 4867 | out5: | ||
| 4843 | kset_unregister(ext4_kset); | 4868 | kset_unregister(ext4_kset); |
| 4844 | out4: | 4869 | out6: |
| 4845 | ext4_exit_system_zone(); | 4870 | ext4_exit_system_zone(); |
| 4846 | out5: | 4871 | out7: |
| 4847 | ext4_exit_pageio(); | 4872 | ext4_exit_pageio(); |
| 4848 | return err; | 4873 | return err; |
| 4849 | } | 4874 | } |
| @@ -4857,6 +4882,7 @@ static void __exit ext4_exit_fs(void) | |||
| 4857 | destroy_inodecache(); | 4882 | destroy_inodecache(); |
| 4858 | ext4_exit_xattr(); | 4883 | ext4_exit_xattr(); |
| 4859 | ext4_exit_mballoc(); | 4884 | ext4_exit_mballoc(); |
| 4885 | ext4_exit_feat_adverts(); | ||
| 4860 | remove_proc_entry("fs/ext4", NULL); | 4886 | remove_proc_entry("fs/ext4", NULL); |
| 4861 | kset_unregister(ext4_kset); | 4887 | kset_unregister(ext4_kset); |
| 4862 | ext4_exit_system_zone(); | 4888 | ext4_exit_system_zone(); |
diff --git a/fs/file_table.c b/fs/file_table.c index c3e89adf53c..eb36b6b17e2 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
| @@ -125,13 +125,13 @@ struct file *get_empty_filp(void) | |||
| 125 | goto fail; | 125 | goto fail; |
| 126 | 126 | ||
| 127 | percpu_counter_inc(&nr_files); | 127 | percpu_counter_inc(&nr_files); |
| 128 | f->f_cred = get_cred(cred); | ||
| 128 | if (security_file_alloc(f)) | 129 | if (security_file_alloc(f)) |
| 129 | goto fail_sec; | 130 | goto fail_sec; |
| 130 | 131 | ||
| 131 | INIT_LIST_HEAD(&f->f_u.fu_list); | 132 | INIT_LIST_HEAD(&f->f_u.fu_list); |
| 132 | atomic_long_set(&f->f_count, 1); | 133 | atomic_long_set(&f->f_count, 1); |
| 133 | rwlock_init(&f->f_owner.lock); | 134 | rwlock_init(&f->f_owner.lock); |
| 134 | f->f_cred = get_cred(cred); | ||
| 135 | spin_lock_init(&f->f_lock); | 135 | spin_lock_init(&f->f_lock); |
| 136 | eventpoll_init_file(f); | 136 | eventpoll_init_file(f); |
| 137 | /* f->f_version: 0 */ | 137 | /* f->f_version: 0 */ |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 08a8beb152e..7cd9a5a68d5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -1779,11 +1779,11 @@ int __init gfs2_glock_init(void) | |||
| 1779 | #endif | 1779 | #endif |
| 1780 | 1780 | ||
| 1781 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | | 1781 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | |
| 1782 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | 1782 | WQ_HIGHPRI | WQ_FREEZABLE, 0); |
| 1783 | if (IS_ERR(glock_workqueue)) | 1783 | if (IS_ERR(glock_workqueue)) |
| 1784 | return PTR_ERR(glock_workqueue); | 1784 | return PTR_ERR(glock_workqueue); |
| 1785 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", | 1785 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", |
| 1786 | WQ_MEM_RECLAIM | WQ_FREEZEABLE, | 1786 | WQ_MEM_RECLAIM | WQ_FREEZABLE, |
| 1787 | 0); | 1787 | 0); |
| 1788 | if (IS_ERR(gfs2_delete_workqueue)) { | 1788 | if (IS_ERR(gfs2_delete_workqueue)) { |
| 1789 | destroy_workqueue(glock_workqueue); | 1789 | destroy_workqueue(glock_workqueue); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index ebef7ab6e17..85ba027d1c4 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
| @@ -144,7 +144,7 @@ static int __init init_gfs2_fs(void) | |||
| 144 | 144 | ||
| 145 | error = -ENOMEM; | 145 | error = -ENOMEM; |
| 146 | gfs_recovery_wq = alloc_workqueue("gfs_recovery", | 146 | gfs_recovery_wq = alloc_workqueue("gfs_recovery", |
| 147 | WQ_MEM_RECLAIM | WQ_FREEZEABLE, 0); | 147 | WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); |
| 148 | if (!gfs_recovery_wq) | 148 | if (!gfs_recovery_wq) |
| 149 | goto fail_wq; | 149 | goto fail_wq; |
| 150 | 150 | ||
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 52a0bcaa7b6..b1991a2a08e 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
| @@ -397,8 +397,8 @@ int hfsplus_file_extend(struct inode *inode) | |||
| 397 | u32 start, len, goal; | 397 | u32 start, len, goal; |
| 398 | int res; | 398 | int res; |
| 399 | 399 | ||
| 400 | if (sbi->total_blocks - sbi->free_blocks + 8 > | 400 | if (sbi->alloc_file->i_size * 8 < |
| 401 | sbi->alloc_file->i_size * 8) { | 401 | sbi->total_blocks - sbi->free_blocks + 8) { |
| 402 | /* extend alloc file */ | 402 | /* extend alloc file */ |
| 403 | printk(KERN_ERR "hfs: extend alloc file! " | 403 | printk(KERN_ERR "hfs: extend alloc file! " |
| 404 | "(%llu,%u,%u)\n", | 404 | "(%llu,%u,%u)\n", |
diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index d66ad113b1c..40ad88c12c6 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c | |||
| @@ -134,7 +134,7 @@ int hfs_part_find(struct super_block *sb, | |||
| 134 | res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, | 134 | res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, |
| 135 | data, READ); | 135 | data, READ); |
| 136 | if (res) | 136 | if (res) |
| 137 | return res; | 137 | goto out; |
| 138 | 138 | ||
| 139 | switch (be16_to_cpu(*((__be16 *)data))) { | 139 | switch (be16_to_cpu(*((__be16 *)data))) { |
| 140 | case HFS_OLD_PMAP_MAGIC: | 140 | case HFS_OLD_PMAP_MAGIC: |
| @@ -147,7 +147,7 @@ int hfs_part_find(struct super_block *sb, | |||
| 147 | res = -ENOENT; | 147 | res = -ENOENT; |
| 148 | break; | 148 | break; |
| 149 | } | 149 | } |
| 150 | 150 | out: | |
| 151 | kfree(data); | 151 | kfree(data); |
| 152 | return res; | 152 | return res; |
| 153 | } | 153 | } |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 9a3b4795f43..b49b55584c8 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -338,20 +338,22 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 338 | struct inode *root, *inode; | 338 | struct inode *root, *inode; |
| 339 | struct qstr str; | 339 | struct qstr str; |
| 340 | struct nls_table *nls = NULL; | 340 | struct nls_table *nls = NULL; |
| 341 | int err = -EINVAL; | 341 | int err; |
| 342 | 342 | ||
| 343 | err = -EINVAL; | ||
| 343 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 344 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
| 344 | if (!sbi) | 345 | if (!sbi) |
| 345 | return -ENOMEM; | 346 | goto out; |
| 346 | 347 | ||
| 347 | sb->s_fs_info = sbi; | 348 | sb->s_fs_info = sbi; |
| 348 | mutex_init(&sbi->alloc_mutex); | 349 | mutex_init(&sbi->alloc_mutex); |
| 349 | mutex_init(&sbi->vh_mutex); | 350 | mutex_init(&sbi->vh_mutex); |
| 350 | hfsplus_fill_defaults(sbi); | 351 | hfsplus_fill_defaults(sbi); |
| 352 | |||
| 353 | err = -EINVAL; | ||
| 351 | if (!hfsplus_parse_options(data, sbi)) { | 354 | if (!hfsplus_parse_options(data, sbi)) { |
| 352 | printk(KERN_ERR "hfs: unable to parse mount options\n"); | 355 | printk(KERN_ERR "hfs: unable to parse mount options\n"); |
| 353 | err = -EINVAL; | 356 | goto out_unload_nls; |
| 354 | goto cleanup; | ||
| 355 | } | 357 | } |
| 356 | 358 | ||
| 357 | /* temporarily use utf8 to correctly find the hidden dir below */ | 359 | /* temporarily use utf8 to correctly find the hidden dir below */ |
| @@ -359,16 +361,14 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 359 | sbi->nls = load_nls("utf8"); | 361 | sbi->nls = load_nls("utf8"); |
| 360 | if (!sbi->nls) { | 362 | if (!sbi->nls) { |
| 361 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); | 363 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); |
| 362 | err = -EINVAL; | 364 | goto out_unload_nls; |
| 363 | goto cleanup; | ||
| 364 | } | 365 | } |
| 365 | 366 | ||
| 366 | /* Grab the volume header */ | 367 | /* Grab the volume header */ |
| 367 | if (hfsplus_read_wrapper(sb)) { | 368 | if (hfsplus_read_wrapper(sb)) { |
| 368 | if (!silent) | 369 | if (!silent) |
| 369 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); | 370 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); |
| 370 | err = -EINVAL; | 371 | goto out_unload_nls; |
| 371 | goto cleanup; | ||
| 372 | } | 372 | } |
| 373 | vhdr = sbi->s_vhdr; | 373 | vhdr = sbi->s_vhdr; |
| 374 | 374 | ||
| @@ -377,7 +377,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 377 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || | 377 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || |
| 378 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { | 378 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { |
| 379 | printk(KERN_ERR "hfs: wrong filesystem version\n"); | 379 | printk(KERN_ERR "hfs: wrong filesystem version\n"); |
| 380 | goto cleanup; | 380 | goto out_free_vhdr; |
| 381 | } | 381 | } |
| 382 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); | 382 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); |
| 383 | sbi->free_blocks = be32_to_cpu(vhdr->free_blocks); | 383 | sbi->free_blocks = be32_to_cpu(vhdr->free_blocks); |
| @@ -421,19 +421,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 421 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); | 421 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); |
| 422 | if (!sbi->ext_tree) { | 422 | if (!sbi->ext_tree) { |
| 423 | printk(KERN_ERR "hfs: failed to load extents file\n"); | 423 | printk(KERN_ERR "hfs: failed to load extents file\n"); |
| 424 | goto cleanup; | 424 | goto out_free_vhdr; |
| 425 | } | 425 | } |
| 426 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); | 426 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); |
| 427 | if (!sbi->cat_tree) { | 427 | if (!sbi->cat_tree) { |
| 428 | printk(KERN_ERR "hfs: failed to load catalog file\n"); | 428 | printk(KERN_ERR "hfs: failed to load catalog file\n"); |
| 429 | goto cleanup; | 429 | goto out_close_ext_tree; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); | 432 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); |
| 433 | if (IS_ERR(inode)) { | 433 | if (IS_ERR(inode)) { |
| 434 | printk(KERN_ERR "hfs: failed to load allocation file\n"); | 434 | printk(KERN_ERR "hfs: failed to load allocation file\n"); |
| 435 | err = PTR_ERR(inode); | 435 | err = PTR_ERR(inode); |
| 436 | goto cleanup; | 436 | goto out_close_cat_tree; |
| 437 | } | 437 | } |
| 438 | sbi->alloc_file = inode; | 438 | sbi->alloc_file = inode; |
| 439 | 439 | ||
| @@ -442,14 +442,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 442 | if (IS_ERR(root)) { | 442 | if (IS_ERR(root)) { |
| 443 | printk(KERN_ERR "hfs: failed to load root directory\n"); | 443 | printk(KERN_ERR "hfs: failed to load root directory\n"); |
| 444 | err = PTR_ERR(root); | 444 | err = PTR_ERR(root); |
| 445 | goto cleanup; | 445 | goto out_put_alloc_file; |
| 446 | } | ||
| 447 | sb->s_d_op = &hfsplus_dentry_operations; | ||
| 448 | sb->s_root = d_alloc_root(root); | ||
| 449 | if (!sb->s_root) { | ||
| 450 | iput(root); | ||
| 451 | err = -ENOMEM; | ||
| 452 | goto cleanup; | ||
| 453 | } | 446 | } |
| 454 | 447 | ||
| 455 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; | 448 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; |
| @@ -459,46 +452,69 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 459 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { | 452 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { |
| 460 | hfs_find_exit(&fd); | 453 | hfs_find_exit(&fd); |
| 461 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) | 454 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) |
| 462 | goto cleanup; | 455 | goto out_put_root; |
| 463 | inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); | 456 | inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); |
| 464 | if (IS_ERR(inode)) { | 457 | if (IS_ERR(inode)) { |
| 465 | err = PTR_ERR(inode); | 458 | err = PTR_ERR(inode); |
| 466 | goto cleanup; | 459 | goto out_put_root; |
| 467 | } | 460 | } |
| 468 | sbi->hidden_dir = inode; | 461 | sbi->hidden_dir = inode; |
| 469 | } else | 462 | } else |
| 470 | hfs_find_exit(&fd); | 463 | hfs_find_exit(&fd); |
| 471 | 464 | ||
| 472 | if (sb->s_flags & MS_RDONLY) | 465 | if (!(sb->s_flags & MS_RDONLY)) { |
| 473 | goto out; | 466 | /* |
| 467 | * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused | ||
| 468 | * all three are registered with Apple for our use | ||
| 469 | */ | ||
| 470 | vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); | ||
| 471 | vhdr->modify_date = hfsp_now2mt(); | ||
| 472 | be32_add_cpu(&vhdr->write_count, 1); | ||
| 473 | vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); | ||
| 474 | vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); | ||
| 475 | hfsplus_sync_fs(sb, 1); | ||
| 474 | 476 | ||
| 475 | /* H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused | 477 | if (!sbi->hidden_dir) { |
| 476 | * all three are registered with Apple for our use | 478 | mutex_lock(&sbi->vh_mutex); |
| 477 | */ | 479 | sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); |
| 478 | vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); | 480 | hfsplus_create_cat(sbi->hidden_dir->i_ino, root, &str, |
| 479 | vhdr->modify_date = hfsp_now2mt(); | 481 | sbi->hidden_dir); |
| 480 | be32_add_cpu(&vhdr->write_count, 1); | 482 | mutex_unlock(&sbi->vh_mutex); |
| 481 | vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); | 483 | |
| 482 | vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); | 484 | hfsplus_mark_inode_dirty(sbi->hidden_dir, |
| 483 | hfsplus_sync_fs(sb, 1); | 485 | HFSPLUS_I_CAT_DIRTY); |
| 484 | 486 | } | |
| 485 | if (!sbi->hidden_dir) { | ||
| 486 | mutex_lock(&sbi->vh_mutex); | ||
| 487 | sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); | ||
| 488 | hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode, | ||
| 489 | &str, sbi->hidden_dir); | ||
| 490 | mutex_unlock(&sbi->vh_mutex); | ||
| 491 | |||
| 492 | hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY); | ||
| 493 | } | 487 | } |
| 494 | out: | 488 | |
| 489 | sb->s_d_op = &hfsplus_dentry_operations; | ||
| 490 | sb->s_root = d_alloc_root(root); | ||
| 491 | if (!sb->s_root) { | ||
| 492 | err = -ENOMEM; | ||
| 493 | goto out_put_hidden_dir; | ||
| 494 | } | ||
| 495 | |||
| 495 | unload_nls(sbi->nls); | 496 | unload_nls(sbi->nls); |
| 496 | sbi->nls = nls; | 497 | sbi->nls = nls; |
| 497 | return 0; | 498 | return 0; |
| 498 | 499 | ||
| 499 | cleanup: | 500 | out_put_hidden_dir: |
| 500 | hfsplus_put_super(sb); | 501 | iput(sbi->hidden_dir); |
| 502 | out_put_root: | ||
| 503 | iput(sbi->alloc_file); | ||
| 504 | out_put_alloc_file: | ||
| 505 | iput(sbi->alloc_file); | ||
| 506 | out_close_cat_tree: | ||
| 507 | hfs_btree_close(sbi->cat_tree); | ||
| 508 | out_close_ext_tree: | ||
| 509 | hfs_btree_close(sbi->ext_tree); | ||
| 510 | out_free_vhdr: | ||
| 511 | kfree(sbi->s_vhdr); | ||
| 512 | kfree(sbi->s_backup_vhdr); | ||
| 513 | out_unload_nls: | ||
| 514 | unload_nls(sbi->nls); | ||
| 501 | unload_nls(nls); | 515 | unload_nls(nls); |
| 516 | kfree(sbi); | ||
| 517 | out: | ||
| 502 | return err; | 518 | return err; |
| 503 | } | 519 | } |
| 504 | 520 | ||
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 196231794f6..3031d81f5f0 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
| @@ -167,7 +167,7 @@ reread: | |||
| 167 | break; | 167 | break; |
| 168 | case cpu_to_be16(HFSP_WRAP_MAGIC): | 168 | case cpu_to_be16(HFSP_WRAP_MAGIC): |
| 169 | if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) | 169 | if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) |
| 170 | goto out; | 170 | goto out_free_backup_vhdr; |
| 171 | wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; | 171 | wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; |
| 172 | part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; | 172 | part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; |
| 173 | part_size = wd.embed_count * wd.ablk_size; | 173 | part_size = wd.embed_count * wd.ablk_size; |
| @@ -179,7 +179,7 @@ reread: | |||
| 179 | * (should do this only for cdrom/loop though) | 179 | * (should do this only for cdrom/loop though) |
| 180 | */ | 180 | */ |
| 181 | if (hfs_part_find(sb, &part_start, &part_size)) | 181 | if (hfs_part_find(sb, &part_start, &part_size)) |
| 182 | goto out; | 182 | goto out_free_backup_vhdr; |
| 183 | goto reread; | 183 | goto reread; |
| 184 | } | 184 | } |
| 185 | 185 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 9e4686900f1..97e73469b2c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -473,7 +473,8 @@ int __jbd2_log_space_left(journal_t *journal) | |||
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | /* | 475 | /* |
| 476 | * Called under j_state_lock. Returns true if a transaction commit was started. | 476 | * Called with j_state_lock locked for writing. |
| 477 | * Returns true if a transaction commit was started. | ||
| 477 | */ | 478 | */ |
| 478 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) | 479 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) |
| 479 | { | 480 | { |
| @@ -520,11 +521,13 @@ int jbd2_journal_force_commit_nested(journal_t *journal) | |||
| 520 | { | 521 | { |
| 521 | transaction_t *transaction = NULL; | 522 | transaction_t *transaction = NULL; |
| 522 | tid_t tid; | 523 | tid_t tid; |
| 524 | int need_to_start = 0; | ||
| 523 | 525 | ||
| 524 | read_lock(&journal->j_state_lock); | 526 | read_lock(&journal->j_state_lock); |
| 525 | if (journal->j_running_transaction && !current->journal_info) { | 527 | if (journal->j_running_transaction && !current->journal_info) { |
| 526 | transaction = journal->j_running_transaction; | 528 | transaction = journal->j_running_transaction; |
| 527 | __jbd2_log_start_commit(journal, transaction->t_tid); | 529 | if (!tid_geq(journal->j_commit_request, transaction->t_tid)) |
| 530 | need_to_start = 1; | ||
| 528 | } else if (journal->j_committing_transaction) | 531 | } else if (journal->j_committing_transaction) |
| 529 | transaction = journal->j_committing_transaction; | 532 | transaction = journal->j_committing_transaction; |
| 530 | 533 | ||
| @@ -535,6 +538,8 @@ int jbd2_journal_force_commit_nested(journal_t *journal) | |||
| 535 | 538 | ||
| 536 | tid = transaction->t_tid; | 539 | tid = transaction->t_tid; |
| 537 | read_unlock(&journal->j_state_lock); | 540 | read_unlock(&journal->j_state_lock); |
| 541 | if (need_to_start) | ||
| 542 | jbd2_log_start_commit(journal, tid); | ||
| 538 | jbd2_log_wait_commit(journal, tid); | 543 | jbd2_log_wait_commit(journal, tid); |
| 539 | return 1; | 544 | return 1; |
| 540 | } | 545 | } |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index faad2bd787c..1d1191050f9 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -117,10 +117,10 @@ static inline void update_t_max_wait(transaction_t *transaction) | |||
| 117 | static int start_this_handle(journal_t *journal, handle_t *handle, | 117 | static int start_this_handle(journal_t *journal, handle_t *handle, |
| 118 | int gfp_mask) | 118 | int gfp_mask) |
| 119 | { | 119 | { |
| 120 | transaction_t *transaction; | 120 | transaction_t *transaction, *new_transaction = NULL; |
| 121 | int needed; | 121 | tid_t tid; |
| 122 | int nblocks = handle->h_buffer_credits; | 122 | int needed, need_to_start; |
| 123 | transaction_t *new_transaction = NULL; | 123 | int nblocks = handle->h_buffer_credits; |
| 124 | 124 | ||
| 125 | if (nblocks > journal->j_max_transaction_buffers) { | 125 | if (nblocks > journal->j_max_transaction_buffers) { |
| 126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", | 126 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", |
| @@ -222,8 +222,11 @@ repeat: | |||
| 222 | atomic_sub(nblocks, &transaction->t_outstanding_credits); | 222 | atomic_sub(nblocks, &transaction->t_outstanding_credits); |
| 223 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, | 223 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, |
| 224 | TASK_UNINTERRUPTIBLE); | 224 | TASK_UNINTERRUPTIBLE); |
| 225 | __jbd2_log_start_commit(journal, transaction->t_tid); | 225 | tid = transaction->t_tid; |
| 226 | need_to_start = !tid_geq(journal->j_commit_request, tid); | ||
| 226 | read_unlock(&journal->j_state_lock); | 227 | read_unlock(&journal->j_state_lock); |
| 228 | if (need_to_start) | ||
| 229 | jbd2_log_start_commit(journal, tid); | ||
| 227 | schedule(); | 230 | schedule(); |
| 228 | finish_wait(&journal->j_wait_transaction_locked, &wait); | 231 | finish_wait(&journal->j_wait_transaction_locked, &wait); |
| 229 | goto repeat; | 232 | goto repeat; |
| @@ -442,7 +445,8 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask) | |||
| 442 | { | 445 | { |
| 443 | transaction_t *transaction = handle->h_transaction; | 446 | transaction_t *transaction = handle->h_transaction; |
| 444 | journal_t *journal = transaction->t_journal; | 447 | journal_t *journal = transaction->t_journal; |
| 445 | int ret; | 448 | tid_t tid; |
| 449 | int need_to_start, ret; | ||
| 446 | 450 | ||
| 447 | /* If we've had an abort of any type, don't even think about | 451 | /* If we've had an abort of any type, don't even think about |
| 448 | * actually doing the restart! */ | 452 | * actually doing the restart! */ |
| @@ -465,8 +469,11 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask) | |||
| 465 | spin_unlock(&transaction->t_handle_lock); | 469 | spin_unlock(&transaction->t_handle_lock); |
| 466 | 470 | ||
| 467 | jbd_debug(2, "restarting handle %p\n", handle); | 471 | jbd_debug(2, "restarting handle %p\n", handle); |
| 468 | __jbd2_log_start_commit(journal, transaction->t_tid); | 472 | tid = transaction->t_tid; |
| 473 | need_to_start = !tid_geq(journal->j_commit_request, tid); | ||
| 469 | read_unlock(&journal->j_state_lock); | 474 | read_unlock(&journal->j_state_lock); |
| 475 | if (need_to_start) | ||
| 476 | jbd2_log_start_commit(journal, tid); | ||
| 470 | 477 | ||
| 471 | lock_map_release(&handle->h_lockdep_map); | 478 | lock_map_release(&handle->h_lockdep_map); |
| 472 | handle->h_buffer_credits = nblocks; | 479 | handle->h_buffer_credits = nblocks; |
diff --git a/fs/namei.c b/fs/namei.c index 7d77f24d32a..0087cf9c2c6 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -455,14 +455,6 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry | |||
| 455 | struct fs_struct *fs = current->fs; | 455 | struct fs_struct *fs = current->fs; |
| 456 | struct dentry *parent = nd->path.dentry; | 456 | struct dentry *parent = nd->path.dentry; |
| 457 | 457 | ||
| 458 | /* | ||
| 459 | * It can be possible to revalidate the dentry that we started | ||
| 460 | * the path walk with. force_reval_path may also revalidate the | ||
| 461 | * dentry already committed to the nameidata. | ||
| 462 | */ | ||
| 463 | if (unlikely(parent == dentry)) | ||
| 464 | return nameidata_drop_rcu(nd); | ||
| 465 | |||
| 466 | BUG_ON(!(nd->flags & LOOKUP_RCU)); | 458 | BUG_ON(!(nd->flags & LOOKUP_RCU)); |
| 467 | if (nd->root.mnt) { | 459 | if (nd->root.mnt) { |
| 468 | spin_lock(&fs->lock); | 460 | spin_lock(&fs->lock); |
| @@ -561,39 +553,25 @@ static inline int nameidata_drop_rcu_last_maybe(struct nameidata *nd) | |||
| 561 | */ | 553 | */ |
| 562 | void release_open_intent(struct nameidata *nd) | 554 | void release_open_intent(struct nameidata *nd) |
| 563 | { | 555 | { |
| 564 | if (nd->intent.open.file->f_path.dentry == NULL) | 556 | struct file *file = nd->intent.open.file; |
| 565 | put_filp(nd->intent.open.file); | ||
| 566 | else | ||
| 567 | fput(nd->intent.open.file); | ||
| 568 | } | ||
| 569 | |||
| 570 | /* | ||
| 571 | * Call d_revalidate and handle filesystems that request rcu-walk | ||
| 572 | * to be dropped. This may be called and return in rcu-walk mode, | ||
| 573 | * regardless of success or error. If -ECHILD is returned, the caller | ||
| 574 | * must return -ECHILD back up the path walk stack so path walk may | ||
| 575 | * be restarted in ref-walk mode. | ||
| 576 | */ | ||
| 577 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
| 578 | { | ||
| 579 | int status; | ||
| 580 | 557 | ||
| 581 | status = dentry->d_op->d_revalidate(dentry, nd); | 558 | if (file && !IS_ERR(file)) { |
| 582 | if (status == -ECHILD) { | 559 | if (file->f_path.dentry == NULL) |
| 583 | if (nameidata_dentry_drop_rcu(nd, dentry)) | 560 | put_filp(file); |
| 584 | return status; | 561 | else |
| 585 | status = dentry->d_op->d_revalidate(dentry, nd); | 562 | fput(file); |
| 586 | } | 563 | } |
| 564 | } | ||
| 587 | 565 | ||
| 588 | return status; | 566 | static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) |
| 567 | { | ||
| 568 | return dentry->d_op->d_revalidate(dentry, nd); | ||
| 589 | } | 569 | } |
| 590 | 570 | ||
| 591 | static inline struct dentry * | 571 | static struct dentry * |
| 592 | do_revalidate(struct dentry *dentry, struct nameidata *nd) | 572 | do_revalidate(struct dentry *dentry, struct nameidata *nd) |
| 593 | { | 573 | { |
| 594 | int status; | 574 | int status = d_revalidate(dentry, nd); |
| 595 | |||
| 596 | status = d_revalidate(dentry, nd); | ||
| 597 | if (unlikely(status <= 0)) { | 575 | if (unlikely(status <= 0)) { |
| 598 | /* | 576 | /* |
| 599 | * The dentry failed validation. | 577 | * The dentry failed validation. |
| @@ -602,24 +580,39 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
| 602 | * to return a fail status. | 580 | * to return a fail status. |
| 603 | */ | 581 | */ |
| 604 | if (status < 0) { | 582 | if (status < 0) { |
| 605 | /* If we're in rcu-walk, we don't have a ref */ | 583 | dput(dentry); |
| 606 | if (!(nd->flags & LOOKUP_RCU)) | ||
| 607 | dput(dentry); | ||
| 608 | dentry = ERR_PTR(status); | 584 | dentry = ERR_PTR(status); |
| 609 | 585 | } else if (!d_invalidate(dentry)) { | |
| 610 | } else { | 586 | dput(dentry); |
| 611 | /* Don't d_invalidate in rcu-walk mode */ | 587 | dentry = NULL; |
| 612 | if (nameidata_dentry_drop_rcu_maybe(nd, dentry)) | ||
| 613 | return ERR_PTR(-ECHILD); | ||
| 614 | if (!d_invalidate(dentry)) { | ||
| 615 | dput(dentry); | ||
| 616 | dentry = NULL; | ||
| 617 | } | ||
| 618 | } | 588 | } |
| 619 | } | 589 | } |
| 620 | return dentry; | 590 | return dentry; |
| 621 | } | 591 | } |
| 622 | 592 | ||
| 593 | static inline struct dentry * | ||
| 594 | do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd) | ||
| 595 | { | ||
| 596 | int status = d_revalidate(dentry, nd); | ||
| 597 | if (likely(status > 0)) | ||
| 598 | return dentry; | ||
| 599 | if (status == -ECHILD) { | ||
| 600 | if (nameidata_dentry_drop_rcu(nd, dentry)) | ||
| 601 | return ERR_PTR(-ECHILD); | ||
| 602 | return do_revalidate(dentry, nd); | ||
| 603 | } | ||
| 604 | if (status < 0) | ||
| 605 | return ERR_PTR(status); | ||
| 606 | /* Don't d_invalidate in rcu-walk mode */ | ||
| 607 | if (nameidata_dentry_drop_rcu(nd, dentry)) | ||
| 608 | return ERR_PTR(-ECHILD); | ||
| 609 | if (!d_invalidate(dentry)) { | ||
| 610 | dput(dentry); | ||
| 611 | dentry = NULL; | ||
| 612 | } | ||
| 613 | return dentry; | ||
| 614 | } | ||
| 615 | |||
| 623 | static inline int need_reval_dot(struct dentry *dentry) | 616 | static inline int need_reval_dot(struct dentry *dentry) |
| 624 | { | 617 | { |
| 625 | if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE))) | 618 | if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE))) |
| @@ -664,9 +657,6 @@ force_reval_path(struct path *path, struct nameidata *nd) | |||
| 664 | return 0; | 657 | return 0; |
| 665 | 658 | ||
| 666 | if (!status) { | 659 | if (!status) { |
| 667 | /* Don't d_invalidate in rcu-walk mode */ | ||
| 668 | if (nameidata_drop_rcu(nd)) | ||
| 669 | return -ECHILD; | ||
| 670 | d_invalidate(dentry); | 660 | d_invalidate(dentry); |
| 671 | status = -ESTALE; | 661 | status = -ESTALE; |
| 672 | } | 662 | } |
| @@ -773,6 +763,8 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p) | |||
| 773 | int error; | 763 | int error; |
| 774 | struct dentry *dentry = link->dentry; | 764 | struct dentry *dentry = link->dentry; |
| 775 | 765 | ||
| 766 | BUG_ON(nd->flags & LOOKUP_RCU); | ||
| 767 | |||
| 776 | touch_atime(link->mnt, dentry); | 768 | touch_atime(link->mnt, dentry); |
| 777 | nd_set_link(nd, NULL); | 769 | nd_set_link(nd, NULL); |
| 778 | 770 | ||
| @@ -803,10 +795,16 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p) | |||
| 803 | * Without that kind of total limit, nasty chains of consecutive | 795 | * Without that kind of total limit, nasty chains of consecutive |
| 804 | * symlinks can cause almost arbitrarily long lookups. | 796 | * symlinks can cause almost arbitrarily long lookups. |
| 805 | */ | 797 | */ |
| 806 | static inline int do_follow_link(struct path *path, struct nameidata *nd) | 798 | static inline int do_follow_link(struct inode *inode, struct path *path, struct nameidata *nd) |
| 807 | { | 799 | { |
| 808 | void *cookie; | 800 | void *cookie; |
| 809 | int err = -ELOOP; | 801 | int err = -ELOOP; |
| 802 | |||
| 803 | /* We drop rcu-walk here */ | ||
| 804 | if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry)) | ||
| 805 | return -ECHILD; | ||
| 806 | BUG_ON(inode != path->dentry->d_inode); | ||
| 807 | |||
| 810 | if (current->link_count >= MAX_NESTED_LINKS) | 808 | if (current->link_count >= MAX_NESTED_LINKS) |
| 811 | goto loop; | 809 | goto loop; |
| 812 | if (current->total_link_count >= 40) | 810 | if (current->total_link_count >= 40) |
| @@ -1251,9 +1249,15 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
| 1251 | return -ECHILD; | 1249 | return -ECHILD; |
| 1252 | 1250 | ||
| 1253 | nd->seq = seq; | 1251 | nd->seq = seq; |
| 1254 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) | 1252 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { |
| 1255 | goto need_revalidate; | 1253 | dentry = do_revalidate_rcu(dentry, nd); |
| 1256 | done2: | 1254 | if (!dentry) |
| 1255 | goto need_lookup; | ||
| 1256 | if (IS_ERR(dentry)) | ||
| 1257 | goto fail; | ||
| 1258 | if (!(nd->flags & LOOKUP_RCU)) | ||
| 1259 | goto done; | ||
| 1260 | } | ||
| 1257 | path->mnt = mnt; | 1261 | path->mnt = mnt; |
| 1258 | path->dentry = dentry; | 1262 | path->dentry = dentry; |
| 1259 | if (likely(__follow_mount_rcu(nd, path, inode, false))) | 1263 | if (likely(__follow_mount_rcu(nd, path, inode, false))) |
| @@ -1266,8 +1270,13 @@ done2: | |||
| 1266 | if (!dentry) | 1270 | if (!dentry) |
| 1267 | goto need_lookup; | 1271 | goto need_lookup; |
| 1268 | found: | 1272 | found: |
| 1269 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) | 1273 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { |
| 1270 | goto need_revalidate; | 1274 | dentry = do_revalidate(dentry, nd); |
| 1275 | if (!dentry) | ||
| 1276 | goto need_lookup; | ||
| 1277 | if (IS_ERR(dentry)) | ||
| 1278 | goto fail; | ||
| 1279 | } | ||
| 1271 | done: | 1280 | done: |
| 1272 | path->mnt = mnt; | 1281 | path->mnt = mnt; |
| 1273 | path->dentry = dentry; | 1282 | path->dentry = dentry; |
| @@ -1309,16 +1318,6 @@ need_lookup: | |||
| 1309 | mutex_unlock(&dir->i_mutex); | 1318 | mutex_unlock(&dir->i_mutex); |
| 1310 | goto found; | 1319 | goto found; |
| 1311 | 1320 | ||
| 1312 | need_revalidate: | ||
| 1313 | dentry = do_revalidate(dentry, nd); | ||
| 1314 | if (!dentry) | ||
| 1315 | goto need_lookup; | ||
| 1316 | if (IS_ERR(dentry)) | ||
| 1317 | goto fail; | ||
| 1318 | if (nd->flags & LOOKUP_RCU) | ||
| 1319 | goto done2; | ||
| 1320 | goto done; | ||
| 1321 | |||
| 1322 | fail: | 1321 | fail: |
| 1323 | return PTR_ERR(dentry); | 1322 | return PTR_ERR(dentry); |
| 1324 | } | 1323 | } |
| @@ -1415,11 +1414,7 @@ exec_again: | |||
| 1415 | goto out_dput; | 1414 | goto out_dput; |
| 1416 | 1415 | ||
| 1417 | if (inode->i_op->follow_link) { | 1416 | if (inode->i_op->follow_link) { |
| 1418 | /* We commonly drop rcu-walk here */ | 1417 | err = do_follow_link(inode, &next, nd); |
| 1419 | if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) | ||
| 1420 | return -ECHILD; | ||
| 1421 | BUG_ON(inode != next.dentry->d_inode); | ||
| 1422 | err = do_follow_link(&next, nd); | ||
| 1423 | if (err) | 1418 | if (err) |
| 1424 | goto return_err; | 1419 | goto return_err; |
| 1425 | nd->inode = nd->path.dentry->d_inode; | 1420 | nd->inode = nd->path.dentry->d_inode; |
| @@ -1463,10 +1458,7 @@ last_component: | |||
| 1463 | break; | 1458 | break; |
| 1464 | if (inode && unlikely(inode->i_op->follow_link) && | 1459 | if (inode && unlikely(inode->i_op->follow_link) && |
| 1465 | (lookup_flags & LOOKUP_FOLLOW)) { | 1460 | (lookup_flags & LOOKUP_FOLLOW)) { |
| 1466 | if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) | 1461 | err = do_follow_link(inode, &next, nd); |
| 1467 | return -ECHILD; | ||
| 1468 | BUG_ON(inode != next.dentry->d_inode); | ||
| 1469 | err = do_follow_link(&next, nd); | ||
| 1470 | if (err) | 1462 | if (err) |
| 1471 | goto return_err; | 1463 | goto return_err; |
| 1472 | nd->inode = nd->path.dentry->d_inode; | 1464 | nd->inode = nd->path.dentry->d_inode; |
| @@ -1500,12 +1492,15 @@ return_reval: | |||
| 1500 | * We may need to check the cached dentry for staleness. | 1492 | * We may need to check the cached dentry for staleness. |
| 1501 | */ | 1493 | */ |
| 1502 | if (need_reval_dot(nd->path.dentry)) { | 1494 | if (need_reval_dot(nd->path.dentry)) { |
| 1495 | if (nameidata_drop_rcu_last_maybe(nd)) | ||
| 1496 | return -ECHILD; | ||
| 1503 | /* Note: we do not d_invalidate() */ | 1497 | /* Note: we do not d_invalidate() */ |
| 1504 | err = d_revalidate(nd->path.dentry, nd); | 1498 | err = d_revalidate(nd->path.dentry, nd); |
| 1505 | if (!err) | 1499 | if (!err) |
| 1506 | err = -ESTALE; | 1500 | err = -ESTALE; |
| 1507 | if (err < 0) | 1501 | if (err < 0) |
| 1508 | break; | 1502 | break; |
| 1503 | return 0; | ||
| 1509 | } | 1504 | } |
| 1510 | return_base: | 1505 | return_base: |
| 1511 | if (nameidata_drop_rcu_last_maybe(nd)) | 1506 | if (nameidata_drop_rcu_last_maybe(nd)) |
| @@ -2265,8 +2260,6 @@ static struct file *finish_open(struct nameidata *nd, | |||
| 2265 | return filp; | 2260 | return filp; |
| 2266 | 2261 | ||
| 2267 | exit: | 2262 | exit: |
| 2268 | if (!IS_ERR(nd->intent.open.file)) | ||
| 2269 | release_open_intent(nd); | ||
| 2270 | path_put(&nd->path); | 2263 | path_put(&nd->path); |
| 2271 | return ERR_PTR(error); | 2264 | return ERR_PTR(error); |
| 2272 | } | 2265 | } |
| @@ -2389,8 +2382,6 @@ exit_mutex_unlock: | |||
| 2389 | exit_dput: | 2382 | exit_dput: |
| 2390 | path_put_conditional(path, nd); | 2383 | path_put_conditional(path, nd); |
| 2391 | exit: | 2384 | exit: |
| 2392 | if (!IS_ERR(nd->intent.open.file)) | ||
| 2393 | release_open_intent(nd); | ||
| 2394 | path_put(&nd->path); | 2385 | path_put(&nd->path); |
| 2395 | return ERR_PTR(error); | 2386 | return ERR_PTR(error); |
| 2396 | } | 2387 | } |
| @@ -2477,6 +2468,7 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
| 2477 | } | 2468 | } |
| 2478 | audit_inode(pathname, nd.path.dentry); | 2469 | audit_inode(pathname, nd.path.dentry); |
| 2479 | filp = finish_open(&nd, open_flag, acc_mode); | 2470 | filp = finish_open(&nd, open_flag, acc_mode); |
| 2471 | release_open_intent(&nd); | ||
| 2480 | return filp; | 2472 | return filp; |
| 2481 | 2473 | ||
| 2482 | creat: | 2474 | creat: |
| @@ -2553,6 +2545,7 @@ out: | |||
| 2553 | path_put(&nd.root); | 2545 | path_put(&nd.root); |
| 2554 | if (filp == ERR_PTR(-ESTALE) && !(flags & LOOKUP_REVAL)) | 2546 | if (filp == ERR_PTR(-ESTALE) && !(flags & LOOKUP_REVAL)) |
| 2555 | goto reval; | 2547 | goto reval; |
| 2548 | release_open_intent(&nd); | ||
| 2556 | return filp; | 2549 | return filp; |
| 2557 | 2550 | ||
| 2558 | exit_dput: | 2551 | exit_dput: |
| @@ -2560,8 +2553,6 @@ exit_dput: | |||
| 2560 | out_path: | 2553 | out_path: |
| 2561 | path_put(&nd.path); | 2554 | path_put(&nd.path); |
| 2562 | out_filp: | 2555 | out_filp: |
| 2563 | if (!IS_ERR(nd.intent.open.file)) | ||
| 2564 | release_open_intent(&nd); | ||
| 2565 | filp = ERR_PTR(error); | 2556 | filp = ERR_PTR(error); |
| 2566 | goto out; | 2557 | goto out; |
| 2567 | } | 2558 | } |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 3be975e1891..cde36cb0f34 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -484,7 +484,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr, | |||
| 484 | out: | 484 | out: |
| 485 | return status; | 485 | return status; |
| 486 | out_default: | 486 | out_default: |
| 487 | return nfs_cb_stat_to_errno(status); | 487 | return nfs_cb_stat_to_errno(nfserr); |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | /* | 490 | /* |
| @@ -564,11 +564,9 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, | |||
| 564 | if (unlikely(status)) | 564 | if (unlikely(status)) |
| 565 | goto out; | 565 | goto out; |
| 566 | if (unlikely(nfserr != NFS4_OK)) | 566 | if (unlikely(nfserr != NFS4_OK)) |
| 567 | goto out_default; | 567 | status = nfs_cb_stat_to_errno(nfserr); |
| 568 | out: | 568 | out: |
| 569 | return status; | 569 | return status; |
| 570 | out_default: | ||
| 571 | return nfs_cb_stat_to_errno(status); | ||
| 572 | } | 570 | } |
| 573 | 571 | ||
| 574 | /* | 572 | /* |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d98d0213285..54b60bfceb8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -230,9 +230,6 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f | |||
| 230 | dp->dl_client = clp; | 230 | dp->dl_client = clp; |
| 231 | get_nfs4_file(fp); | 231 | get_nfs4_file(fp); |
| 232 | dp->dl_file = fp; | 232 | dp->dl_file = fp; |
| 233 | dp->dl_vfs_file = find_readable_file(fp); | ||
| 234 | get_file(dp->dl_vfs_file); | ||
| 235 | dp->dl_flock = NULL; | ||
| 236 | dp->dl_type = type; | 233 | dp->dl_type = type; |
| 237 | dp->dl_stateid.si_boot = boot_time; | 234 | dp->dl_stateid.si_boot = boot_time; |
| 238 | dp->dl_stateid.si_stateownerid = current_delegid++; | 235 | dp->dl_stateid.si_stateownerid = current_delegid++; |
| @@ -241,8 +238,6 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f | |||
| 241 | fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle); | 238 | fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle); |
| 242 | dp->dl_time = 0; | 239 | dp->dl_time = 0; |
| 243 | atomic_set(&dp->dl_count, 1); | 240 | atomic_set(&dp->dl_count, 1); |
| 244 | list_add(&dp->dl_perfile, &fp->fi_delegations); | ||
| 245 | list_add(&dp->dl_perclnt, &clp->cl_delegations); | ||
| 246 | INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); | 241 | INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); |
| 247 | return dp; | 242 | return dp; |
| 248 | } | 243 | } |
| @@ -253,36 +248,30 @@ nfs4_put_delegation(struct nfs4_delegation *dp) | |||
| 253 | if (atomic_dec_and_test(&dp->dl_count)) { | 248 | if (atomic_dec_and_test(&dp->dl_count)) { |
| 254 | dprintk("NFSD: freeing dp %p\n",dp); | 249 | dprintk("NFSD: freeing dp %p\n",dp); |
| 255 | put_nfs4_file(dp->dl_file); | 250 | put_nfs4_file(dp->dl_file); |
| 256 | fput(dp->dl_vfs_file); | ||
| 257 | kmem_cache_free(deleg_slab, dp); | 251 | kmem_cache_free(deleg_slab, dp); |
| 258 | num_delegations--; | 252 | num_delegations--; |
| 259 | } | 253 | } |
| 260 | } | 254 | } |
| 261 | 255 | ||
| 262 | /* Remove the associated file_lock first, then remove the delegation. | 256 | static void nfs4_put_deleg_lease(struct nfs4_file *fp) |
| 263 | * lease_modify() is called to remove the FS_LEASE file_lock from | ||
| 264 | * the i_flock list, eventually calling nfsd's lock_manager | ||
| 265 | * fl_release_callback. | ||
| 266 | */ | ||
| 267 | static void | ||
| 268 | nfs4_close_delegation(struct nfs4_delegation *dp) | ||
| 269 | { | 257 | { |
| 270 | dprintk("NFSD: close_delegation dp %p\n",dp); | 258 | if (atomic_dec_and_test(&fp->fi_delegees)) { |
| 271 | /* XXX: do we even need this check?: */ | 259 | vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); |
| 272 | if (dp->dl_flock) | 260 | fp->fi_lease = NULL; |
| 273 | vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock); | 261 | fp->fi_deleg_file = NULL; |
| 262 | } | ||
| 274 | } | 263 | } |
| 275 | 264 | ||
| 276 | /* Called under the state lock. */ | 265 | /* Called under the state lock. */ |
| 277 | static void | 266 | static void |
| 278 | unhash_delegation(struct nfs4_delegation *dp) | 267 | unhash_delegation(struct nfs4_delegation *dp) |
| 279 | { | 268 | { |
| 280 | list_del_init(&dp->dl_perfile); | ||
| 281 | list_del_init(&dp->dl_perclnt); | 269 | list_del_init(&dp->dl_perclnt); |
| 282 | spin_lock(&recall_lock); | 270 | spin_lock(&recall_lock); |
| 271 | list_del_init(&dp->dl_perfile); | ||
| 283 | list_del_init(&dp->dl_recall_lru); | 272 | list_del_init(&dp->dl_recall_lru); |
| 284 | spin_unlock(&recall_lock); | 273 | spin_unlock(&recall_lock); |
| 285 | nfs4_close_delegation(dp); | 274 | nfs4_put_deleg_lease(dp->dl_file); |
| 286 | nfs4_put_delegation(dp); | 275 | nfs4_put_delegation(dp); |
| 287 | } | 276 | } |
| 288 | 277 | ||
| @@ -958,8 +947,6 @@ expire_client(struct nfs4_client *clp) | |||
| 958 | spin_lock(&recall_lock); | 947 | spin_lock(&recall_lock); |
| 959 | while (!list_empty(&clp->cl_delegations)) { | 948 | while (!list_empty(&clp->cl_delegations)) { |
| 960 | dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt); | 949 | dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt); |
| 961 | dprintk("NFSD: expire client. dp %p, fp %p\n", dp, | ||
| 962 | dp->dl_flock); | ||
| 963 | list_del_init(&dp->dl_perclnt); | 950 | list_del_init(&dp->dl_perclnt); |
| 964 | list_move(&dp->dl_recall_lru, &reaplist); | 951 | list_move(&dp->dl_recall_lru, &reaplist); |
| 965 | } | 952 | } |
| @@ -2078,6 +2065,7 @@ alloc_init_file(struct inode *ino) | |||
| 2078 | fp->fi_inode = igrab(ino); | 2065 | fp->fi_inode = igrab(ino); |
| 2079 | fp->fi_id = current_fileid++; | 2066 | fp->fi_id = current_fileid++; |
| 2080 | fp->fi_had_conflict = false; | 2067 | fp->fi_had_conflict = false; |
| 2068 | fp->fi_lease = NULL; | ||
| 2081 | memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); | 2069 | memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); |
| 2082 | memset(fp->fi_access, 0, sizeof(fp->fi_access)); | 2070 | memset(fp->fi_access, 0, sizeof(fp->fi_access)); |
| 2083 | spin_lock(&recall_lock); | 2071 | spin_lock(&recall_lock); |
| @@ -2329,23 +2317,8 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access) | |||
| 2329 | nfs4_file_put_access(fp, O_RDONLY); | 2317 | nfs4_file_put_access(fp, O_RDONLY); |
| 2330 | } | 2318 | } |
| 2331 | 2319 | ||
| 2332 | /* | 2320 | static void nfsd_break_one_deleg(struct nfs4_delegation *dp) |
| 2333 | * Spawn a thread to perform a recall on the delegation represented | ||
| 2334 | * by the lease (file_lock) | ||
| 2335 | * | ||
| 2336 | * Called from break_lease() with lock_flocks() held. | ||
| 2337 | * Note: we assume break_lease will only call this *once* for any given | ||
| 2338 | * lease. | ||
| 2339 | */ | ||
| 2340 | static | ||
| 2341 | void nfsd_break_deleg_cb(struct file_lock *fl) | ||
| 2342 | { | 2321 | { |
| 2343 | struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner; | ||
| 2344 | |||
| 2345 | dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); | ||
| 2346 | if (!dp) | ||
| 2347 | return; | ||
| 2348 | |||
| 2349 | /* We're assuming the state code never drops its reference | 2322 | /* We're assuming the state code never drops its reference |
| 2350 | * without first removing the lease. Since we're in this lease | 2323 | * without first removing the lease. Since we're in this lease |
| 2351 | * callback (and since the lease code is serialized by the kernel | 2324 | * callback (and since the lease code is serialized by the kernel |
| @@ -2353,22 +2326,35 @@ void nfsd_break_deleg_cb(struct file_lock *fl) | |||
| 2353 | * it's safe to take a reference: */ | 2326 | * it's safe to take a reference: */ |
| 2354 | atomic_inc(&dp->dl_count); | 2327 | atomic_inc(&dp->dl_count); |
| 2355 | 2328 | ||
| 2356 | spin_lock(&recall_lock); | ||
| 2357 | list_add_tail(&dp->dl_recall_lru, &del_recall_lru); | 2329 | list_add_tail(&dp->dl_recall_lru, &del_recall_lru); |
| 2358 | spin_unlock(&recall_lock); | ||
| 2359 | 2330 | ||
| 2360 | /* only place dl_time is set. protected by lock_flocks*/ | 2331 | /* only place dl_time is set. protected by lock_flocks*/ |
| 2361 | dp->dl_time = get_seconds(); | 2332 | dp->dl_time = get_seconds(); |
| 2362 | 2333 | ||
| 2334 | nfsd4_cb_recall(dp); | ||
| 2335 | } | ||
| 2336 | |||
| 2337 | /* Called from break_lease() with lock_flocks() held. */ | ||
| 2338 | static void nfsd_break_deleg_cb(struct file_lock *fl) | ||
| 2339 | { | ||
| 2340 | struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; | ||
| 2341 | struct nfs4_delegation *dp; | ||
| 2342 | |||
| 2343 | BUG_ON(!fp); | ||
| 2344 | /* We assume break_lease is only called once per lease: */ | ||
| 2345 | BUG_ON(fp->fi_had_conflict); | ||
| 2363 | /* | 2346 | /* |
| 2364 | * We don't want the locks code to timeout the lease for us; | 2347 | * We don't want the locks code to timeout the lease for us; |
| 2365 | * we'll remove it ourself if the delegation isn't returned | 2348 | * we'll remove it ourself if a delegation isn't returned |
| 2366 | * in time. | 2349 | * in time: |
| 2367 | */ | 2350 | */ |
| 2368 | fl->fl_break_time = 0; | 2351 | fl->fl_break_time = 0; |
| 2369 | 2352 | ||
| 2370 | dp->dl_file->fi_had_conflict = true; | 2353 | spin_lock(&recall_lock); |
| 2371 | nfsd4_cb_recall(dp); | 2354 | fp->fi_had_conflict = true; |
| 2355 | list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) | ||
| 2356 | nfsd_break_one_deleg(dp); | ||
| 2357 | spin_unlock(&recall_lock); | ||
| 2372 | } | 2358 | } |
| 2373 | 2359 | ||
| 2374 | static | 2360 | static |
| @@ -2459,13 +2445,15 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags) | |||
| 2459 | static struct nfs4_delegation * | 2445 | static struct nfs4_delegation * |
| 2460 | find_delegation_file(struct nfs4_file *fp, stateid_t *stid) | 2446 | find_delegation_file(struct nfs4_file *fp, stateid_t *stid) |
| 2461 | { | 2447 | { |
| 2462 | struct nfs4_delegation *dp; | 2448 | struct nfs4_delegation *dp = NULL; |
| 2463 | 2449 | ||
| 2450 | spin_lock(&recall_lock); | ||
| 2464 | list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) { | 2451 | list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) { |
| 2465 | if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid) | 2452 | if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid) |
| 2466 | return dp; | 2453 | break; |
| 2467 | } | 2454 | } |
| 2468 | return NULL; | 2455 | spin_unlock(&recall_lock); |
| 2456 | return dp; | ||
| 2469 | } | 2457 | } |
| 2470 | 2458 | ||
| 2471 | int share_access_to_flags(u32 share_access) | 2459 | int share_access_to_flags(u32 share_access) |
| @@ -2641,6 +2629,66 @@ static bool nfsd4_cb_channel_good(struct nfs4_client *clp) | |||
| 2641 | return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; | 2629 | return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; |
| 2642 | } | 2630 | } |
| 2643 | 2631 | ||
| 2632 | static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag) | ||
| 2633 | { | ||
| 2634 | struct file_lock *fl; | ||
| 2635 | |||
| 2636 | fl = locks_alloc_lock(); | ||
| 2637 | if (!fl) | ||
| 2638 | return NULL; | ||
| 2639 | locks_init_lock(fl); | ||
| 2640 | fl->fl_lmops = &nfsd_lease_mng_ops; | ||
| 2641 | fl->fl_flags = FL_LEASE; | ||
| 2642 | fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; | ||
| 2643 | fl->fl_end = OFFSET_MAX; | ||
| 2644 | fl->fl_owner = (fl_owner_t)(dp->dl_file); | ||
| 2645 | fl->fl_pid = current->tgid; | ||
| 2646 | return fl; | ||
| 2647 | } | ||
| 2648 | |||
| 2649 | static int nfs4_setlease(struct nfs4_delegation *dp, int flag) | ||
| 2650 | { | ||
| 2651 | struct nfs4_file *fp = dp->dl_file; | ||
| 2652 | struct file_lock *fl; | ||
| 2653 | int status; | ||
| 2654 | |||
| 2655 | fl = nfs4_alloc_init_lease(dp, flag); | ||
| 2656 | if (!fl) | ||
| 2657 | return -ENOMEM; | ||
| 2658 | fl->fl_file = find_readable_file(fp); | ||
| 2659 | list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); | ||
| 2660 | status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); | ||
| 2661 | if (status) { | ||
| 2662 | list_del_init(&dp->dl_perclnt); | ||
| 2663 | locks_free_lock(fl); | ||
| 2664 | return -ENOMEM; | ||
| 2665 | } | ||
| 2666 | fp->fi_lease = fl; | ||
| 2667 | fp->fi_deleg_file = fl->fl_file; | ||
| 2668 | get_file(fp->fi_deleg_file); | ||
| 2669 | atomic_set(&fp->fi_delegees, 1); | ||
| 2670 | list_add(&dp->dl_perfile, &fp->fi_delegations); | ||
| 2671 | return 0; | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) | ||
| 2675 | { | ||
| 2676 | struct nfs4_file *fp = dp->dl_file; | ||
| 2677 | |||
| 2678 | if (!fp->fi_lease) | ||
| 2679 | return nfs4_setlease(dp, flag); | ||
| 2680 | spin_lock(&recall_lock); | ||
| 2681 | if (fp->fi_had_conflict) { | ||
| 2682 | spin_unlock(&recall_lock); | ||
| 2683 | return -EAGAIN; | ||
| 2684 | } | ||
| 2685 | atomic_inc(&fp->fi_delegees); | ||
| 2686 | list_add(&dp->dl_perfile, &fp->fi_delegations); | ||
| 2687 | spin_unlock(&recall_lock); | ||
| 2688 | list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); | ||
| 2689 | return 0; | ||
| 2690 | } | ||
| 2691 | |||
| 2644 | /* | 2692 | /* |
| 2645 | * Attempt to hand out a delegation. | 2693 | * Attempt to hand out a delegation. |
| 2646 | */ | 2694 | */ |
| @@ -2650,7 +2698,6 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
| 2650 | struct nfs4_delegation *dp; | 2698 | struct nfs4_delegation *dp; |
| 2651 | struct nfs4_stateowner *sop = stp->st_stateowner; | 2699 | struct nfs4_stateowner *sop = stp->st_stateowner; |
| 2652 | int cb_up; | 2700 | int cb_up; |
| 2653 | struct file_lock *fl; | ||
| 2654 | int status, flag = 0; | 2701 | int status, flag = 0; |
| 2655 | 2702 | ||
| 2656 | cb_up = nfsd4_cb_channel_good(sop->so_client); | 2703 | cb_up = nfsd4_cb_channel_good(sop->so_client); |
| @@ -2681,36 +2728,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
| 2681 | } | 2728 | } |
| 2682 | 2729 | ||
| 2683 | dp = alloc_init_deleg(sop->so_client, stp, fh, flag); | 2730 | dp = alloc_init_deleg(sop->so_client, stp, fh, flag); |
| 2684 | if (dp == NULL) { | 2731 | if (dp == NULL) |
| 2685 | flag = NFS4_OPEN_DELEGATE_NONE; | 2732 | goto out_no_deleg; |
| 2686 | goto out; | 2733 | status = nfs4_set_delegation(dp, flag); |
| 2687 | } | 2734 | if (status) |
| 2688 | status = -ENOMEM; | 2735 | goto out_free; |
| 2689 | fl = locks_alloc_lock(); | ||
| 2690 | if (!fl) | ||
| 2691 | goto out; | ||
| 2692 | locks_init_lock(fl); | ||
| 2693 | fl->fl_lmops = &nfsd_lease_mng_ops; | ||
| 2694 | fl->fl_flags = FL_LEASE; | ||
| 2695 | fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; | ||
| 2696 | fl->fl_end = OFFSET_MAX; | ||
| 2697 | fl->fl_owner = (fl_owner_t)dp; | ||
| 2698 | fl->fl_file = find_readable_file(stp->st_file); | ||
| 2699 | BUG_ON(!fl->fl_file); | ||
| 2700 | fl->fl_pid = current->tgid; | ||
| 2701 | dp->dl_flock = fl; | ||
| 2702 | |||
| 2703 | /* vfs_setlease checks to see if delegation should be handed out. | ||
| 2704 | * the lock_manager callback fl_change is used | ||
| 2705 | */ | ||
| 2706 | if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { | ||
| 2707 | dprintk("NFSD: setlease failed [%d], no delegation\n", status); | ||
| 2708 | dp->dl_flock = NULL; | ||
| 2709 | locks_free_lock(fl); | ||
| 2710 | unhash_delegation(dp); | ||
| 2711 | flag = NFS4_OPEN_DELEGATE_NONE; | ||
| 2712 | goto out; | ||
| 2713 | } | ||
| 2714 | 2736 | ||
| 2715 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); | 2737 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); |
| 2716 | 2738 | ||
| @@ -2722,6 +2744,12 @@ out: | |||
| 2722 | && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) | 2744 | && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) |
| 2723 | dprintk("NFSD: WARNING: refusing delegation reclaim\n"); | 2745 | dprintk("NFSD: WARNING: refusing delegation reclaim\n"); |
| 2724 | open->op_delegate_type = flag; | 2746 | open->op_delegate_type = flag; |
| 2747 | return; | ||
| 2748 | out_free: | ||
| 2749 | nfs4_put_delegation(dp); | ||
| 2750 | out_no_deleg: | ||
| 2751 | flag = NFS4_OPEN_DELEGATE_NONE; | ||
| 2752 | goto out; | ||
| 2725 | } | 2753 | } |
| 2726 | 2754 | ||
| 2727 | /* | 2755 | /* |
| @@ -2916,8 +2944,6 @@ nfs4_laundromat(void) | |||
| 2916 | test_val = u; | 2944 | test_val = u; |
| 2917 | break; | 2945 | break; |
| 2918 | } | 2946 | } |
| 2919 | dprintk("NFSD: purging unused delegation dp %p, fp %p\n", | ||
| 2920 | dp, dp->dl_flock); | ||
| 2921 | list_move(&dp->dl_recall_lru, &reaplist); | 2947 | list_move(&dp->dl_recall_lru, &reaplist); |
| 2922 | } | 2948 | } |
| 2923 | spin_unlock(&recall_lock); | 2949 | spin_unlock(&recall_lock); |
| @@ -3128,7 +3154,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
| 3128 | goto out; | 3154 | goto out; |
| 3129 | renew_client(dp->dl_client); | 3155 | renew_client(dp->dl_client); |
| 3130 | if (filpp) { | 3156 | if (filpp) { |
| 3131 | *filpp = find_readable_file(dp->dl_file); | 3157 | *filpp = dp->dl_file->fi_deleg_file; |
| 3132 | BUG_ON(!*filpp); | 3158 | BUG_ON(!*filpp); |
| 3133 | } | 3159 | } |
| 3134 | } else { /* open or lock stateid */ | 3160 | } else { /* open or lock stateid */ |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 956629b9cdc..1275b865507 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -317,8 +317,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
| 317 | READ_BUF(dummy32); | 317 | READ_BUF(dummy32); |
| 318 | len += (XDR_QUADLEN(dummy32) << 2); | 318 | len += (XDR_QUADLEN(dummy32) << 2); |
| 319 | READMEM(buf, dummy32); | 319 | READMEM(buf, dummy32); |
| 320 | if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) | 320 | if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) |
| 321 | goto out_nfserr; | 321 | return status; |
| 322 | iattr->ia_valid |= ATTR_UID; | 322 | iattr->ia_valid |= ATTR_UID; |
| 323 | } | 323 | } |
| 324 | if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { | 324 | if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { |
| @@ -328,8 +328,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
| 328 | READ_BUF(dummy32); | 328 | READ_BUF(dummy32); |
| 329 | len += (XDR_QUADLEN(dummy32) << 2); | 329 | len += (XDR_QUADLEN(dummy32) << 2); |
| 330 | READMEM(buf, dummy32); | 330 | READMEM(buf, dummy32); |
| 331 | if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) | 331 | if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) |
| 332 | goto out_nfserr; | 332 | return status; |
| 333 | iattr->ia_valid |= ATTR_GID; | 333 | iattr->ia_valid |= ATTR_GID; |
| 334 | } | 334 | } |
| 335 | if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { | 335 | if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 3074656ba7b..2d31224b07b 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
| @@ -83,8 +83,6 @@ struct nfs4_delegation { | |||
| 83 | atomic_t dl_count; /* ref count */ | 83 | atomic_t dl_count; /* ref count */ |
| 84 | struct nfs4_client *dl_client; | 84 | struct nfs4_client *dl_client; |
| 85 | struct nfs4_file *dl_file; | 85 | struct nfs4_file *dl_file; |
| 86 | struct file *dl_vfs_file; | ||
| 87 | struct file_lock *dl_flock; | ||
| 88 | u32 dl_type; | 86 | u32 dl_type; |
| 89 | time_t dl_time; | 87 | time_t dl_time; |
| 90 | /* For recall: */ | 88 | /* For recall: */ |
| @@ -379,6 +377,9 @@ struct nfs4_file { | |||
| 379 | */ | 377 | */ |
| 380 | atomic_t fi_readers; | 378 | atomic_t fi_readers; |
| 381 | atomic_t fi_writers; | 379 | atomic_t fi_writers; |
| 380 | struct file *fi_deleg_file; | ||
| 381 | struct file_lock *fi_lease; | ||
| 382 | atomic_t fi_delegees; | ||
| 382 | struct inode *fi_inode; | 383 | struct inode *fi_inode; |
| 383 | u32 fi_id; /* used with stateowner->so_id | 384 | u32 fi_id; /* used with stateowner->so_id |
| 384 | * for stateid_hashtbl hash */ | 385 | * for stateid_hashtbl hash */ |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 641117f2188..da1d9701f8e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -808,7 +808,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino) | |||
| 808 | if (ra->p_count == 0) | 808 | if (ra->p_count == 0) |
| 809 | frap = rap; | 809 | frap = rap; |
| 810 | } | 810 | } |
| 811 | depth = nfsdstats.ra_size*11/10; | 811 | depth = nfsdstats.ra_size; |
| 812 | if (!frap) { | 812 | if (!frap) { |
| 813 | spin_unlock(&rab->pb_lock); | 813 | spin_unlock(&rab->pb_lock); |
| 814 | return NULL; | 814 | return NULL; |
| @@ -1744,6 +1744,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
| 1744 | host_err = nfsd_break_lease(odentry->d_inode); | 1744 | host_err = nfsd_break_lease(odentry->d_inode); |
| 1745 | if (host_err) | 1745 | if (host_err) |
| 1746 | goto out_drop_write; | 1746 | goto out_drop_write; |
| 1747 | if (ndentry->d_inode) { | ||
| 1748 | host_err = nfsd_break_lease(ndentry->d_inode); | ||
| 1749 | if (host_err) | ||
| 1750 | goto out_drop_write; | ||
| 1751 | } | ||
| 1752 | if (host_err) | ||
| 1753 | goto out_drop_write; | ||
| 1747 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1754 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
| 1748 | if (!host_err) { | 1755 | if (!host_err) { |
| 1749 | host_err = commit_metadata(tfhp); | 1756 | host_err = commit_metadata(tfhp); |
| @@ -1812,22 +1819,22 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 1812 | 1819 | ||
| 1813 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | 1820 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); |
| 1814 | if (host_err) | 1821 | if (host_err) |
| 1815 | goto out_nfserr; | 1822 | goto out_put; |
| 1816 | 1823 | ||
| 1817 | host_err = nfsd_break_lease(rdentry->d_inode); | 1824 | host_err = nfsd_break_lease(rdentry->d_inode); |
| 1818 | if (host_err) | 1825 | if (host_err) |
| 1819 | goto out_put; | 1826 | goto out_drop_write; |
| 1820 | if (type != S_IFDIR) | 1827 | if (type != S_IFDIR) |
| 1821 | host_err = vfs_unlink(dirp, rdentry); | 1828 | host_err = vfs_unlink(dirp, rdentry); |
| 1822 | else | 1829 | else |
| 1823 | host_err = vfs_rmdir(dirp, rdentry); | 1830 | host_err = vfs_rmdir(dirp, rdentry); |
| 1824 | out_put: | ||
| 1825 | dput(rdentry); | ||
| 1826 | |||
| 1827 | if (!host_err) | 1831 | if (!host_err) |
| 1828 | host_err = commit_metadata(fhp); | 1832 | host_err = commit_metadata(fhp); |
| 1829 | 1833 | out_drop_write: | |
| 1830 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | 1834 | mnt_drop_write(fhp->fh_export->ex_path.mnt); |
| 1835 | out_put: | ||
| 1836 | dput(rdentry); | ||
| 1837 | |||
| 1831 | out_nfserr: | 1838 | out_nfserr: |
| 1832 | err = nfserrno(host_err); | 1839 | err = nfserrno(host_err); |
| 1833 | out: | 1840 | out: |
| @@ -790,6 +790,8 @@ struct file *nameidata_to_filp(struct nameidata *nd) | |||
| 790 | 790 | ||
| 791 | /* Pick up the filp from the open intent */ | 791 | /* Pick up the filp from the open intent */ |
| 792 | filp = nd->intent.open.file; | 792 | filp = nd->intent.open.file; |
| 793 | nd->intent.open.file = NULL; | ||
| 794 | |||
| 793 | /* Has the filesystem initialised the file for us? */ | 795 | /* Has the filesystem initialised the file for us? */ |
| 794 | if (filp->f_path.dentry == NULL) { | 796 | if (filp->f_path.dentry == NULL) { |
| 795 | path_get(&nd->path); | 797 | path_get(&nd->path); |
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index 68d6a216ee7..11f688bd76c 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
| @@ -29,10 +29,9 @@ static inline void mac_fix_string(char *stg, int len) | |||
| 29 | 29 | ||
| 30 | int mac_partition(struct parsed_partitions *state) | 30 | int mac_partition(struct parsed_partitions *state) |
| 31 | { | 31 | { |
| 32 | int slot = 1; | ||
| 33 | Sector sect; | 32 | Sector sect; |
| 34 | unsigned char *data; | 33 | unsigned char *data; |
| 35 | int blk, blocks_in_map; | 34 | int slot, blocks_in_map; |
| 36 | unsigned secsize; | 35 | unsigned secsize; |
| 37 | #ifdef CONFIG_PPC_PMAC | 36 | #ifdef CONFIG_PPC_PMAC |
| 38 | int found_root = 0; | 37 | int found_root = 0; |
| @@ -59,10 +58,14 @@ int mac_partition(struct parsed_partitions *state) | |||
| 59 | put_dev_sector(sect); | 58 | put_dev_sector(sect); |
| 60 | return 0; /* not a MacOS disk */ | 59 | return 0; /* not a MacOS disk */ |
| 61 | } | 60 | } |
| 62 | strlcat(state->pp_buf, " [mac]", PAGE_SIZE); | ||
| 63 | blocks_in_map = be32_to_cpu(part->map_count); | 61 | blocks_in_map = be32_to_cpu(part->map_count); |
| 64 | for (blk = 1; blk <= blocks_in_map; ++blk) { | 62 | if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) { |
| 65 | int pos = blk * secsize; | 63 | put_dev_sector(sect); |
| 64 | return 0; | ||
| 65 | } | ||
| 66 | strlcat(state->pp_buf, " [mac]", PAGE_SIZE); | ||
| 67 | for (slot = 1; slot <= blocks_in_map; ++slot) { | ||
| 68 | int pos = slot * secsize; | ||
| 66 | put_dev_sector(sect); | 69 | put_dev_sector(sect); |
| 67 | data = read_part_sector(state, pos/512, §); | 70 | data = read_part_sector(state, pos/512, §); |
| 68 | if (!data) | 71 | if (!data) |
| @@ -113,13 +116,11 @@ int mac_partition(struct parsed_partitions *state) | |||
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | if (goodness > found_root_goodness) { | 118 | if (goodness > found_root_goodness) { |
| 116 | found_root = blk; | 119 | found_root = slot; |
| 117 | found_root_goodness = goodness; | 120 | found_root_goodness = goodness; |
| 118 | } | 121 | } |
| 119 | } | 122 | } |
| 120 | #endif /* CONFIG_PPC_PMAC */ | 123 | #endif /* CONFIG_PPC_PMAC */ |
| 121 | |||
| 122 | ++slot; | ||
| 123 | } | 124 | } |
| 124 | #ifdef CONFIG_PPC_PMAC | 125 | #ifdef CONFIG_PPC_PMAC |
| 125 | if (found_root_goodness) | 126 | if (found_root_goodness) |
diff --git a/fs/proc/array.c b/fs/proc/array.c index df2b703b9d0..7c99c1cf7e5 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
| @@ -353,9 +353,6 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | |||
| 353 | task_cap(m, task); | 353 | task_cap(m, task); |
| 354 | task_cpus_allowed(m, task); | 354 | task_cpus_allowed(m, task); |
| 355 | cpuset_task_status_allowed(m, task); | 355 | cpuset_task_status_allowed(m, task); |
| 356 | #if defined(CONFIG_S390) | ||
| 357 | task_show_regs(m, task); | ||
| 358 | #endif | ||
| 359 | task_context_switch_counts(m, task); | 356 | task_context_switch_counts(m, task); |
| 360 | return 0; | 357 | return 0; |
| 361 | } | 358 | } |
diff --git a/fs/super.c b/fs/super.c index 74e149efed8..7e9dd4cc2c0 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -177,6 +177,11 @@ void deactivate_locked_super(struct super_block *s) | |||
| 177 | struct file_system_type *fs = s->s_type; | 177 | struct file_system_type *fs = s->s_type; |
| 178 | if (atomic_dec_and_test(&s->s_active)) { | 178 | if (atomic_dec_and_test(&s->s_active)) { |
| 179 | fs->kill_sb(s); | 179 | fs->kill_sb(s); |
| 180 | /* | ||
| 181 | * We need to call rcu_barrier so all the delayed rcu free | ||
| 182 | * inodes are flushed before we release the fs module. | ||
| 183 | */ | ||
| 184 | rcu_barrier(); | ||
| 180 | put_filesystem(fs); | 185 | put_filesystem(fs); |
| 181 | put_super(s); | 186 | put_super(s); |
| 182 | } else { | 187 | } else { |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 6ebb81030d2..fe77e3395b4 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
| @@ -124,7 +124,8 @@ | |||
| 124 | #endif | 124 | #endif |
| 125 | 125 | ||
| 126 | #ifdef CONFIG_EVENT_TRACING | 126 | #ifdef CONFIG_EVENT_TRACING |
| 127 | #define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \ | 127 | #define FTRACE_EVENTS() . = ALIGN(8); \ |
| 128 | VMLINUX_SYMBOL(__start_ftrace_events) = .; \ | ||
| 128 | *(_ftrace_events) \ | 129 | *(_ftrace_events) \ |
| 129 | VMLINUX_SYMBOL(__stop_ftrace_events) = .; | 130 | VMLINUX_SYMBOL(__stop_ftrace_events) = .; |
| 130 | #else | 131 | #else |
| @@ -140,7 +141,8 @@ | |||
| 140 | #endif | 141 | #endif |
| 141 | 142 | ||
| 142 | #ifdef CONFIG_FTRACE_SYSCALLS | 143 | #ifdef CONFIG_FTRACE_SYSCALLS |
| 143 | #define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ | 144 | #define TRACE_SYSCALLS() . = ALIGN(8); \ |
| 145 | VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ | ||
| 144 | *(__syscalls_metadata) \ | 146 | *(__syscalls_metadata) \ |
| 145 | VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; | 147 | VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; |
| 146 | #else | 148 | #else |
| @@ -165,10 +167,8 @@ | |||
| 165 | CPU_KEEP(exit.data) \ | 167 | CPU_KEEP(exit.data) \ |
| 166 | MEM_KEEP(init.data) \ | 168 | MEM_KEEP(init.data) \ |
| 167 | MEM_KEEP(exit.data) \ | 169 | MEM_KEEP(exit.data) \ |
| 168 | . = ALIGN(32); \ | 170 | STRUCT_ALIGN(); \ |
| 169 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ | ||
| 170 | *(__tracepoints) \ | 171 | *(__tracepoints) \ |
| 171 | VMLINUX_SYMBOL(__stop___tracepoints) = .; \ | ||
| 172 | /* implement dynamic printk debug */ \ | 172 | /* implement dynamic printk debug */ \ |
| 173 | . = ALIGN(8); \ | 173 | . = ALIGN(8); \ |
| 174 | VMLINUX_SYMBOL(__start___verbose) = .; \ | 174 | VMLINUX_SYMBOL(__start___verbose) = .; \ |
| @@ -176,13 +176,7 @@ | |||
| 176 | VMLINUX_SYMBOL(__stop___verbose) = .; \ | 176 | VMLINUX_SYMBOL(__stop___verbose) = .; \ |
| 177 | LIKELY_PROFILE() \ | 177 | LIKELY_PROFILE() \ |
| 178 | BRANCH_PROFILE() \ | 178 | BRANCH_PROFILE() \ |
| 179 | TRACE_PRINTKS() \ | 179 | TRACE_PRINTKS() |
| 180 | \ | ||
| 181 | STRUCT_ALIGN(); \ | ||
| 182 | FTRACE_EVENTS() \ | ||
| 183 | \ | ||
| 184 | STRUCT_ALIGN(); \ | ||
| 185 | TRACE_SYSCALLS() | ||
| 186 | 180 | ||
| 187 | /* | 181 | /* |
| 188 | * Data section helpers | 182 | * Data section helpers |
| @@ -220,6 +214,10 @@ | |||
| 220 | VMLINUX_SYMBOL(__start_rodata) = .; \ | 214 | VMLINUX_SYMBOL(__start_rodata) = .; \ |
| 221 | *(.rodata) *(.rodata.*) \ | 215 | *(.rodata) *(.rodata.*) \ |
| 222 | *(__vermagic) /* Kernel version magic */ \ | 216 | *(__vermagic) /* Kernel version magic */ \ |
| 217 | . = ALIGN(8); \ | ||
| 218 | VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .; \ | ||
| 219 | *(__tracepoints_ptrs) /* Tracepoints: pointer array */\ | ||
| 220 | VMLINUX_SYMBOL(__stop___tracepoints_ptrs) = .; \ | ||
| 223 | *(__markers_strings) /* Markers: strings */ \ | 221 | *(__markers_strings) /* Markers: strings */ \ |
| 224 | *(__tracepoints_strings)/* Tracepoints: strings */ \ | 222 | *(__tracepoints_strings)/* Tracepoints: strings */ \ |
| 225 | } \ | 223 | } \ |
| @@ -482,6 +480,8 @@ | |||
| 482 | KERNEL_CTORS() \ | 480 | KERNEL_CTORS() \ |
| 483 | *(.init.rodata) \ | 481 | *(.init.rodata) \ |
| 484 | MCOUNT_REC() \ | 482 | MCOUNT_REC() \ |
| 483 | FTRACE_EVENTS() \ | ||
| 484 | TRACE_SYSCALLS() \ | ||
| 485 | DEV_DISCARD(init.rodata) \ | 485 | DEV_DISCARD(init.rodata) \ |
| 486 | CPU_DISCARD(init.rodata) \ | 486 | CPU_DISCARD(init.rodata) \ |
| 487 | MEM_DISCARD(init.rodata) \ | 487 | MEM_DISCARD(init.rodata) \ |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index a4694c61033..fe29aadb129 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -1367,7 +1367,7 @@ extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); | |||
| 1367 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | 1367 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); |
| 1368 | extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, | 1368 | extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, |
| 1369 | struct timeval *vblanktime); | 1369 | struct timeval *vblanktime); |
| 1370 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | 1370 | extern bool drm_handle_vblank(struct drm_device *dev, int crtc); |
| 1371 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | 1371 | extern int drm_vblank_get(struct drm_device *dev, int crtc); |
| 1372 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | 1372 | extern void drm_vblank_put(struct drm_device *dev, int crtc); |
| 1373 | extern void drm_vblank_off(struct drm_device *dev, int crtc); | 1373 | extern void drm_vblank_off(struct drm_device *dev, int crtc); |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index acd7fade160..801be59f4f1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -275,6 +275,7 @@ struct drm_pending_vblank_event; | |||
| 275 | 275 | ||
| 276 | /** | 276 | /** |
| 277 | * drm_crtc_funcs - control CRTCs for a given device | 277 | * drm_crtc_funcs - control CRTCs for a given device |
| 278 | * @reset: reset CRTC after state has been invalidate (e.g. resume) | ||
| 278 | * @dpms: control display power levels | 279 | * @dpms: control display power levels |
| 279 | * @save: save CRTC state | 280 | * @save: save CRTC state |
| 280 | * @resore: restore CRTC state | 281 | * @resore: restore CRTC state |
| @@ -302,6 +303,8 @@ struct drm_crtc_funcs { | |||
| 302 | void (*save)(struct drm_crtc *crtc); /* suspend? */ | 303 | void (*save)(struct drm_crtc *crtc); /* suspend? */ |
| 303 | /* Restore CRTC state */ | 304 | /* Restore CRTC state */ |
| 304 | void (*restore)(struct drm_crtc *crtc); /* resume? */ | 305 | void (*restore)(struct drm_crtc *crtc); /* resume? */ |
| 306 | /* Reset CRTC state */ | ||
| 307 | void (*reset)(struct drm_crtc *crtc); | ||
| 305 | 308 | ||
| 306 | /* cursor controls */ | 309 | /* cursor controls */ |
| 307 | int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, | 310 | int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, |
| @@ -379,6 +382,7 @@ struct drm_crtc { | |||
| 379 | * @dpms: set power state (see drm_crtc_funcs above) | 382 | * @dpms: set power state (see drm_crtc_funcs above) |
| 380 | * @save: save connector state | 383 | * @save: save connector state |
| 381 | * @restore: restore connector state | 384 | * @restore: restore connector state |
| 385 | * @reset: reset connector after state has been invalidate (e.g. resume) | ||
| 382 | * @mode_valid: is this mode valid on the given connector? | 386 | * @mode_valid: is this mode valid on the given connector? |
| 383 | * @mode_fixup: try to fixup proposed mode for this connector | 387 | * @mode_fixup: try to fixup proposed mode for this connector |
| 384 | * @mode_set: set this mode | 388 | * @mode_set: set this mode |
| @@ -396,6 +400,7 @@ struct drm_connector_funcs { | |||
| 396 | void (*dpms)(struct drm_connector *connector, int mode); | 400 | void (*dpms)(struct drm_connector *connector, int mode); |
| 397 | void (*save)(struct drm_connector *connector); | 401 | void (*save)(struct drm_connector *connector); |
| 398 | void (*restore)(struct drm_connector *connector); | 402 | void (*restore)(struct drm_connector *connector); |
| 403 | void (*reset)(struct drm_connector *connector); | ||
| 399 | 404 | ||
| 400 | /* Check to see if anything is attached to the connector. | 405 | /* Check to see if anything is attached to the connector. |
| 401 | * @force is set to false whilst polling, true when checking the | 406 | * @force is set to false whilst polling, true when checking the |
| @@ -413,6 +418,7 @@ struct drm_connector_funcs { | |||
| 413 | }; | 418 | }; |
| 414 | 419 | ||
| 415 | struct drm_encoder_funcs { | 420 | struct drm_encoder_funcs { |
| 421 | void (*reset)(struct drm_encoder *encoder); | ||
| 416 | void (*destroy)(struct drm_encoder *encoder); | 422 | void (*destroy)(struct drm_encoder *encoder); |
| 417 | }; | 423 | }; |
| 418 | 424 | ||
| @@ -656,6 +662,7 @@ extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, | |||
| 656 | struct drm_display_mode *mode); | 662 | struct drm_display_mode *mode); |
| 657 | extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode); | 663 | extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode); |
| 658 | extern void drm_mode_config_init(struct drm_device *dev); | 664 | extern void drm_mode_config_init(struct drm_device *dev); |
| 665 | extern void drm_mode_config_reset(struct drm_device *dev); | ||
| 659 | extern void drm_mode_config_cleanup(struct drm_device *dev); | 666 | extern void drm_mode_config_cleanup(struct drm_device *dev); |
| 660 | extern void drm_mode_set_name(struct drm_display_mode *mode); | 667 | extern void drm_mode_set_name(struct drm_display_mode *mode); |
| 661 | extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2); | 668 | extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2); |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index fe29ae328bd..5ff1194dc2e 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 28 | {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
| 29 | {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ | 29 | {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ |
| 30 | {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 30 | {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
| 31 | {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
| 32 | {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 31 | {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
| 33 | {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 32 | {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
| 34 | {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 33 | {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 2296d8b1931..b0ada6f37dd 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | header-y += byteorder/ | 1 | header-y += byteorder/ |
| 2 | header-y += can/ | 2 | header-y += can/ |
| 3 | header-y += caif/ | ||
| 3 | header-y += dvb/ | 4 | header-y += dvb/ |
| 4 | header-y += hdlc/ | 5 | header-y += hdlc/ |
| 5 | header-y += isdn/ | 6 | header-y += isdn/ |
diff --git a/include/linux/caif/Kbuild b/include/linux/caif/Kbuild new file mode 100644 index 00000000000..a9cf250689d --- /dev/null +++ b/include/linux/caif/Kbuild | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | header-y += caif_socket.h | ||
| 2 | header-y += if_caif.h | ||
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index da7e52b099f..1effc8b56b4 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
| @@ -109,7 +109,7 @@ static inline void freezer_count(void) | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /* | 111 | /* |
| 112 | * Check if the task should be counted as freezeable by the freezer | 112 | * Check if the task should be counted as freezable by the freezer |
| 113 | */ | 113 | */ |
| 114 | static inline int freezer_should_skip(struct task_struct *p) | 114 | static inline int freezer_should_skip(struct task_struct *p) |
| 115 | { | 115 | { |
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 8e6c8c42bc3..df29c8fde36 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
| @@ -57,7 +57,8 @@ extern pmd_t *page_check_address_pmd(struct page *page, | |||
| 57 | (transparent_hugepage_flags & \ | 57 | (transparent_hugepage_flags & \ |
| 58 | (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG) && \ | 58 | (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG) && \ |
| 59 | ((__vma)->vm_flags & VM_HUGEPAGE))) && \ | 59 | ((__vma)->vm_flags & VM_HUGEPAGE))) && \ |
| 60 | !((__vma)->vm_flags & VM_NOHUGEPAGE)) | 60 | !((__vma)->vm_flags & VM_NOHUGEPAGE) && \ |
| 61 | !is_vma_temporary_stack(__vma)) | ||
| 61 | #define transparent_hugepage_defrag(__vma) \ | 62 | #define transparent_hugepage_defrag(__vma) \ |
| 62 | ((transparent_hugepage_flags & \ | 63 | ((transparent_hugepage_flags & \ |
| 63 | (1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) || \ | 64 | (1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) || \ |
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 69747469174..fe7c4b9ae27 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include <linux/input.h> | 5 | #include <linux/input.h> |
| 6 | 6 | ||
| 7 | #define MATRIX_MAX_ROWS 16 | 7 | #define MATRIX_MAX_ROWS 32 |
| 8 | #define MATRIX_MAX_COLS 16 | 8 | #define MATRIX_MAX_COLS 32 |
| 9 | 9 | ||
| 10 | #define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ | 10 | #define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ |
| 11 | (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ | 11 | (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ |
diff --git a/include/linux/irq.h b/include/linux/irq.h index abde2527c69..80fcb53057b 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
| @@ -74,7 +74,8 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, | |||
| 74 | 74 | ||
| 75 | #define IRQF_MODIFY_MASK \ | 75 | #define IRQF_MODIFY_MASK \ |
| 76 | (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ | 76 | (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ |
| 77 | IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL) | 77 | IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ |
| 78 | IRQ_PER_CPU) | ||
| 78 | 79 | ||
| 79 | #ifdef CONFIG_IRQ_PER_CPU | 80 | #ifdef CONFIG_IRQ_PER_CPU |
| 80 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) | 81 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) |
diff --git a/include/linux/klist.h b/include/linux/klist.h index e91a4e59b77..a370ce57cf1 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h | |||
| @@ -22,7 +22,7 @@ struct klist { | |||
| 22 | struct list_head k_list; | 22 | struct list_head k_list; |
| 23 | void (*get)(struct klist_node *); | 23 | void (*get)(struct klist_node *); |
| 24 | void (*put)(struct klist_node *); | 24 | void (*put)(struct klist_node *); |
| 25 | } __attribute__ ((aligned (4))); | 25 | } __attribute__ ((aligned (sizeof(void *)))); |
| 26 | 26 | ||
| 27 | #define KLIST_INIT(_name, _get, _put) \ | 27 | #define KLIST_INIT(_name, _get, _put) \ |
| 28 | { .k_lock = __SPIN_LOCK_UNLOCKED(_name.k_lock), \ | 28 | { .k_lock = __SPIN_LOCK_UNLOCKED(_name.k_lock), \ |
diff --git a/include/linux/list.h b/include/linux/list.h index 9a5f8a71810..3a54266a1e8 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
| @@ -96,6 +96,11 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) | |||
| 96 | * in an undefined state. | 96 | * in an undefined state. |
| 97 | */ | 97 | */ |
| 98 | #ifndef CONFIG_DEBUG_LIST | 98 | #ifndef CONFIG_DEBUG_LIST |
| 99 | static inline void __list_del_entry(struct list_head *entry) | ||
| 100 | { | ||
| 101 | __list_del(entry->prev, entry->next); | ||
| 102 | } | ||
| 103 | |||
| 99 | static inline void list_del(struct list_head *entry) | 104 | static inline void list_del(struct list_head *entry) |
| 100 | { | 105 | { |
| 101 | __list_del(entry->prev, entry->next); | 106 | __list_del(entry->prev, entry->next); |
| @@ -103,6 +108,7 @@ static inline void list_del(struct list_head *entry) | |||
| 103 | entry->prev = LIST_POISON2; | 108 | entry->prev = LIST_POISON2; |
| 104 | } | 109 | } |
| 105 | #else | 110 | #else |
| 111 | extern void __list_del_entry(struct list_head *entry); | ||
| 106 | extern void list_del(struct list_head *entry); | 112 | extern void list_del(struct list_head *entry); |
| 107 | #endif | 113 | #endif |
| 108 | 114 | ||
| @@ -135,7 +141,7 @@ static inline void list_replace_init(struct list_head *old, | |||
| 135 | */ | 141 | */ |
| 136 | static inline void list_del_init(struct list_head *entry) | 142 | static inline void list_del_init(struct list_head *entry) |
| 137 | { | 143 | { |
| 138 | __list_del(entry->prev, entry->next); | 144 | __list_del_entry(entry); |
| 139 | INIT_LIST_HEAD(entry); | 145 | INIT_LIST_HEAD(entry); |
| 140 | } | 146 | } |
| 141 | 147 | ||
| @@ -146,7 +152,7 @@ static inline void list_del_init(struct list_head *entry) | |||
| 146 | */ | 152 | */ |
| 147 | static inline void list_move(struct list_head *list, struct list_head *head) | 153 | static inline void list_move(struct list_head *list, struct list_head *head) |
| 148 | { | 154 | { |
| 149 | __list_del(list->prev, list->next); | 155 | __list_del_entry(list); |
| 150 | list_add(list, head); | 156 | list_add(list, head); |
| 151 | } | 157 | } |
| 152 | 158 | ||
| @@ -158,7 +164,7 @@ static inline void list_move(struct list_head *list, struct list_head *head) | |||
| 158 | static inline void list_move_tail(struct list_head *list, | 164 | static inline void list_move_tail(struct list_head *list, |
| 159 | struct list_head *head) | 165 | struct list_head *head) |
| 160 | { | 166 | { |
| 161 | __list_del(list->prev, list->next); | 167 | __list_del_entry(list); |
| 162 | list_add_tail(list, head); | 168 | list_add_tail(list, head); |
| 163 | } | 169 | } |
| 164 | 170 | ||
diff --git a/include/linux/module.h b/include/linux/module.h index e7c6385c668..9bdf27c7615 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -377,7 +377,7 @@ struct module | |||
| 377 | keeping pointers to this stuff */ | 377 | keeping pointers to this stuff */ |
| 378 | char *args; | 378 | char *args; |
| 379 | #ifdef CONFIG_TRACEPOINTS | 379 | #ifdef CONFIG_TRACEPOINTS |
| 380 | struct tracepoint *tracepoints; | 380 | struct tracepoint * const *tracepoints_ptrs; |
| 381 | unsigned int num_tracepoints; | 381 | unsigned int num_tracepoints; |
| 382 | #endif | 382 | #endif |
| 383 | #ifdef HAVE_JUMP_LABEL | 383 | #ifdef HAVE_JUMP_LABEL |
| @@ -389,7 +389,7 @@ struct module | |||
| 389 | unsigned int num_trace_bprintk_fmt; | 389 | unsigned int num_trace_bprintk_fmt; |
| 390 | #endif | 390 | #endif |
| 391 | #ifdef CONFIG_EVENT_TRACING | 391 | #ifdef CONFIG_EVENT_TRACING |
| 392 | struct ftrace_event_call *trace_events; | 392 | struct ftrace_event_call **trace_events; |
| 393 | unsigned int num_trace_events; | 393 | unsigned int num_trace_events; |
| 394 | #endif | 394 | #endif |
| 395 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 395 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
diff --git a/include/linux/mroute.h b/include/linux/mroute.h index 0fa7a3a874c..b21d567692b 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h | |||
| @@ -150,6 +150,7 @@ static inline int ip_mroute_opt(int opt) | |||
| 150 | extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int); | 150 | extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int); |
| 151 | extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *); | 151 | extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *); |
| 152 | extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); | 152 | extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); |
| 153 | extern int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); | ||
| 153 | extern int ip_mr_init(void); | 154 | extern int ip_mr_init(void); |
| 154 | #else | 155 | #else |
| 155 | static inline | 156 | static inline |
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 6091ab77f38..9d2deb200f5 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h | |||
| @@ -136,6 +136,7 @@ extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, unsigned int | |||
| 136 | extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *); | 136 | extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *); |
| 137 | extern int ip6_mr_input(struct sk_buff *skb); | 137 | extern int ip6_mr_input(struct sk_buff *skb); |
| 138 | extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); | 138 | extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); |
| 139 | extern int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); | ||
| 139 | extern int ip6_mr_init(void); | 140 | extern int ip6_mr_init(void); |
| 140 | extern void ip6_mr_cleanup(void); | 141 | extern void ip6_mr_cleanup(void); |
| 141 | #else | 142 | #else |
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index 32fb81212fd..1ca64113efe 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/printk.h> | ||
| 19 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
| 20 | 22 | ||
| 21 | /* Each escaped entry is prefixed by ESCAPE_CODE | 23 | /* Each escaped entry is prefixed by ESCAPE_CODE |
| @@ -186,10 +188,17 @@ int oprofile_add_data(struct op_entry *entry, unsigned long val); | |||
| 186 | int oprofile_add_data64(struct op_entry *entry, u64 val); | 188 | int oprofile_add_data64(struct op_entry *entry, u64 val); |
| 187 | int oprofile_write_commit(struct op_entry *entry); | 189 | int oprofile_write_commit(struct op_entry *entry); |
| 188 | 190 | ||
| 189 | #ifdef CONFIG_PERF_EVENTS | 191 | #ifdef CONFIG_HW_PERF_EVENTS |
| 190 | int __init oprofile_perf_init(struct oprofile_operations *ops); | 192 | int __init oprofile_perf_init(struct oprofile_operations *ops); |
| 191 | void oprofile_perf_exit(void); | 193 | void oprofile_perf_exit(void); |
| 192 | char *op_name_from_perf_id(void); | 194 | char *op_name_from_perf_id(void); |
| 193 | #endif /* CONFIG_PERF_EVENTS */ | 195 | #else |
| 196 | static inline int __init oprofile_perf_init(struct oprofile_operations *ops) | ||
| 197 | { | ||
| 198 | pr_info("oprofile: hardware counters not available\n"); | ||
| 199 | return -ENODEV; | ||
| 200 | } | ||
| 201 | static inline void oprofile_perf_exit(void) { } | ||
| 202 | #endif /* CONFIG_HW_PERF_EVENTS */ | ||
| 194 | 203 | ||
| 195 | #endif /* OPROFILE_H */ | 204 | #endif /* OPROFILE_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index d747f948b34..777d8a5ed06 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1744,7 +1744,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * | |||
| 1744 | #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ | 1744 | #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ |
| 1745 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ | 1745 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ |
| 1746 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ | 1746 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ |
| 1747 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ | 1747 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ |
| 1748 | #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ | 1748 | #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ |
| 1749 | 1749 | ||
| 1750 | /* | 1750 | /* |
diff --git a/include/linux/security.h b/include/linux/security.h index c642bb8b8f5..b2b7f9749f5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -1662,7 +1662,7 @@ int security_capset(struct cred *new, const struct cred *old, | |||
| 1662 | const kernel_cap_t *effective, | 1662 | const kernel_cap_t *effective, |
| 1663 | const kernel_cap_t *inheritable, | 1663 | const kernel_cap_t *inheritable, |
| 1664 | const kernel_cap_t *permitted); | 1664 | const kernel_cap_t *permitted); |
| 1665 | int security_capable(int cap); | 1665 | int security_capable(const struct cred *cred, int cap); |
| 1666 | int security_real_capable(struct task_struct *tsk, int cap); | 1666 | int security_real_capable(struct task_struct *tsk, int cap); |
| 1667 | int security_real_capable_noaudit(struct task_struct *tsk, int cap); | 1667 | int security_real_capable_noaudit(struct task_struct *tsk, int cap); |
| 1668 | int security_sysctl(struct ctl_table *table, int op); | 1668 | int security_sysctl(struct ctl_table *table, int op); |
| @@ -1856,9 +1856,9 @@ static inline int security_capset(struct cred *new, | |||
| 1856 | return cap_capset(new, old, effective, inheritable, permitted); | 1856 | return cap_capset(new, old, effective, inheritable, permitted); |
| 1857 | } | 1857 | } |
| 1858 | 1858 | ||
| 1859 | static inline int security_capable(int cap) | 1859 | static inline int security_capable(const struct cred *cred, int cap) |
| 1860 | { | 1860 | { |
| 1861 | return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT); | 1861 | return cap_capable(current, cred, cap, SECURITY_CAP_AUDIT); |
| 1862 | } | 1862 | } |
| 1863 | 1863 | ||
| 1864 | static inline int security_real_capable(struct task_struct *tsk, int cap) | 1864 | static inline int security_real_capable(struct task_struct *tsk, int cap) |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 18cd0684fc4..98664db1be4 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -125,39 +125,37 @@ extern struct trace_event_functions enter_syscall_print_funcs; | |||
| 125 | extern struct trace_event_functions exit_syscall_print_funcs; | 125 | extern struct trace_event_functions exit_syscall_print_funcs; |
| 126 | 126 | ||
| 127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
| 128 | static struct syscall_metadata \ | 128 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 129 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
| 130 | static struct ftrace_event_call __used \ | 129 | static struct ftrace_event_call __used \ |
| 131 | __attribute__((__aligned__(4))) \ | ||
| 132 | __attribute__((section("_ftrace_events"))) \ | ||
| 133 | event_enter_##sname = { \ | 130 | event_enter_##sname = { \ |
| 134 | .name = "sys_enter"#sname, \ | 131 | .name = "sys_enter"#sname, \ |
| 135 | .class = &event_class_syscall_enter, \ | 132 | .class = &event_class_syscall_enter, \ |
| 136 | .event.funcs = &enter_syscall_print_funcs, \ | 133 | .event.funcs = &enter_syscall_print_funcs, \ |
| 137 | .data = (void *)&__syscall_meta_##sname,\ | 134 | .data = (void *)&__syscall_meta_##sname,\ |
| 138 | }; \ | 135 | }; \ |
| 136 | static struct ftrace_event_call __used \ | ||
| 137 | __attribute__((section("_ftrace_events"))) \ | ||
| 138 | *__event_enter_##sname = &event_enter_##sname; \ | ||
| 139 | __TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY) | 139 | __TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY) |
| 140 | 140 | ||
| 141 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 141 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
| 142 | static struct syscall_metadata \ | 142 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 143 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
| 144 | static struct ftrace_event_call __used \ | 143 | static struct ftrace_event_call __used \ |
| 145 | __attribute__((__aligned__(4))) \ | ||
| 146 | __attribute__((section("_ftrace_events"))) \ | ||
| 147 | event_exit_##sname = { \ | 144 | event_exit_##sname = { \ |
| 148 | .name = "sys_exit"#sname, \ | 145 | .name = "sys_exit"#sname, \ |
| 149 | .class = &event_class_syscall_exit, \ | 146 | .class = &event_class_syscall_exit, \ |
| 150 | .event.funcs = &exit_syscall_print_funcs, \ | 147 | .event.funcs = &exit_syscall_print_funcs, \ |
| 151 | .data = (void *)&__syscall_meta_##sname,\ | 148 | .data = (void *)&__syscall_meta_##sname,\ |
| 152 | }; \ | 149 | }; \ |
| 150 | static struct ftrace_event_call __used \ | ||
| 151 | __attribute__((section("_ftrace_events"))) \ | ||
| 152 | *__event_exit_##sname = &event_exit_##sname; \ | ||
| 153 | __TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY) | 153 | __TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY) |
| 154 | 154 | ||
| 155 | #define SYSCALL_METADATA(sname, nb) \ | 155 | #define SYSCALL_METADATA(sname, nb) \ |
| 156 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | 156 | SYSCALL_TRACE_ENTER_EVENT(sname); \ |
| 157 | SYSCALL_TRACE_EXIT_EVENT(sname); \ | 157 | SYSCALL_TRACE_EXIT_EVENT(sname); \ |
| 158 | static struct syscall_metadata __used \ | 158 | static struct syscall_metadata __used \ |
| 159 | __attribute__((__aligned__(4))) \ | ||
| 160 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 161 | __syscall_meta_##sname = { \ | 159 | __syscall_meta_##sname = { \ |
| 162 | .name = "sys"#sname, \ | 160 | .name = "sys"#sname, \ |
| 163 | .nb_args = nb, \ | 161 | .nb_args = nb, \ |
| @@ -166,14 +164,15 @@ extern struct trace_event_functions exit_syscall_print_funcs; | |||
| 166 | .enter_event = &event_enter_##sname, \ | 164 | .enter_event = &event_enter_##sname, \ |
| 167 | .exit_event = &event_exit_##sname, \ | 165 | .exit_event = &event_exit_##sname, \ |
| 168 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ | 166 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ |
| 169 | }; | 167 | }; \ |
| 168 | static struct syscall_metadata __used \ | ||
| 169 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 170 | *__p_syscall_meta_##sname = &__syscall_meta_##sname; | ||
| 170 | 171 | ||
| 171 | #define SYSCALL_DEFINE0(sname) \ | 172 | #define SYSCALL_DEFINE0(sname) \ |
| 172 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | 173 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ |
| 173 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | 174 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ |
| 174 | static struct syscall_metadata __used \ | 175 | static struct syscall_metadata __used \ |
| 175 | __attribute__((__aligned__(4))) \ | ||
| 176 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 177 | __syscall_meta__##sname = { \ | 176 | __syscall_meta__##sname = { \ |
| 178 | .name = "sys_"#sname, \ | 177 | .name = "sys_"#sname, \ |
| 179 | .nb_args = 0, \ | 178 | .nb_args = 0, \ |
| @@ -181,6 +180,9 @@ extern struct trace_event_functions exit_syscall_print_funcs; | |||
| 181 | .exit_event = &event_exit__##sname, \ | 180 | .exit_event = &event_exit__##sname, \ |
| 182 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ | 181 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ |
| 183 | }; \ | 182 | }; \ |
| 183 | static struct syscall_metadata __used \ | ||
| 184 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 185 | *__p_syscall_meta_##sname = &__syscall_meta__##sname; \ | ||
| 184 | asmlinkage long sys_##sname(void) | 186 | asmlinkage long sys_##sname(void) |
| 185 | #else | 187 | #else |
| 186 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 188 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index c6814616653..97c84a58efb 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -33,12 +33,7 @@ struct tracepoint { | |||
| 33 | void (*regfunc)(void); | 33 | void (*regfunc)(void); |
| 34 | void (*unregfunc)(void); | 34 | void (*unregfunc)(void); |
| 35 | struct tracepoint_func __rcu *funcs; | 35 | struct tracepoint_func __rcu *funcs; |
| 36 | } __attribute__((aligned(32))); /* | 36 | }; |
| 37 | * Aligned on 32 bytes because it is | ||
| 38 | * globally visible and gcc happily | ||
| 39 | * align these on the structure size. | ||
| 40 | * Keep in sync with vmlinux.lds.h. | ||
| 41 | */ | ||
| 42 | 37 | ||
| 43 | /* | 38 | /* |
| 44 | * Connect a probe to a tracepoint. | 39 | * Connect a probe to a tracepoint. |
| @@ -61,15 +56,15 @@ extern void tracepoint_probe_update_all(void); | |||
| 61 | 56 | ||
| 62 | struct tracepoint_iter { | 57 | struct tracepoint_iter { |
| 63 | struct module *module; | 58 | struct module *module; |
| 64 | struct tracepoint *tracepoint; | 59 | struct tracepoint * const *tracepoint; |
| 65 | }; | 60 | }; |
| 66 | 61 | ||
| 67 | extern void tracepoint_iter_start(struct tracepoint_iter *iter); | 62 | extern void tracepoint_iter_start(struct tracepoint_iter *iter); |
| 68 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); | 63 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); |
| 69 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); | 64 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); |
| 70 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); | 65 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); |
| 71 | extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, | 66 | extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, |
| 72 | struct tracepoint *begin, struct tracepoint *end); | 67 | struct tracepoint * const *begin, struct tracepoint * const *end); |
| 73 | 68 | ||
| 74 | /* | 69 | /* |
| 75 | * tracepoint_synchronize_unregister must be called between the last tracepoint | 70 | * tracepoint_synchronize_unregister must be called between the last tracepoint |
| @@ -84,11 +79,13 @@ static inline void tracepoint_synchronize_unregister(void) | |||
| 84 | #define PARAMS(args...) args | 79 | #define PARAMS(args...) args |
| 85 | 80 | ||
| 86 | #ifdef CONFIG_TRACEPOINTS | 81 | #ifdef CONFIG_TRACEPOINTS |
| 87 | extern void tracepoint_update_probe_range(struct tracepoint *begin, | 82 | extern |
| 88 | struct tracepoint *end); | 83 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 84 | struct tracepoint * const *end); | ||
| 89 | #else | 85 | #else |
| 90 | static inline void tracepoint_update_probe_range(struct tracepoint *begin, | 86 | static inline |
| 91 | struct tracepoint *end) | 87 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 88 | struct tracepoint * const *end) | ||
| 92 | { } | 89 | { } |
| 93 | #endif /* CONFIG_TRACEPOINTS */ | 90 | #endif /* CONFIG_TRACEPOINTS */ |
| 94 | 91 | ||
| @@ -174,12 +171,20 @@ do_trace: \ | |||
| 174 | { \ | 171 | { \ |
| 175 | } | 172 | } |
| 176 | 173 | ||
| 174 | /* | ||
| 175 | * We have no guarantee that gcc and the linker won't up-align the tracepoint | ||
| 176 | * structures, so we create an array of pointers that will be used for iteration | ||
| 177 | * on the tracepoints. | ||
| 178 | */ | ||
| 177 | #define DEFINE_TRACE_FN(name, reg, unreg) \ | 179 | #define DEFINE_TRACE_FN(name, reg, unreg) \ |
| 178 | static const char __tpstrtab_##name[] \ | 180 | static const char __tpstrtab_##name[] \ |
| 179 | __attribute__((section("__tracepoints_strings"))) = #name; \ | 181 | __attribute__((section("__tracepoints_strings"))) = #name; \ |
| 180 | struct tracepoint __tracepoint_##name \ | 182 | struct tracepoint __tracepoint_##name \ |
| 181 | __attribute__((section("__tracepoints"), aligned(32))) = \ | 183 | __attribute__((section("__tracepoints"))) = \ |
| 182 | { __tpstrtab_##name, 0, reg, unreg, NULL } | 184 | { __tpstrtab_##name, 0, reg, unreg, NULL }; \ |
| 185 | static struct tracepoint * const __tracepoint_ptr_##name __used \ | ||
| 186 | __attribute__((section("__tracepoints_ptrs"))) = \ | ||
| 187 | &__tracepoint_##name; | ||
| 183 | 188 | ||
| 184 | #define DEFINE_TRACE(name) \ | 189 | #define DEFINE_TRACE(name) \ |
| 185 | DEFINE_TRACE_FN(name, NULL, NULL); | 190 | DEFINE_TRACE_FN(name, NULL, NULL); |
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h index 5e86dc771da..81a927930bf 100644 --- a/include/linux/usb/cdc.h +++ b/include/linux/usb/cdc.h | |||
| @@ -89,7 +89,7 @@ struct usb_cdc_acm_descriptor { | |||
| 89 | 89 | ||
| 90 | #define USB_CDC_COMM_FEATURE 0x01 | 90 | #define USB_CDC_COMM_FEATURE 0x01 |
| 91 | #define USB_CDC_CAP_LINE 0x02 | 91 | #define USB_CDC_CAP_LINE 0x02 |
| 92 | #define USB_CDC_CAP_BRK 0x04 | 92 | #define USB_CDC_CAP_BRK 0x04 |
| 93 | #define USB_CDC_CAP_NOTIFY 0x08 | 93 | #define USB_CDC_CAP_NOTIFY 0x08 |
| 94 | 94 | ||
| 95 | /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ | 95 | /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ |
| @@ -271,6 +271,11 @@ struct usb_cdc_notification { | |||
| 271 | __le16 wLength; | 271 | __le16 wLength; |
| 272 | } __attribute__ ((packed)); | 272 | } __attribute__ ((packed)); |
| 273 | 273 | ||
| 274 | struct usb_cdc_speed_change { | ||
| 275 | __le32 DLBitRRate; /* contains the downlink bit rate (IN pipe) */ | ||
| 276 | __le32 ULBitRate; /* contains the uplink bit rate (OUT pipe) */ | ||
| 277 | } __attribute__ ((packed)); | ||
| 278 | |||
| 274 | /*-------------------------------------------------------------------------*/ | 279 | /*-------------------------------------------------------------------------*/ |
| 275 | 280 | ||
| 276 | /* | 281 | /* |
| @@ -292,7 +297,7 @@ struct usb_cdc_ncm_ntb_parameters { | |||
| 292 | __le16 wNdpOutDivisor; | 297 | __le16 wNdpOutDivisor; |
| 293 | __le16 wNdpOutPayloadRemainder; | 298 | __le16 wNdpOutPayloadRemainder; |
| 294 | __le16 wNdpOutAlignment; | 299 | __le16 wNdpOutAlignment; |
| 295 | __le16 wPadding2; | 300 | __le16 wNtbOutMaxDatagrams; |
| 296 | } __attribute__ ((packed)); | 301 | } __attribute__ ((packed)); |
| 297 | 302 | ||
| 298 | /* | 303 | /* |
| @@ -307,7 +312,7 @@ struct usb_cdc_ncm_nth16 { | |||
| 307 | __le16 wHeaderLength; | 312 | __le16 wHeaderLength; |
| 308 | __le16 wSequence; | 313 | __le16 wSequence; |
| 309 | __le16 wBlockLength; | 314 | __le16 wBlockLength; |
| 310 | __le16 wFpIndex; | 315 | __le16 wNdpIndex; |
| 311 | } __attribute__ ((packed)); | 316 | } __attribute__ ((packed)); |
| 312 | 317 | ||
| 313 | struct usb_cdc_ncm_nth32 { | 318 | struct usb_cdc_ncm_nth32 { |
| @@ -315,7 +320,7 @@ struct usb_cdc_ncm_nth32 { | |||
| 315 | __le16 wHeaderLength; | 320 | __le16 wHeaderLength; |
| 316 | __le16 wSequence; | 321 | __le16 wSequence; |
| 317 | __le32 dwBlockLength; | 322 | __le32 dwBlockLength; |
| 318 | __le32 dwFpIndex; | 323 | __le32 dwNdpIndex; |
| 319 | } __attribute__ ((packed)); | 324 | } __attribute__ ((packed)); |
| 320 | 325 | ||
| 321 | /* | 326 | /* |
| @@ -337,7 +342,7 @@ struct usb_cdc_ncm_dpe16 { | |||
| 337 | struct usb_cdc_ncm_ndp16 { | 342 | struct usb_cdc_ncm_ndp16 { |
| 338 | __le32 dwSignature; | 343 | __le32 dwSignature; |
| 339 | __le16 wLength; | 344 | __le16 wLength; |
| 340 | __le16 wNextFpIndex; | 345 | __le16 wNextNdpIndex; |
| 341 | struct usb_cdc_ncm_dpe16 dpe16[0]; | 346 | struct usb_cdc_ncm_dpe16 dpe16[0]; |
| 342 | } __attribute__ ((packed)); | 347 | } __attribute__ ((packed)); |
| 343 | 348 | ||
| @@ -375,6 +380,7 @@ struct usb_cdc_ncm_ndp32 { | |||
| 375 | #define USB_CDC_NCM_NCAP_ENCAP_COMMAND (1 << 2) | 380 | #define USB_CDC_NCM_NCAP_ENCAP_COMMAND (1 << 2) |
| 376 | #define USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE (1 << 3) | 381 | #define USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE (1 << 3) |
| 377 | #define USB_CDC_NCM_NCAP_CRC_MODE (1 << 4) | 382 | #define USB_CDC_NCM_NCAP_CRC_MODE (1 << 4) |
| 383 | #define USB_CDC_NCM_NCAP_NTB_INPUT_SIZE (1 << 5) | ||
| 378 | 384 | ||
| 379 | /* CDC NCM subclass Table 6-3: NTB Parameter Structure */ | 385 | /* CDC NCM subclass Table 6-3: NTB Parameter Structure */ |
| 380 | #define USB_CDC_NCM_NTB16_SUPPORTED (1 << 0) | 386 | #define USB_CDC_NCM_NTB16_SUPPORTED (1 << 0) |
| @@ -392,6 +398,13 @@ struct usb_cdc_ncm_ndp32 { | |||
| 392 | #define USB_CDC_NCM_NTB_MIN_IN_SIZE 2048 | 398 | #define USB_CDC_NCM_NTB_MIN_IN_SIZE 2048 |
| 393 | #define USB_CDC_NCM_NTB_MIN_OUT_SIZE 2048 | 399 | #define USB_CDC_NCM_NTB_MIN_OUT_SIZE 2048 |
| 394 | 400 | ||
| 401 | /* NTB Input Size Structure */ | ||
| 402 | struct usb_cdc_ncm_ndp_input_size { | ||
| 403 | __le32 dwNtbInMaxSize; | ||
| 404 | __le16 wNtbInMaxDatagrams; | ||
| 405 | __le16 wReserved; | ||
| 406 | } __attribute__ ((packed)); | ||
| 407 | |||
| 395 | /* CDC NCM subclass 6.2.11 SetCrcMode */ | 408 | /* CDC NCM subclass 6.2.11 SetCrcMode */ |
| 396 | #define USB_CDC_NCM_CRC_NOT_APPENDED 0x00 | 409 | #define USB_CDC_NCM_CRC_NOT_APPENDED 0x00 |
| 397 | #define USB_CDC_NCM_CRC_APPENDED 0x01 | 410 | #define USB_CDC_NCM_CRC_APPENDED 0x01 |
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h index b92e17349c7..7d1babbff07 100644 --- a/include/linux/usb/msm_hsusb_hw.h +++ b/include/linux/usb/msm_hsusb_hw.h | |||
| @@ -16,12 +16,8 @@ | |||
| 16 | #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ | 16 | #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ |
| 17 | #define __LINUX_USB_GADGET_MSM72K_UDC_H__ | 17 | #define __LINUX_USB_GADGET_MSM72K_UDC_H__ |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_ARCH_MSM7X00A | ||
| 20 | #define USB_SBUSCFG (MSM_USB_BASE + 0x0090) | ||
| 21 | #else | ||
| 22 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) | 19 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) |
| 23 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) | 20 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) |
| 24 | #endif | ||
| 25 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ | 21 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ |
| 26 | 22 | ||
| 27 | #define USB_USBCMD (MSM_USB_BASE + 0x0140) | 23 | #define USB_USBCMD (MSM_USB_BASE + 0x0140) |
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index a85064db8f9..e4d333543a3 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h | |||
| @@ -7,7 +7,8 @@ | |||
| 7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | 7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so |
| 8 | * anyone can use the definitions to implement compatible drivers/servers. | 8 | * anyone can use the definitions to implement compatible drivers/servers. |
| 9 | * | 9 | * |
| 10 | * Copyright (C) Red Hat, Inc., 2009, 2010 | 10 | * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 |
| 11 | * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011 | ||
| 11 | */ | 12 | */ |
| 12 | 13 | ||
| 13 | /* Feature bits */ | 14 | /* Feature bits */ |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 1ac11586a2f..f7998a3bf02 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
| @@ -250,7 +250,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } | |||
| 250 | enum { | 250 | enum { |
| 251 | WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ | 251 | WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ |
| 252 | WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ | 252 | WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ |
| 253 | WQ_FREEZEABLE = 1 << 2, /* freeze during suspend */ | 253 | WQ_FREEZABLE = 1 << 2, /* freeze during suspend */ |
| 254 | WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ | 254 | WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ |
| 255 | WQ_HIGHPRI = 1 << 4, /* high priority */ | 255 | WQ_HIGHPRI = 1 << 4, /* high priority */ |
| 256 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ | 256 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ |
| @@ -318,7 +318,7 @@ __alloc_workqueue_key(const char *name, unsigned int flags, int max_active, | |||
| 318 | /** | 318 | /** |
| 319 | * alloc_ordered_workqueue - allocate an ordered workqueue | 319 | * alloc_ordered_workqueue - allocate an ordered workqueue |
| 320 | * @name: name of the workqueue | 320 | * @name: name of the workqueue |
| 321 | * @flags: WQ_* flags (only WQ_FREEZEABLE and WQ_MEM_RECLAIM are meaningful) | 321 | * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful) |
| 322 | * | 322 | * |
| 323 | * Allocate an ordered workqueue. An ordered workqueue executes at | 323 | * Allocate an ordered workqueue. An ordered workqueue executes at |
| 324 | * most one work item at any given time in the queued order. They are | 324 | * most one work item at any given time in the queued order. They are |
| @@ -335,8 +335,8 @@ alloc_ordered_workqueue(const char *name, unsigned int flags) | |||
| 335 | 335 | ||
| 336 | #define create_workqueue(name) \ | 336 | #define create_workqueue(name) \ |
| 337 | alloc_workqueue((name), WQ_MEM_RECLAIM, 1) | 337 | alloc_workqueue((name), WQ_MEM_RECLAIM, 1) |
| 338 | #define create_freezeable_workqueue(name) \ | 338 | #define create_freezable_workqueue(name) \ |
| 339 | alloc_workqueue((name), WQ_FREEZEABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1) | 339 | alloc_workqueue((name), WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1) |
| 340 | #define create_singlethread_workqueue(name) \ | 340 | #define create_singlethread_workqueue(name) \ |
| 341 | alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1) | 341 | alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1) |
| 342 | 342 | ||
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 8a64b811a39..b4c7c1cbcf4 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
| @@ -195,7 +195,8 @@ static inline int genlmsg_end(struct sk_buff *skb, void *hdr) | |||
| 195 | */ | 195 | */ |
| 196 | static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) | 196 | static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr) |
| 197 | { | 197 | { |
| 198 | nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN); | 198 | if (hdr) |
| 199 | nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN); | ||
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | /** | 202 | /** |
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 96ba5f7dcab..349cefedc9f 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h | |||
| @@ -77,9 +77,6 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) | |||
| 77 | if (e == NULL) | 77 | if (e == NULL) |
| 78 | return; | 78 | return; |
| 79 | 79 | ||
| 80 | if (!(e->ctmask & (1 << event))) | ||
| 81 | return; | ||
| 82 | |||
| 83 | set_bit(event, &e->cache); | 80 | set_bit(event, &e->cache); |
| 84 | } | 81 | } |
| 85 | 82 | ||
diff --git a/include/net/sock.h b/include/net/sock.h index d884d268c70..bc1cf7d88cc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -753,6 +753,8 @@ struct proto { | |||
| 753 | int level, | 753 | int level, |
| 754 | int optname, char __user *optval, | 754 | int optname, char __user *optval, |
| 755 | int __user *option); | 755 | int __user *option); |
| 756 | int (*compat_ioctl)(struct sock *sk, | ||
| 757 | unsigned int cmd, unsigned long arg); | ||
| 756 | #endif | 758 | #endif |
| 757 | int (*sendmsg)(struct kiocb *iocb, struct sock *sk, | 759 | int (*sendmsg)(struct kiocb *iocb, struct sock *sk, |
| 758 | struct msghdr *msg, size_t len); | 760 | struct msghdr *msg, size_t len); |
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 648d2335803..b76d4006e36 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #define _SCSI_SCSI_H | 9 | #define _SCSI_SCSI_H |
| 10 | 10 | ||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <linux/scatterlist.h> | ||
| 12 | 13 | ||
| 13 | struct scsi_cmnd; | 14 | struct scsi_cmnd; |
| 14 | 15 | ||
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 07fdfb6b9a9..0828b6c8610 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <scsi/scsi_cmnd.h> | 8 | #include <scsi/scsi_cmnd.h> |
| 9 | #include <net/sock.h> | 9 | #include <net/sock.h> |
| 10 | #include <net/tcp.h> | 10 | #include <net/tcp.h> |
| 11 | #include "target_core_mib.h" | ||
| 12 | 11 | ||
| 13 | #define TARGET_CORE_MOD_VERSION "v4.0.0-rc6" | 12 | #define TARGET_CORE_MOD_VERSION "v4.0.0-rc6" |
| 14 | #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT)) | 13 | #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT)) |
| @@ -195,6 +194,21 @@ typedef enum { | |||
| 195 | SAM_TASK_ATTR_EMULATED | 194 | SAM_TASK_ATTR_EMULATED |
| 196 | } t10_task_attr_index_t; | 195 | } t10_task_attr_index_t; |
| 197 | 196 | ||
| 197 | /* | ||
| 198 | * Used for target SCSI statistics | ||
| 199 | */ | ||
| 200 | typedef enum { | ||
| 201 | SCSI_INST_INDEX, | ||
| 202 | SCSI_DEVICE_INDEX, | ||
| 203 | SCSI_AUTH_INTR_INDEX, | ||
| 204 | SCSI_INDEX_TYPE_MAX | ||
| 205 | } scsi_index_t; | ||
| 206 | |||
| 207 | struct scsi_index_table { | ||
| 208 | spinlock_t lock; | ||
| 209 | u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; | ||
| 210 | } ____cacheline_aligned; | ||
| 211 | |||
| 198 | struct se_cmd; | 212 | struct se_cmd; |
| 199 | 213 | ||
| 200 | struct t10_alua { | 214 | struct t10_alua { |
| @@ -578,8 +592,6 @@ struct se_node_acl { | |||
| 578 | spinlock_t stats_lock; | 592 | spinlock_t stats_lock; |
| 579 | /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ | 593 | /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ |
| 580 | atomic_t acl_pr_ref_count; | 594 | atomic_t acl_pr_ref_count; |
| 581 | /* Used for MIB access */ | ||
| 582 | atomic_t mib_ref_count; | ||
| 583 | struct se_dev_entry *device_list; | 595 | struct se_dev_entry *device_list; |
| 584 | struct se_session *nacl_sess; | 596 | struct se_session *nacl_sess; |
| 585 | struct se_portal_group *se_tpg; | 597 | struct se_portal_group *se_tpg; |
| @@ -595,8 +607,6 @@ struct se_node_acl { | |||
| 595 | } ____cacheline_aligned; | 607 | } ____cacheline_aligned; |
| 596 | 608 | ||
| 597 | struct se_session { | 609 | struct se_session { |
| 598 | /* Used for MIB access */ | ||
| 599 | atomic_t mib_ref_count; | ||
| 600 | u64 sess_bin_isid; | 610 | u64 sess_bin_isid; |
| 601 | struct se_node_acl *se_node_acl; | 611 | struct se_node_acl *se_node_acl; |
| 602 | struct se_portal_group *se_tpg; | 612 | struct se_portal_group *se_tpg; |
| @@ -806,7 +816,6 @@ struct se_hba { | |||
| 806 | /* Virtual iSCSI devices attached. */ | 816 | /* Virtual iSCSI devices attached. */ |
| 807 | u32 dev_count; | 817 | u32 dev_count; |
| 808 | u32 hba_index; | 818 | u32 hba_index; |
| 809 | atomic_t dev_mib_access_count; | ||
| 810 | atomic_t load_balance_queue; | 819 | atomic_t load_balance_queue; |
| 811 | atomic_t left_queue_depth; | 820 | atomic_t left_queue_depth; |
| 812 | /* Maximum queue depth the HBA can handle. */ | 821 | /* Maximum queue depth the HBA can handle. */ |
| @@ -845,6 +854,12 @@ struct se_lun { | |||
| 845 | 854 | ||
| 846 | #define SE_LUN(c) ((struct se_lun *)(c)->se_lun) | 855 | #define SE_LUN(c) ((struct se_lun *)(c)->se_lun) |
| 847 | 856 | ||
| 857 | struct scsi_port_stats { | ||
| 858 | u64 cmd_pdus; | ||
| 859 | u64 tx_data_octets; | ||
| 860 | u64 rx_data_octets; | ||
| 861 | } ____cacheline_aligned; | ||
| 862 | |||
| 848 | struct se_port { | 863 | struct se_port { |
| 849 | /* RELATIVE TARGET PORT IDENTIFER */ | 864 | /* RELATIVE TARGET PORT IDENTIFER */ |
| 850 | u16 sep_rtpi; | 865 | u16 sep_rtpi; |
| @@ -867,6 +882,7 @@ struct se_port { | |||
| 867 | } ____cacheline_aligned; | 882 | } ____cacheline_aligned; |
| 868 | 883 | ||
| 869 | struct se_tpg_np { | 884 | struct se_tpg_np { |
| 885 | struct se_portal_group *tpg_np_parent; | ||
| 870 | struct config_group tpg_np_group; | 886 | struct config_group tpg_np_group; |
| 871 | } ____cacheline_aligned; | 887 | } ____cacheline_aligned; |
| 872 | 888 | ||
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index 66f44e56eb8..24694051157 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h | |||
| @@ -111,6 +111,8 @@ struct se_subsystem_api; | |||
| 111 | 111 | ||
| 112 | extern int init_se_global(void); | 112 | extern int init_se_global(void); |
| 113 | extern void release_se_global(void); | 113 | extern void release_se_global(void); |
| 114 | extern void init_scsi_index_table(void); | ||
| 115 | extern u32 scsi_get_new_index(scsi_index_t); | ||
| 114 | extern void transport_init_queue_obj(struct se_queue_obj *); | 116 | extern void transport_init_queue_obj(struct se_queue_obj *); |
| 115 | extern int transport_subsystem_check_init(void); | 117 | extern int transport_subsystem_check_init(void); |
| 116 | extern int transport_subsystem_register(struct se_subsystem_api *); | 118 | extern int transport_subsystem_register(struct se_subsystem_api *); |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index e16610c208c..3e68366d485 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -446,14 +446,16 @@ static inline notrace int ftrace_get_offsets_##call( \ | |||
| 446 | * .reg = ftrace_event_reg, | 446 | * .reg = ftrace_event_reg, |
| 447 | * }; | 447 | * }; |
| 448 | * | 448 | * |
| 449 | * static struct ftrace_event_call __used | 449 | * static struct ftrace_event_call event_<call> = { |
| 450 | * __attribute__((__aligned__(4))) | ||
| 451 | * __attribute__((section("_ftrace_events"))) event_<call> = { | ||
| 452 | * .name = "<call>", | 450 | * .name = "<call>", |
| 453 | * .class = event_class_<template>, | 451 | * .class = event_class_<template>, |
| 454 | * .event = &ftrace_event_type_<call>, | 452 | * .event = &ftrace_event_type_<call>, |
| 455 | * .print_fmt = print_fmt_<call>, | 453 | * .print_fmt = print_fmt_<call>, |
| 456 | * }; | 454 | * }; |
| 455 | * // its only safe to use pointers when doing linker tricks to | ||
| 456 | * // create an array. | ||
| 457 | * static struct ftrace_event_call __used | ||
| 458 | * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; | ||
| 457 | * | 459 | * |
| 458 | */ | 460 | */ |
| 459 | 461 | ||
| @@ -579,28 +581,28 @@ static struct ftrace_event_class __used event_class_##call = { \ | |||
| 579 | #undef DEFINE_EVENT | 581 | #undef DEFINE_EVENT |
| 580 | #define DEFINE_EVENT(template, call, proto, args) \ | 582 | #define DEFINE_EVENT(template, call, proto, args) \ |
| 581 | \ | 583 | \ |
| 582 | static struct ftrace_event_call __used \ | 584 | static struct ftrace_event_call __used event_##call = { \ |
| 583 | __attribute__((__aligned__(4))) \ | ||
| 584 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 585 | .name = #call, \ | 585 | .name = #call, \ |
| 586 | .class = &event_class_##template, \ | 586 | .class = &event_class_##template, \ |
| 587 | .event.funcs = &ftrace_event_type_funcs_##template, \ | 587 | .event.funcs = &ftrace_event_type_funcs_##template, \ |
| 588 | .print_fmt = print_fmt_##template, \ | 588 | .print_fmt = print_fmt_##template, \ |
| 589 | }; | 589 | }; \ |
| 590 | static struct ftrace_event_call __used \ | ||
| 591 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | ||
| 590 | 592 | ||
| 591 | #undef DEFINE_EVENT_PRINT | 593 | #undef DEFINE_EVENT_PRINT |
| 592 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 594 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
| 593 | \ | 595 | \ |
| 594 | static const char print_fmt_##call[] = print; \ | 596 | static const char print_fmt_##call[] = print; \ |
| 595 | \ | 597 | \ |
| 596 | static struct ftrace_event_call __used \ | 598 | static struct ftrace_event_call __used event_##call = { \ |
| 597 | __attribute__((__aligned__(4))) \ | ||
| 598 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 599 | .name = #call, \ | 599 | .name = #call, \ |
| 600 | .class = &event_class_##template, \ | 600 | .class = &event_class_##template, \ |
| 601 | .event.funcs = &ftrace_event_type_funcs_##call, \ | 601 | .event.funcs = &ftrace_event_type_funcs_##call, \ |
| 602 | .print_fmt = print_fmt_##call, \ | 602 | .print_fmt = print_fmt_##call, \ |
| 603 | } | 603 | }; \ |
| 604 | static struct ftrace_event_call __used \ | ||
| 605 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | ||
| 604 | 606 | ||
| 605 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 607 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 606 | 608 | ||
diff --git a/init/calibrate.c b/init/calibrate.c index 6eb48e53d61..24fe022c55f 100644 --- a/init/calibrate.c +++ b/init/calibrate.c | |||
| @@ -66,7 +66,7 @@ static unsigned long __cpuinit calibrate_delay_direct(void) | |||
| 66 | pre_start = 0; | 66 | pre_start = 0; |
| 67 | read_current_timer(&start); | 67 | read_current_timer(&start); |
| 68 | start_jiffies = jiffies; | 68 | start_jiffies = jiffies; |
| 69 | while (jiffies <= (start_jiffies + 1)) { | 69 | while (time_before_eq(jiffies, start_jiffies + 1)) { |
| 70 | pre_start = start; | 70 | pre_start = start; |
| 71 | read_current_timer(&start); | 71 | read_current_timer(&start); |
| 72 | } | 72 | } |
| @@ -74,8 +74,8 @@ static unsigned long __cpuinit calibrate_delay_direct(void) | |||
| 74 | 74 | ||
| 75 | pre_end = 0; | 75 | pre_end = 0; |
| 76 | end = post_start; | 76 | end = post_start; |
| 77 | while (jiffies <= | 77 | while (time_before_eq(jiffies, start_jiffies + 1 + |
| 78 | (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) { | 78 | DELAY_CALIBRATION_TICKS)) { |
| 79 | pre_end = end; | 79 | pre_end = end; |
| 80 | read_current_timer(&end); | 80 | read_current_timer(&end); |
| 81 | } | 81 | } |
diff --git a/kernel/capability.c b/kernel/capability.c index 2f05303715a..9e9385f132c 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
| @@ -306,7 +306,7 @@ int capable(int cap) | |||
| 306 | BUG(); | 306 | BUG(); |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | if (security_capable(cap) == 0) { | 309 | if (security_capable(current_cred(), cap) == 0) { |
| 310 | current->flags |= PF_SUPERPRIV; | 310 | current->flags |= PF_SUPERPRIV; |
| 311 | return 1; | 311 | return 1; |
| 312 | } | 312 | } |
diff --git a/kernel/cred.c b/kernel/cred.c index 6a1aa004e37..3a9d6dd53a6 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
| @@ -252,13 +252,13 @@ struct cred *cred_alloc_blank(void) | |||
| 252 | #endif | 252 | #endif |
| 253 | 253 | ||
| 254 | atomic_set(&new->usage, 1); | 254 | atomic_set(&new->usage, 1); |
| 255 | #ifdef CONFIG_DEBUG_CREDENTIALS | ||
| 256 | new->magic = CRED_MAGIC; | ||
| 257 | #endif | ||
| 255 | 258 | ||
| 256 | if (security_cred_alloc_blank(new, GFP_KERNEL) < 0) | 259 | if (security_cred_alloc_blank(new, GFP_KERNEL) < 0) |
| 257 | goto error; | 260 | goto error; |
| 258 | 261 | ||
| 259 | #ifdef CONFIG_DEBUG_CREDENTIALS | ||
| 260 | new->magic = CRED_MAGIC; | ||
| 261 | #endif | ||
| 262 | return new; | 262 | return new; |
| 263 | 263 | ||
| 264 | error: | 264 | error: |
| @@ -657,6 +657,8 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) | |||
| 657 | validate_creds(old); | 657 | validate_creds(old); |
| 658 | 658 | ||
| 659 | *new = *old; | 659 | *new = *old; |
| 660 | atomic_set(&new->usage, 1); | ||
| 661 | set_cred_subscribers(new, 0); | ||
| 660 | get_uid(new->user); | 662 | get_uid(new->user); |
| 661 | get_group_info(new->group_info); | 663 | get_group_info(new->group_info); |
| 662 | 664 | ||
| @@ -674,8 +676,6 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) | |||
| 674 | if (security_prepare_creds(new, old, GFP_KERNEL) < 0) | 676 | if (security_prepare_creds(new, old, GFP_KERNEL) < 0) |
| 675 | goto error; | 677 | goto error; |
| 676 | 678 | ||
| 677 | atomic_set(&new->usage, 1); | ||
| 678 | set_cred_subscribers(new, 0); | ||
| 679 | put_cred(old); | 679 | put_cred(old); |
| 680 | validate_creds(new); | 680 | validate_creds(new); |
| 681 | return new; | 681 | return new; |
| @@ -748,7 +748,11 @@ bool creds_are_invalid(const struct cred *cred) | |||
| 748 | if (cred->magic != CRED_MAGIC) | 748 | if (cred->magic != CRED_MAGIC) |
| 749 | return true; | 749 | return true; |
| 750 | #ifdef CONFIG_SECURITY_SELINUX | 750 | #ifdef CONFIG_SECURITY_SELINUX |
| 751 | if (selinux_is_enabled()) { | 751 | /* |
| 752 | * cred->security == NULL if security_cred_alloc_blank() or | ||
| 753 | * security_prepare_creds() returned an error. | ||
| 754 | */ | ||
| 755 | if (selinux_is_enabled() && cred->security) { | ||
| 752 | if ((unsigned long) cred->security < PAGE_SIZE) | 756 | if ((unsigned long) cred->security < PAGE_SIZE) |
| 753 | return true; | 757 | return true; |
| 754 | if ((*(u32 *)cred->security & 0xffffff00) == | 758 | if ((*(u32 *)cred->security & 0xffffff00) == |
diff --git a/kernel/module.c b/kernel/module.c index 34e00b708fa..efa290ea94b 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -2460,9 +2460,9 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
| 2460 | #endif | 2460 | #endif |
| 2461 | 2461 | ||
| 2462 | #ifdef CONFIG_TRACEPOINTS | 2462 | #ifdef CONFIG_TRACEPOINTS |
| 2463 | mod->tracepoints = section_objs(info, "__tracepoints", | 2463 | mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs", |
| 2464 | sizeof(*mod->tracepoints), | 2464 | sizeof(*mod->tracepoints_ptrs), |
| 2465 | &mod->num_tracepoints); | 2465 | &mod->num_tracepoints); |
| 2466 | #endif | 2466 | #endif |
| 2467 | #ifdef HAVE_JUMP_LABEL | 2467 | #ifdef HAVE_JUMP_LABEL |
| 2468 | mod->jump_entries = section_objs(info, "__jump_table", | 2468 | mod->jump_entries = section_objs(info, "__jump_table", |
| @@ -3393,7 +3393,7 @@ void module_layout(struct module *mod, | |||
| 3393 | struct modversion_info *ver, | 3393 | struct modversion_info *ver, |
| 3394 | struct kernel_param *kp, | 3394 | struct kernel_param *kp, |
| 3395 | struct kernel_symbol *ks, | 3395 | struct kernel_symbol *ks, |
| 3396 | struct tracepoint *tp) | 3396 | struct tracepoint * const *tp) |
| 3397 | { | 3397 | { |
| 3398 | } | 3398 | } |
| 3399 | EXPORT_SYMBOL(module_layout); | 3399 | EXPORT_SYMBOL(module_layout); |
| @@ -3407,8 +3407,8 @@ void module_update_tracepoints(void) | |||
| 3407 | mutex_lock(&module_mutex); | 3407 | mutex_lock(&module_mutex); |
| 3408 | list_for_each_entry(mod, &modules, list) | 3408 | list_for_each_entry(mod, &modules, list) |
| 3409 | if (!mod->taints) | 3409 | if (!mod->taints) |
| 3410 | tracepoint_update_probe_range(mod->tracepoints, | 3410 | tracepoint_update_probe_range(mod->tracepoints_ptrs, |
| 3411 | mod->tracepoints + mod->num_tracepoints); | 3411 | mod->tracepoints_ptrs + mod->num_tracepoints); |
| 3412 | mutex_unlock(&module_mutex); | 3412 | mutex_unlock(&module_mutex); |
| 3413 | } | 3413 | } |
| 3414 | 3414 | ||
| @@ -3432,8 +3432,8 @@ int module_get_iter_tracepoints(struct tracepoint_iter *iter) | |||
| 3432 | else if (iter_mod > iter->module) | 3432 | else if (iter_mod > iter->module) |
| 3433 | iter->tracepoint = NULL; | 3433 | iter->tracepoint = NULL; |
| 3434 | found = tracepoint_get_iter_range(&iter->tracepoint, | 3434 | found = tracepoint_get_iter_range(&iter->tracepoint, |
| 3435 | iter_mod->tracepoints, | 3435 | iter_mod->tracepoints_ptrs, |
| 3436 | iter_mod->tracepoints | 3436 | iter_mod->tracepoints_ptrs |
| 3437 | + iter_mod->num_tracepoints); | 3437 | + iter_mod->num_tracepoints); |
| 3438 | if (found) { | 3438 | if (found) { |
| 3439 | iter->module = iter_mod; | 3439 | iter->module = iter_mod; |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 7b5db6a8561..701853042c2 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -326,7 +326,7 @@ EXPORT_SYMBOL_GPL(pm_wq); | |||
| 326 | 326 | ||
| 327 | static int __init pm_start_workqueue(void) | 327 | static int __init pm_start_workqueue(void) |
| 328 | { | 328 | { |
| 329 | pm_wq = alloc_workqueue("pm", WQ_FREEZEABLE, 0); | 329 | pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0); |
| 330 | 330 | ||
| 331 | return pm_wq ? 0 : -ENOMEM; | 331 | return pm_wq ? 0 : -ENOMEM; |
| 332 | } | 332 | } |
diff --git a/kernel/power/process.c b/kernel/power/process.c index d6d2a10320e..0cf3a27a6c9 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | */ | 22 | */ |
| 23 | #define TIMEOUT (20 * HZ) | 23 | #define TIMEOUT (20 * HZ) |
| 24 | 24 | ||
| 25 | static inline int freezeable(struct task_struct * p) | 25 | static inline int freezable(struct task_struct * p) |
| 26 | { | 26 | { |
| 27 | if ((p == current) || | 27 | if ((p == current) || |
| 28 | (p->flags & PF_NOFREEZE) || | 28 | (p->flags & PF_NOFREEZE) || |
| @@ -53,7 +53,7 @@ static int try_to_freeze_tasks(bool sig_only) | |||
| 53 | todo = 0; | 53 | todo = 0; |
| 54 | read_lock(&tasklist_lock); | 54 | read_lock(&tasklist_lock); |
| 55 | do_each_thread(g, p) { | 55 | do_each_thread(g, p) { |
| 56 | if (frozen(p) || !freezeable(p)) | 56 | if (frozen(p) || !freezable(p)) |
| 57 | continue; | 57 | continue; |
| 58 | 58 | ||
| 59 | if (!freeze_task(p, sig_only)) | 59 | if (!freeze_task(p, sig_only)) |
| @@ -167,7 +167,7 @@ static void thaw_tasks(bool nosig_only) | |||
| 167 | 167 | ||
| 168 | read_lock(&tasklist_lock); | 168 | read_lock(&tasklist_lock); |
| 169 | do_each_thread(g, p) { | 169 | do_each_thread(g, p) { |
| 170 | if (!freezeable(p)) | 170 | if (!freezable(p)) |
| 171 | continue; | 171 | continue; |
| 172 | 172 | ||
| 173 | if (nosig_only && should_send_signal(p)) | 173 | if (nosig_only && should_send_signal(p)) |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0dac75ea445..64db648ff91 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
| @@ -1519,11 +1519,8 @@ static int | |||
| 1519 | swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, | 1519 | swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, |
| 1520 | unsigned int nr_pages, unsigned int nr_highmem) | 1520 | unsigned int nr_pages, unsigned int nr_highmem) |
| 1521 | { | 1521 | { |
| 1522 | int error = 0; | ||
| 1523 | |||
| 1524 | if (nr_highmem > 0) { | 1522 | if (nr_highmem > 0) { |
| 1525 | error = get_highmem_buffer(PG_ANY); | 1523 | if (get_highmem_buffer(PG_ANY)) |
| 1526 | if (error) | ||
| 1527 | goto err_out; | 1524 | goto err_out; |
| 1528 | if (nr_highmem > alloc_highmem) { | 1525 | if (nr_highmem > alloc_highmem) { |
| 1529 | nr_highmem -= alloc_highmem; | 1526 | nr_highmem -= alloc_highmem; |
| @@ -1546,7 +1543,7 @@ swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, | |||
| 1546 | 1543 | ||
| 1547 | err_out: | 1544 | err_out: |
| 1548 | swsusp_free(); | 1545 | swsusp_free(); |
| 1549 | return error; | 1546 | return -ENOMEM; |
| 1550 | } | 1547 | } |
| 1551 | 1548 | ||
| 1552 | asmlinkage int swsusp_save(void) | 1549 | asmlinkage int swsusp_save(void) |
diff --git a/kernel/printk.c b/kernel/printk.c index 2ddbdc73aad..36231525e22 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -262,25 +262,47 @@ int dmesg_restrict = 1; | |||
| 262 | int dmesg_restrict; | 262 | int dmesg_restrict; |
| 263 | #endif | 263 | #endif |
| 264 | 264 | ||
| 265 | static int syslog_action_restricted(int type) | ||
| 266 | { | ||
| 267 | if (dmesg_restrict) | ||
| 268 | return 1; | ||
| 269 | /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ | ||
| 270 | return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int check_syslog_permissions(int type, bool from_file) | ||
| 274 | { | ||
| 275 | /* | ||
| 276 | * If this is from /proc/kmsg and we've already opened it, then we've | ||
| 277 | * already done the capabilities checks at open time. | ||
| 278 | */ | ||
| 279 | if (from_file && type != SYSLOG_ACTION_OPEN) | ||
| 280 | return 0; | ||
| 281 | |||
| 282 | if (syslog_action_restricted(type)) { | ||
| 283 | if (capable(CAP_SYSLOG)) | ||
| 284 | return 0; | ||
| 285 | /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ | ||
| 286 | if (capable(CAP_SYS_ADMIN)) { | ||
| 287 | WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " | ||
| 288 | "but no CAP_SYSLOG (deprecated).\n"); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | return -EPERM; | ||
| 292 | } | ||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 265 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 296 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
| 266 | { | 297 | { |
| 267 | unsigned i, j, limit, count; | 298 | unsigned i, j, limit, count; |
| 268 | int do_clear = 0; | 299 | int do_clear = 0; |
| 269 | char c; | 300 | char c; |
| 270 | int error = 0; | 301 | int error; |
| 271 | 302 | ||
| 272 | /* | 303 | error = check_syslog_permissions(type, from_file); |
| 273 | * If this is from /proc/kmsg we only do the capabilities checks | 304 | if (error) |
| 274 | * at open time. | 305 | goto out; |
| 275 | */ | ||
| 276 | if (type == SYSLOG_ACTION_OPEN || !from_file) { | ||
| 277 | if (dmesg_restrict && !capable(CAP_SYSLOG)) | ||
| 278 | goto warn; /* switch to return -EPERM after 2.6.39 */ | ||
| 279 | if ((type != SYSLOG_ACTION_READ_ALL && | ||
| 280 | type != SYSLOG_ACTION_SIZE_BUFFER) && | ||
| 281 | !capable(CAP_SYSLOG)) | ||
| 282 | goto warn; /* switch to return -EPERM after 2.6.39 */ | ||
| 283 | } | ||
| 284 | 306 | ||
| 285 | error = security_syslog(type); | 307 | error = security_syslog(type); |
| 286 | if (error) | 308 | if (error) |
| @@ -423,12 +445,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 423 | } | 445 | } |
| 424 | out: | 446 | out: |
| 425 | return error; | 447 | return error; |
| 426 | warn: | ||
| 427 | /* remove after 2.6.39 */ | ||
| 428 | if (capable(CAP_SYS_ADMIN)) | ||
| 429 | WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " | ||
| 430 | "but no CAP_SYSLOG (deprecated and denied).\n"); | ||
| 431 | return -EPERM; | ||
| 432 | } | 448 | } |
| 433 | 449 | ||
| 434 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | 450 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 99bbaa3e5b0..1708b1e2972 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -313,7 +313,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
| 313 | child->exit_code = data; | 313 | child->exit_code = data; |
| 314 | dead = __ptrace_detach(current, child); | 314 | dead = __ptrace_detach(current, child); |
| 315 | if (!child->exit_state) | 315 | if (!child->exit_state) |
| 316 | wake_up_process(child); | 316 | wake_up_state(child, TASK_TRACED | TASK_STOPPED); |
| 317 | } | 317 | } |
| 318 | write_unlock_irq(&tasklist_lock); | 318 | write_unlock_irq(&tasklist_lock); |
| 319 | 319 | ||
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 32a19f9397f..3258455549f 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
| @@ -41,7 +41,7 @@ static void print_name_offset(struct seq_file *m, void *sym) | |||
| 41 | char symname[KSYM_NAME_LEN]; | 41 | char symname[KSYM_NAME_LEN]; |
| 42 | 42 | ||
| 43 | if (lookup_symbol_name((unsigned long)sym, symname) < 0) | 43 | if (lookup_symbol_name((unsigned long)sym, symname) < 0) |
| 44 | SEQ_printf(m, "<%p>", sym); | 44 | SEQ_printf(m, "<%pK>", sym); |
| 45 | else | 45 | else |
| 46 | SEQ_printf(m, "%s", symname); | 46 | SEQ_printf(m, "%s", symname); |
| 47 | } | 47 | } |
| @@ -112,7 +112,7 @@ next_one: | |||
| 112 | static void | 112 | static void |
| 113 | print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) | 113 | print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) |
| 114 | { | 114 | { |
| 115 | SEQ_printf(m, " .base: %p\n", base); | 115 | SEQ_printf(m, " .base: %pK\n", base); |
| 116 | SEQ_printf(m, " .index: %d\n", | 116 | SEQ_printf(m, " .index: %d\n", |
| 117 | base->index); | 117 | base->index); |
| 118 | SEQ_printf(m, " .resolution: %Lu nsecs\n", | 118 | SEQ_printf(m, " .resolution: %Lu nsecs\n", |
diff --git a/kernel/timer.c b/kernel/timer.c index 43ca9936f2d..d6459923d24 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -959,7 +959,7 @@ EXPORT_SYMBOL(try_to_del_timer_sync); | |||
| 959 | * | 959 | * |
| 960 | * Synchronization rules: Callers must prevent restarting of the timer, | 960 | * Synchronization rules: Callers must prevent restarting of the timer, |
| 961 | * otherwise this function is meaningless. It must not be called from | 961 | * otherwise this function is meaningless. It must not be called from |
| 962 | * hardirq contexts. The caller must not hold locks which would prevent | 962 | * interrupt contexts. The caller must not hold locks which would prevent |
| 963 | * completion of the timer's handler. The timer's handler must not call | 963 | * completion of the timer's handler. The timer's handler must not call |
| 964 | * add_timer_on(). Upon exit the timer is not queued and the handler is | 964 | * add_timer_on(). Upon exit the timer is not queued and the handler is |
| 965 | * not running on any CPU. | 965 | * not running on any CPU. |
| @@ -969,10 +969,12 @@ EXPORT_SYMBOL(try_to_del_timer_sync); | |||
| 969 | int del_timer_sync(struct timer_list *timer) | 969 | int del_timer_sync(struct timer_list *timer) |
| 970 | { | 970 | { |
| 971 | #ifdef CONFIG_LOCKDEP | 971 | #ifdef CONFIG_LOCKDEP |
| 972 | local_bh_disable(); | 972 | unsigned long flags; |
| 973 | |||
| 974 | local_irq_save(flags); | ||
| 973 | lock_map_acquire(&timer->lockdep_map); | 975 | lock_map_acquire(&timer->lockdep_map); |
| 974 | lock_map_release(&timer->lockdep_map); | 976 | lock_map_release(&timer->lockdep_map); |
| 975 | local_bh_enable(); | 977 | local_irq_restore(flags); |
| 976 | #endif | 978 | #endif |
| 977 | /* | 979 | /* |
| 978 | * don't use it in hardirq context, because it | 980 | * don't use it in hardirq context, because it |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 153562d0b93..d95721f3370 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -138,6 +138,13 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) | |||
| 138 | !blk_tracer_enabled)) | 138 | !blk_tracer_enabled)) |
| 139 | return; | 139 | return; |
| 140 | 140 | ||
| 141 | /* | ||
| 142 | * If the BLK_TC_NOTIFY action mask isn't set, don't send any note | ||
| 143 | * message to the trace. | ||
| 144 | */ | ||
| 145 | if (!(bt->act_mask & BLK_TC_NOTIFY)) | ||
| 146 | return; | ||
| 147 | |||
| 141 | local_irq_save(flags); | 148 | local_irq_save(flags); |
| 142 | buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); | 149 | buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); |
| 143 | va_start(args, fmt); | 150 | va_start(args, fmt); |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 35fde09b81d..5f499e0438a 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -1284,7 +1284,7 @@ trace_create_file_ops(struct module *mod) | |||
| 1284 | static void trace_module_add_events(struct module *mod) | 1284 | static void trace_module_add_events(struct module *mod) |
| 1285 | { | 1285 | { |
| 1286 | struct ftrace_module_file_ops *file_ops = NULL; | 1286 | struct ftrace_module_file_ops *file_ops = NULL; |
| 1287 | struct ftrace_event_call *call, *start, *end; | 1287 | struct ftrace_event_call **call, **start, **end; |
| 1288 | 1288 | ||
| 1289 | start = mod->trace_events; | 1289 | start = mod->trace_events; |
| 1290 | end = mod->trace_events + mod->num_trace_events; | 1290 | end = mod->trace_events + mod->num_trace_events; |
| @@ -1297,7 +1297,7 @@ static void trace_module_add_events(struct module *mod) | |||
| 1297 | return; | 1297 | return; |
| 1298 | 1298 | ||
| 1299 | for_each_event(call, start, end) { | 1299 | for_each_event(call, start, end) { |
| 1300 | __trace_add_event_call(call, mod, | 1300 | __trace_add_event_call(*call, mod, |
| 1301 | &file_ops->id, &file_ops->enable, | 1301 | &file_ops->id, &file_ops->enable, |
| 1302 | &file_ops->filter, &file_ops->format); | 1302 | &file_ops->filter, &file_ops->format); |
| 1303 | } | 1303 | } |
| @@ -1367,8 +1367,8 @@ static struct notifier_block trace_module_nb = { | |||
| 1367 | .priority = 0, | 1367 | .priority = 0, |
| 1368 | }; | 1368 | }; |
| 1369 | 1369 | ||
| 1370 | extern struct ftrace_event_call __start_ftrace_events[]; | 1370 | extern struct ftrace_event_call *__start_ftrace_events[]; |
| 1371 | extern struct ftrace_event_call __stop_ftrace_events[]; | 1371 | extern struct ftrace_event_call *__stop_ftrace_events[]; |
| 1372 | 1372 | ||
| 1373 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; | 1373 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; |
| 1374 | 1374 | ||
| @@ -1384,7 +1384,7 @@ __setup("trace_event=", setup_trace_event); | |||
| 1384 | 1384 | ||
| 1385 | static __init int event_trace_init(void) | 1385 | static __init int event_trace_init(void) |
| 1386 | { | 1386 | { |
| 1387 | struct ftrace_event_call *call; | 1387 | struct ftrace_event_call **call; |
| 1388 | struct dentry *d_tracer; | 1388 | struct dentry *d_tracer; |
| 1389 | struct dentry *entry; | 1389 | struct dentry *entry; |
| 1390 | struct dentry *d_events; | 1390 | struct dentry *d_events; |
| @@ -1430,7 +1430,7 @@ static __init int event_trace_init(void) | |||
| 1430 | pr_warning("tracing: Failed to allocate common fields"); | 1430 | pr_warning("tracing: Failed to allocate common fields"); |
| 1431 | 1431 | ||
| 1432 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | 1432 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { |
| 1433 | __trace_add_event_call(call, NULL, &ftrace_event_id_fops, | 1433 | __trace_add_event_call(*call, NULL, &ftrace_event_id_fops, |
| 1434 | &ftrace_enable_fops, | 1434 | &ftrace_enable_fops, |
| 1435 | &ftrace_event_filter_fops, | 1435 | &ftrace_event_filter_fops, |
| 1436 | &ftrace_event_format_fops); | 1436 | &ftrace_event_format_fops); |
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 4b74d71705c..bbeec31e0ae 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
| @@ -161,13 +161,13 @@ struct ftrace_event_class event_class_ftrace_##call = { \ | |||
| 161 | .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ | 161 | .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ |
| 162 | }; \ | 162 | }; \ |
| 163 | \ | 163 | \ |
| 164 | struct ftrace_event_call __used \ | 164 | struct ftrace_event_call __used event_##call = { \ |
| 165 | __attribute__((__aligned__(4))) \ | ||
| 166 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 167 | .name = #call, \ | 165 | .name = #call, \ |
| 168 | .event.type = etype, \ | 166 | .event.type = etype, \ |
| 169 | .class = &event_class_ftrace_##call, \ | 167 | .class = &event_class_ftrace_##call, \ |
| 170 | .print_fmt = print, \ | 168 | .print_fmt = print, \ |
| 171 | }; \ | 169 | }; \ |
| 170 | struct ftrace_event_call __used \ | ||
| 171 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; | ||
| 172 | 172 | ||
| 173 | #include "trace_entries.h" | 173 | #include "trace_entries.h" |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index b706529b4fc..5c9fe08d209 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -55,20 +55,21 @@ struct ftrace_event_class event_class_syscall_exit = { | |||
| 55 | .raw_init = init_syscall_trace, | 55 | .raw_init = init_syscall_trace, |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | extern unsigned long __start_syscalls_metadata[]; | 58 | extern struct syscall_metadata *__start_syscalls_metadata[]; |
| 59 | extern unsigned long __stop_syscalls_metadata[]; | 59 | extern struct syscall_metadata *__stop_syscalls_metadata[]; |
| 60 | 60 | ||
| 61 | static struct syscall_metadata **syscalls_metadata; | 61 | static struct syscall_metadata **syscalls_metadata; |
| 62 | 62 | ||
| 63 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | 63 | static __init struct syscall_metadata * |
| 64 | find_syscall_meta(unsigned long syscall) | ||
| 64 | { | 65 | { |
| 65 | struct syscall_metadata *start; | 66 | struct syscall_metadata **start; |
| 66 | struct syscall_metadata *stop; | 67 | struct syscall_metadata **stop; |
| 67 | char str[KSYM_SYMBOL_LEN]; | 68 | char str[KSYM_SYMBOL_LEN]; |
| 68 | 69 | ||
| 69 | 70 | ||
| 70 | start = (struct syscall_metadata *)__start_syscalls_metadata; | 71 | start = __start_syscalls_metadata; |
| 71 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | 72 | stop = __stop_syscalls_metadata; |
| 72 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); | 73 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); |
| 73 | 74 | ||
| 74 | for ( ; start < stop; start++) { | 75 | for ( ; start < stop; start++) { |
| @@ -78,8 +79,8 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | |||
| 78 | * with "SyS" instead of "sys", leading to an unwanted | 79 | * with "SyS" instead of "sys", leading to an unwanted |
| 79 | * mismatch. | 80 | * mismatch. |
| 80 | */ | 81 | */ |
| 81 | if (start->name && !strcmp(start->name + 3, str + 3)) | 82 | if ((*start)->name && !strcmp((*start)->name + 3, str + 3)) |
| 82 | return start; | 83 | return *start; |
| 83 | } | 84 | } |
| 84 | return NULL; | 85 | return NULL; |
| 85 | } | 86 | } |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index e95ee7f31d4..68187af4889 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -27,8 +27,8 @@ | |||
| 27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/jump_label.h> | 28 | #include <linux/jump_label.h> |
| 29 | 29 | ||
| 30 | extern struct tracepoint __start___tracepoints[]; | 30 | extern struct tracepoint * const __start___tracepoints_ptrs[]; |
| 31 | extern struct tracepoint __stop___tracepoints[]; | 31 | extern struct tracepoint * const __stop___tracepoints_ptrs[]; |
| 32 | 32 | ||
| 33 | /* Set to 1 to enable tracepoint debug output */ | 33 | /* Set to 1 to enable tracepoint debug output */ |
| 34 | static const int tracepoint_debug; | 34 | static const int tracepoint_debug; |
| @@ -298,10 +298,10 @@ static void disable_tracepoint(struct tracepoint *elem) | |||
| 298 | * | 298 | * |
| 299 | * Updates the probe callback corresponding to a range of tracepoints. | 299 | * Updates the probe callback corresponding to a range of tracepoints. |
| 300 | */ | 300 | */ |
| 301 | void | 301 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 302 | tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | 302 | struct tracepoint * const *end) |
| 303 | { | 303 | { |
| 304 | struct tracepoint *iter; | 304 | struct tracepoint * const *iter; |
| 305 | struct tracepoint_entry *mark_entry; | 305 | struct tracepoint_entry *mark_entry; |
| 306 | 306 | ||
| 307 | if (!begin) | 307 | if (!begin) |
| @@ -309,12 +309,12 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | |||
| 309 | 309 | ||
| 310 | mutex_lock(&tracepoints_mutex); | 310 | mutex_lock(&tracepoints_mutex); |
| 311 | for (iter = begin; iter < end; iter++) { | 311 | for (iter = begin; iter < end; iter++) { |
| 312 | mark_entry = get_tracepoint(iter->name); | 312 | mark_entry = get_tracepoint((*iter)->name); |
| 313 | if (mark_entry) { | 313 | if (mark_entry) { |
| 314 | set_tracepoint(&mark_entry, iter, | 314 | set_tracepoint(&mark_entry, *iter, |
| 315 | !!mark_entry->refcount); | 315 | !!mark_entry->refcount); |
| 316 | } else { | 316 | } else { |
| 317 | disable_tracepoint(iter); | 317 | disable_tracepoint(*iter); |
| 318 | } | 318 | } |
| 319 | } | 319 | } |
| 320 | mutex_unlock(&tracepoints_mutex); | 320 | mutex_unlock(&tracepoints_mutex); |
| @@ -326,8 +326,8 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | |||
| 326 | static void tracepoint_update_probes(void) | 326 | static void tracepoint_update_probes(void) |
| 327 | { | 327 | { |
| 328 | /* Core kernel tracepoints */ | 328 | /* Core kernel tracepoints */ |
| 329 | tracepoint_update_probe_range(__start___tracepoints, | 329 | tracepoint_update_probe_range(__start___tracepoints_ptrs, |
| 330 | __stop___tracepoints); | 330 | __stop___tracepoints_ptrs); |
| 331 | /* tracepoints in modules. */ | 331 | /* tracepoints in modules. */ |
| 332 | module_update_tracepoints(); | 332 | module_update_tracepoints(); |
| 333 | } | 333 | } |
| @@ -514,8 +514,8 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_update_all); | |||
| 514 | * Will return the first tracepoint in the range if the input tracepoint is | 514 | * Will return the first tracepoint in the range if the input tracepoint is |
| 515 | * NULL. | 515 | * NULL. |
| 516 | */ | 516 | */ |
| 517 | int tracepoint_get_iter_range(struct tracepoint **tracepoint, | 517 | int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, |
| 518 | struct tracepoint *begin, struct tracepoint *end) | 518 | struct tracepoint * const *begin, struct tracepoint * const *end) |
| 519 | { | 519 | { |
| 520 | if (!*tracepoint && begin != end) { | 520 | if (!*tracepoint && begin != end) { |
| 521 | *tracepoint = begin; | 521 | *tracepoint = begin; |
| @@ -534,7 +534,8 @@ static void tracepoint_get_iter(struct tracepoint_iter *iter) | |||
| 534 | /* Core kernel tracepoints */ | 534 | /* Core kernel tracepoints */ |
| 535 | if (!iter->module) { | 535 | if (!iter->module) { |
| 536 | found = tracepoint_get_iter_range(&iter->tracepoint, | 536 | found = tracepoint_get_iter_range(&iter->tracepoint, |
| 537 | __start___tracepoints, __stop___tracepoints); | 537 | __start___tracepoints_ptrs, |
| 538 | __stop___tracepoints_ptrs); | ||
| 538 | if (found) | 539 | if (found) |
| 539 | goto end; | 540 | goto end; |
| 540 | } | 541 | } |
| @@ -585,8 +586,8 @@ int tracepoint_module_notify(struct notifier_block *self, | |||
| 585 | switch (val) { | 586 | switch (val) { |
| 586 | case MODULE_STATE_COMING: | 587 | case MODULE_STATE_COMING: |
| 587 | case MODULE_STATE_GOING: | 588 | case MODULE_STATE_GOING: |
| 588 | tracepoint_update_probe_range(mod->tracepoints, | 589 | tracepoint_update_probe_range(mod->tracepoints_ptrs, |
| 589 | mod->tracepoints + mod->num_tracepoints); | 590 | mod->tracepoints_ptrs + mod->num_tracepoints); |
| 590 | break; | 591 | break; |
| 591 | } | 592 | } |
| 592 | return 0; | 593 | return 0; |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index f37f974aa81..18bb15776c5 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
| @@ -363,8 +363,14 @@ static int watchdog_nmi_enable(int cpu) | |||
| 363 | goto out_save; | 363 | goto out_save; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n", | 366 | |
| 367 | cpu, PTR_ERR(event)); | 367 | /* vary the KERN level based on the returned errno */ |
| 368 | if (PTR_ERR(event) == -EOPNOTSUPP) | ||
| 369 | printk(KERN_INFO "NMI watchdog disabled (cpu%i): not supported (no LAPIC?)\n", cpu); | ||
| 370 | else if (PTR_ERR(event) == -ENOENT) | ||
| 371 | printk(KERN_WARNING "NMI watchdog disabled (cpu%i): hardware events not enabled\n", cpu); | ||
| 372 | else | ||
| 373 | printk(KERN_ERR "NMI watchdog disabled (cpu%i): unable to create perf event: %ld\n", cpu, PTR_ERR(event)); | ||
| 368 | return PTR_ERR(event); | 374 | return PTR_ERR(event); |
| 369 | 375 | ||
| 370 | /* success path */ | 376 | /* success path */ |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 11869faa681..ee6578b578a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -79,7 +79,9 @@ enum { | |||
| 79 | MAX_IDLE_WORKERS_RATIO = 4, /* 1/4 of busy can be idle */ | 79 | MAX_IDLE_WORKERS_RATIO = 4, /* 1/4 of busy can be idle */ |
| 80 | IDLE_WORKER_TIMEOUT = 300 * HZ, /* keep idle ones for 5 mins */ | 80 | IDLE_WORKER_TIMEOUT = 300 * HZ, /* keep idle ones for 5 mins */ |
| 81 | 81 | ||
| 82 | MAYDAY_INITIAL_TIMEOUT = HZ / 100, /* call for help after 10ms */ | 82 | MAYDAY_INITIAL_TIMEOUT = HZ / 100 >= 2 ? HZ / 100 : 2, |
| 83 | /* call for help after 10ms | ||
| 84 | (min two ticks) */ | ||
| 83 | MAYDAY_INTERVAL = HZ / 10, /* and then every 100ms */ | 85 | MAYDAY_INTERVAL = HZ / 10, /* and then every 100ms */ |
| 84 | CREATE_COOLDOWN = HZ, /* time to breath after fail */ | 86 | CREATE_COOLDOWN = HZ, /* time to breath after fail */ |
| 85 | TRUSTEE_COOLDOWN = HZ / 10, /* for trustee draining */ | 87 | TRUSTEE_COOLDOWN = HZ / 10, /* for trustee draining */ |
| @@ -2047,6 +2049,15 @@ repeat: | |||
| 2047 | move_linked_works(work, scheduled, &n); | 2049 | move_linked_works(work, scheduled, &n); |
| 2048 | 2050 | ||
| 2049 | process_scheduled_works(rescuer); | 2051 | process_scheduled_works(rescuer); |
| 2052 | |||
| 2053 | /* | ||
| 2054 | * Leave this gcwq. If keep_working() is %true, notify a | ||
| 2055 | * regular worker; otherwise, we end up with 0 concurrency | ||
| 2056 | * and stalling the execution. | ||
| 2057 | */ | ||
| 2058 | if (keep_working(gcwq)) | ||
| 2059 | wake_up_worker(gcwq); | ||
| 2060 | |||
| 2050 | spin_unlock_irq(&gcwq->lock); | 2061 | spin_unlock_irq(&gcwq->lock); |
| 2051 | } | 2062 | } |
| 2052 | 2063 | ||
| @@ -2956,7 +2967,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, | |||
| 2956 | */ | 2967 | */ |
| 2957 | spin_lock(&workqueue_lock); | 2968 | spin_lock(&workqueue_lock); |
| 2958 | 2969 | ||
| 2959 | if (workqueue_freezing && wq->flags & WQ_FREEZEABLE) | 2970 | if (workqueue_freezing && wq->flags & WQ_FREEZABLE) |
| 2960 | for_each_cwq_cpu(cpu, wq) | 2971 | for_each_cwq_cpu(cpu, wq) |
| 2961 | get_cwq(cpu, wq)->max_active = 0; | 2972 | get_cwq(cpu, wq)->max_active = 0; |
| 2962 | 2973 | ||
| @@ -3068,7 +3079,7 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) | |||
| 3068 | 3079 | ||
| 3069 | spin_lock_irq(&gcwq->lock); | 3080 | spin_lock_irq(&gcwq->lock); |
| 3070 | 3081 | ||
| 3071 | if (!(wq->flags & WQ_FREEZEABLE) || | 3082 | if (!(wq->flags & WQ_FREEZABLE) || |
| 3072 | !(gcwq->flags & GCWQ_FREEZING)) | 3083 | !(gcwq->flags & GCWQ_FREEZING)) |
| 3073 | get_cwq(gcwq->cpu, wq)->max_active = max_active; | 3084 | get_cwq(gcwq->cpu, wq)->max_active = max_active; |
| 3074 | 3085 | ||
| @@ -3318,7 +3329,7 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3318 | * want to get it over with ASAP - spam rescuers, wake up as | 3329 | * want to get it over with ASAP - spam rescuers, wake up as |
| 3319 | * many idlers as necessary and create new ones till the | 3330 | * many idlers as necessary and create new ones till the |
| 3320 | * worklist is empty. Note that if the gcwq is frozen, there | 3331 | * worklist is empty. Note that if the gcwq is frozen, there |
| 3321 | * may be frozen works in freezeable cwqs. Don't declare | 3332 | * may be frozen works in freezable cwqs. Don't declare |
| 3322 | * completion while frozen. | 3333 | * completion while frozen. |
| 3323 | */ | 3334 | */ |
| 3324 | while (gcwq->nr_workers != gcwq->nr_idle || | 3335 | while (gcwq->nr_workers != gcwq->nr_idle || |
| @@ -3576,9 +3587,9 @@ EXPORT_SYMBOL_GPL(work_on_cpu); | |||
| 3576 | /** | 3587 | /** |
| 3577 | * freeze_workqueues_begin - begin freezing workqueues | 3588 | * freeze_workqueues_begin - begin freezing workqueues |
| 3578 | * | 3589 | * |
| 3579 | * Start freezing workqueues. After this function returns, all | 3590 | * Start freezing workqueues. After this function returns, all freezable |
| 3580 | * freezeable workqueues will queue new works to their frozen_works | 3591 | * workqueues will queue new works to their frozen_works list instead of |
| 3581 | * list instead of gcwq->worklist. | 3592 | * gcwq->worklist. |
| 3582 | * | 3593 | * |
| 3583 | * CONTEXT: | 3594 | * CONTEXT: |
| 3584 | * Grabs and releases workqueue_lock and gcwq->lock's. | 3595 | * Grabs and releases workqueue_lock and gcwq->lock's. |
| @@ -3604,7 +3615,7 @@ void freeze_workqueues_begin(void) | |||
| 3604 | list_for_each_entry(wq, &workqueues, list) { | 3615 | list_for_each_entry(wq, &workqueues, list) { |
| 3605 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | 3616 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); |
| 3606 | 3617 | ||
| 3607 | if (cwq && wq->flags & WQ_FREEZEABLE) | 3618 | if (cwq && wq->flags & WQ_FREEZABLE) |
| 3608 | cwq->max_active = 0; | 3619 | cwq->max_active = 0; |
| 3609 | } | 3620 | } |
| 3610 | 3621 | ||
| @@ -3615,7 +3626,7 @@ void freeze_workqueues_begin(void) | |||
| 3615 | } | 3626 | } |
| 3616 | 3627 | ||
| 3617 | /** | 3628 | /** |
| 3618 | * freeze_workqueues_busy - are freezeable workqueues still busy? | 3629 | * freeze_workqueues_busy - are freezable workqueues still busy? |
| 3619 | * | 3630 | * |
| 3620 | * Check whether freezing is complete. This function must be called | 3631 | * Check whether freezing is complete. This function must be called |
| 3621 | * between freeze_workqueues_begin() and thaw_workqueues(). | 3632 | * between freeze_workqueues_begin() and thaw_workqueues(). |
| @@ -3624,8 +3635,8 @@ void freeze_workqueues_begin(void) | |||
| 3624 | * Grabs and releases workqueue_lock. | 3635 | * Grabs and releases workqueue_lock. |
| 3625 | * | 3636 | * |
| 3626 | * RETURNS: | 3637 | * RETURNS: |
| 3627 | * %true if some freezeable workqueues are still busy. %false if | 3638 | * %true if some freezable workqueues are still busy. %false if freezing |
| 3628 | * freezing is complete. | 3639 | * is complete. |
| 3629 | */ | 3640 | */ |
| 3630 | bool freeze_workqueues_busy(void) | 3641 | bool freeze_workqueues_busy(void) |
| 3631 | { | 3642 | { |
| @@ -3645,7 +3656,7 @@ bool freeze_workqueues_busy(void) | |||
| 3645 | list_for_each_entry(wq, &workqueues, list) { | 3656 | list_for_each_entry(wq, &workqueues, list) { |
| 3646 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | 3657 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); |
| 3647 | 3658 | ||
| 3648 | if (!cwq || !(wq->flags & WQ_FREEZEABLE)) | 3659 | if (!cwq || !(wq->flags & WQ_FREEZABLE)) |
| 3649 | continue; | 3660 | continue; |
| 3650 | 3661 | ||
| 3651 | BUG_ON(cwq->nr_active < 0); | 3662 | BUG_ON(cwq->nr_active < 0); |
| @@ -3690,7 +3701,7 @@ void thaw_workqueues(void) | |||
| 3690 | list_for_each_entry(wq, &workqueues, list) { | 3701 | list_for_each_entry(wq, &workqueues, list) { |
| 3691 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | 3702 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); |
| 3692 | 3703 | ||
| 3693 | if (!cwq || !(wq->flags & WQ_FREEZEABLE)) | 3704 | if (!cwq || !(wq->flags & WQ_FREEZABLE)) |
| 3694 | continue; | 3705 | continue; |
| 3695 | 3706 | ||
| 3696 | /* restore max_active and repopulate worklist */ | 3707 | /* restore max_active and repopulate worklist */ |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 3967c2356e3..2b97418c67e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -805,7 +805,7 @@ config ARCH_WANT_FRAME_POINTERS | |||
| 805 | config FRAME_POINTER | 805 | config FRAME_POINTER |
| 806 | bool "Compile the kernel with frame pointers" | 806 | bool "Compile the kernel with frame pointers" |
| 807 | depends on DEBUG_KERNEL && \ | 807 | depends on DEBUG_KERNEL && \ |
| 808 | (CRIS || M68K || M68KNOMMU || FRV || UML || \ | 808 | (CRIS || M68K || FRV || UML || \ |
| 809 | AVR32 || SUPERH || BLACKFIN || MN10300) || \ | 809 | AVR32 || SUPERH || BLACKFIN || MN10300) || \ |
| 810 | ARCH_WANT_FRAME_POINTERS | 810 | ARCH_WANT_FRAME_POINTERS |
| 811 | default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS | 811 | default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS |
diff --git a/lib/list_debug.c b/lib/list_debug.c index 344c710d16c..b8029a5583f 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c | |||
| @@ -35,6 +35,31 @@ void __list_add(struct list_head *new, | |||
| 35 | } | 35 | } |
| 36 | EXPORT_SYMBOL(__list_add); | 36 | EXPORT_SYMBOL(__list_add); |
| 37 | 37 | ||
| 38 | void __list_del_entry(struct list_head *entry) | ||
| 39 | { | ||
| 40 | struct list_head *prev, *next; | ||
| 41 | |||
| 42 | prev = entry->prev; | ||
| 43 | next = entry->next; | ||
| 44 | |||
| 45 | if (WARN(next == LIST_POISON1, | ||
| 46 | "list_del corruption, %p->next is LIST_POISON1 (%p)\n", | ||
| 47 | entry, LIST_POISON1) || | ||
| 48 | WARN(prev == LIST_POISON2, | ||
| 49 | "list_del corruption, %p->prev is LIST_POISON2 (%p)\n", | ||
| 50 | entry, LIST_POISON2) || | ||
| 51 | WARN(prev->next != entry, | ||
| 52 | "list_del corruption. prev->next should be %p, " | ||
| 53 | "but was %p\n", entry, prev->next) || | ||
| 54 | WARN(next->prev != entry, | ||
| 55 | "list_del corruption. next->prev should be %p, " | ||
| 56 | "but was %p\n", entry, next->prev)) | ||
| 57 | return; | ||
| 58 | |||
| 59 | __list_del(prev, next); | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL(__list_del_entry); | ||
| 62 | |||
| 38 | /** | 63 | /** |
| 39 | * list_del - deletes entry from list. | 64 | * list_del - deletes entry from list. |
| 40 | * @entry: the element to delete from the list. | 65 | * @entry: the element to delete from the list. |
| @@ -43,19 +68,7 @@ EXPORT_SYMBOL(__list_add); | |||
| 43 | */ | 68 | */ |
| 44 | void list_del(struct list_head *entry) | 69 | void list_del(struct list_head *entry) |
| 45 | { | 70 | { |
| 46 | WARN(entry->next == LIST_POISON1, | 71 | __list_del_entry(entry); |
| 47 | "list_del corruption, next is LIST_POISON1 (%p)\n", | ||
| 48 | LIST_POISON1); | ||
| 49 | WARN(entry->next != LIST_POISON1 && entry->prev == LIST_POISON2, | ||
| 50 | "list_del corruption, prev is LIST_POISON2 (%p)\n", | ||
| 51 | LIST_POISON2); | ||
| 52 | WARN(entry->prev->next != entry, | ||
| 53 | "list_del corruption. prev->next should be %p, " | ||
| 54 | "but was %p\n", entry, entry->prev->next); | ||
| 55 | WARN(entry->next->prev != entry, | ||
| 56 | "list_del corruption. next->prev should be %p, " | ||
| 57 | "but was %p\n", entry, entry->next->prev); | ||
| 58 | __list_del(entry->prev, entry->next); | ||
| 59 | entry->next = LIST_POISON1; | 72 | entry->next = LIST_POISON1; |
| 60 | entry->prev = LIST_POISON2; | 73 | entry->prev = LIST_POISON2; |
| 61 | } | 74 | } |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index b6c1ce3c53b..3e29781ee76 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
| @@ -1811,6 +1811,8 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
| 1811 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ | 1811 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ |
| 1812 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) | 1812 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) |
| 1813 | goto out; | 1813 | goto out; |
| 1814 | if (is_vma_temporary_stack(vma)) | ||
| 1815 | goto out; | ||
| 1814 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); | 1816 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); |
| 1815 | 1817 | ||
| 1816 | pgd = pgd_offset(mm, address); | 1818 | pgd = pgd_offset(mm, address); |
| @@ -1852,7 +1854,6 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
| 1852 | set_pmd_at(mm, address, pmd, _pmd); | 1854 | set_pmd_at(mm, address, pmd, _pmd); |
| 1853 | spin_unlock(&mm->page_table_lock); | 1855 | spin_unlock(&mm->page_table_lock); |
| 1854 | anon_vma_unlock(vma->anon_vma); | 1856 | anon_vma_unlock(vma->anon_vma); |
| 1855 | mem_cgroup_uncharge_page(new_page); | ||
| 1856 | goto out; | 1857 | goto out; |
| 1857 | } | 1858 | } |
| 1858 | 1859 | ||
| @@ -1898,6 +1899,7 @@ out_up_write: | |||
| 1898 | return; | 1899 | return; |
| 1899 | 1900 | ||
| 1900 | out: | 1901 | out: |
| 1902 | mem_cgroup_uncharge_page(new_page); | ||
| 1901 | #ifdef CONFIG_NUMA | 1903 | #ifdef CONFIG_NUMA |
| 1902 | put_page(new_page); | 1904 | put_page(new_page); |
| 1903 | #endif | 1905 | #endif |
| @@ -2032,32 +2034,27 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, | |||
| 2032 | if ((!(vma->vm_flags & VM_HUGEPAGE) && | 2034 | if ((!(vma->vm_flags & VM_HUGEPAGE) && |
| 2033 | !khugepaged_always()) || | 2035 | !khugepaged_always()) || |
| 2034 | (vma->vm_flags & VM_NOHUGEPAGE)) { | 2036 | (vma->vm_flags & VM_NOHUGEPAGE)) { |
| 2037 | skip: | ||
| 2035 | progress++; | 2038 | progress++; |
| 2036 | continue; | 2039 | continue; |
| 2037 | } | 2040 | } |
| 2038 | |||
| 2039 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ | 2041 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ |
| 2040 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) { | 2042 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) |
| 2041 | khugepaged_scan.address = vma->vm_end; | 2043 | goto skip; |
| 2042 | progress++; | 2044 | if (is_vma_temporary_stack(vma)) |
| 2043 | continue; | 2045 | goto skip; |
| 2044 | } | 2046 | |
| 2045 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); | 2047 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); |
| 2046 | 2048 | ||
| 2047 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; | 2049 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
| 2048 | hend = vma->vm_end & HPAGE_PMD_MASK; | 2050 | hend = vma->vm_end & HPAGE_PMD_MASK; |
| 2049 | if (hstart >= hend) { | 2051 | if (hstart >= hend) |
| 2050 | progress++; | 2052 | goto skip; |
| 2051 | continue; | 2053 | if (khugepaged_scan.address > hend) |
| 2052 | } | 2054 | goto skip; |
| 2053 | if (khugepaged_scan.address < hstart) | 2055 | if (khugepaged_scan.address < hstart) |
| 2054 | khugepaged_scan.address = hstart; | 2056 | khugepaged_scan.address = hstart; |
| 2055 | if (khugepaged_scan.address > hend) { | 2057 | VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); |
| 2056 | khugepaged_scan.address = hend + HPAGE_PMD_SIZE; | ||
| 2057 | progress++; | ||
| 2058 | continue; | ||
| 2059 | } | ||
| 2060 | BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); | ||
| 2061 | 2058 | ||
| 2062 | while (khugepaged_scan.address < hend) { | 2059 | while (khugepaged_scan.address < hend) { |
| 2063 | int ret; | 2060 | int ret; |
| @@ -2086,7 +2083,7 @@ breakouterloop: | |||
| 2086 | breakouterloop_mmap_sem: | 2083 | breakouterloop_mmap_sem: |
| 2087 | 2084 | ||
| 2088 | spin_lock(&khugepaged_mm_lock); | 2085 | spin_lock(&khugepaged_mm_lock); |
| 2089 | BUG_ON(khugepaged_scan.mm_slot != mm_slot); | 2086 | VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot); |
| 2090 | /* | 2087 | /* |
| 2091 | * Release the current mm_slot if this mm is about to die, or | 2088 | * Release the current mm_slot if this mm is about to die, or |
| 2092 | * if we scanned all vmas of this mm. | 2089 | * if we scanned all vmas of this mm. |
| @@ -2241,9 +2238,9 @@ static int khugepaged(void *none) | |||
| 2241 | 2238 | ||
| 2242 | for (;;) { | 2239 | for (;;) { |
| 2243 | mutex_unlock(&khugepaged_mutex); | 2240 | mutex_unlock(&khugepaged_mutex); |
| 2244 | BUG_ON(khugepaged_thread != current); | 2241 | VM_BUG_ON(khugepaged_thread != current); |
| 2245 | khugepaged_loop(); | 2242 | khugepaged_loop(); |
| 2246 | BUG_ON(khugepaged_thread != current); | 2243 | VM_BUG_ON(khugepaged_thread != current); |
| 2247 | 2244 | ||
| 2248 | mutex_lock(&khugepaged_mutex); | 2245 | mutex_lock(&khugepaged_mutex); |
| 2249 | if (!khugepaged_enabled()) | 2246 | if (!khugepaged_enabled()) |
diff --git a/mm/memblock.c b/mm/memblock.c index bdba245d8af..4618fda975a 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
| @@ -137,8 +137,6 @@ static phys_addr_t __init_memblock memblock_find_base(phys_addr_t size, | |||
| 137 | 137 | ||
| 138 | BUG_ON(0 == size); | 138 | BUG_ON(0 == size); |
| 139 | 139 | ||
| 140 | size = memblock_align_up(size, align); | ||
| 141 | |||
| 142 | /* Pump up max_addr */ | 140 | /* Pump up max_addr */ |
| 143 | if (end == MEMBLOCK_ALLOC_ACCESSIBLE) | 141 | if (end == MEMBLOCK_ALLOC_ACCESSIBLE) |
| 144 | end = memblock.current_limit; | 142 | end = memblock.current_limit; |
diff --git a/mm/memory.c b/mm/memory.c index 31250faff39..8e8c1832486 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -2219,7 +2219,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2219 | &ptl); | 2219 | &ptl); |
| 2220 | if (!pte_same(*page_table, orig_pte)) { | 2220 | if (!pte_same(*page_table, orig_pte)) { |
| 2221 | unlock_page(old_page); | 2221 | unlock_page(old_page); |
| 2222 | page_cache_release(old_page); | ||
| 2223 | goto unlock; | 2222 | goto unlock; |
| 2224 | } | 2223 | } |
| 2225 | page_cache_release(old_page); | 2224 | page_cache_release(old_page); |
| @@ -2289,7 +2288,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2289 | &ptl); | 2288 | &ptl); |
| 2290 | if (!pte_same(*page_table, orig_pte)) { | 2289 | if (!pte_same(*page_table, orig_pte)) { |
| 2291 | unlock_page(old_page); | 2290 | unlock_page(old_page); |
| 2292 | page_cache_release(old_page); | ||
| 2293 | goto unlock; | 2291 | goto unlock; |
| 2294 | } | 2292 | } |
| 2295 | 2293 | ||
| @@ -2367,16 +2365,6 @@ gotten: | |||
| 2367 | } | 2365 | } |
| 2368 | __SetPageUptodate(new_page); | 2366 | __SetPageUptodate(new_page); |
| 2369 | 2367 | ||
| 2370 | /* | ||
| 2371 | * Don't let another task, with possibly unlocked vma, | ||
| 2372 | * keep the mlocked page. | ||
| 2373 | */ | ||
| 2374 | if ((vma->vm_flags & VM_LOCKED) && old_page) { | ||
| 2375 | lock_page(old_page); /* for LRU manipulation */ | ||
| 2376 | clear_page_mlock(old_page); | ||
| 2377 | unlock_page(old_page); | ||
| 2378 | } | ||
| 2379 | |||
| 2380 | if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL)) | 2368 | if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL)) |
| 2381 | goto oom_free_new; | 2369 | goto oom_free_new; |
| 2382 | 2370 | ||
| @@ -2444,10 +2432,20 @@ gotten: | |||
| 2444 | 2432 | ||
| 2445 | if (new_page) | 2433 | if (new_page) |
| 2446 | page_cache_release(new_page); | 2434 | page_cache_release(new_page); |
| 2447 | if (old_page) | ||
| 2448 | page_cache_release(old_page); | ||
| 2449 | unlock: | 2435 | unlock: |
| 2450 | pte_unmap_unlock(page_table, ptl); | 2436 | pte_unmap_unlock(page_table, ptl); |
| 2437 | if (old_page) { | ||
| 2438 | /* | ||
| 2439 | * Don't let another task, with possibly unlocked vma, | ||
| 2440 | * keep the mlocked page. | ||
| 2441 | */ | ||
| 2442 | if ((ret & VM_FAULT_WRITE) && (vma->vm_flags & VM_LOCKED)) { | ||
| 2443 | lock_page(old_page); /* LRU manipulation */ | ||
| 2444 | munlock_vma_page(old_page); | ||
| 2445 | unlock_page(old_page); | ||
| 2446 | } | ||
| 2447 | page_cache_release(old_page); | ||
| 2448 | } | ||
| 2451 | return ret; | 2449 | return ret; |
| 2452 | oom_free_new: | 2450 | oom_free_new: |
| 2453 | page_cache_release(new_page); | 2451 | page_cache_release(new_page); |
| @@ -3053,12 +3051,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 3053 | goto out; | 3051 | goto out; |
| 3054 | } | 3052 | } |
| 3055 | charged = 1; | 3053 | charged = 1; |
| 3056 | /* | ||
| 3057 | * Don't let another task, with possibly unlocked vma, | ||
| 3058 | * keep the mlocked page. | ||
| 3059 | */ | ||
| 3060 | if (vma->vm_flags & VM_LOCKED) | ||
| 3061 | clear_page_mlock(vmf.page); | ||
| 3062 | copy_user_highpage(page, vmf.page, address, vma); | 3054 | copy_user_highpage(page, vmf.page, address, vma); |
| 3063 | __SetPageUptodate(page); | 3055 | __SetPageUptodate(page); |
| 3064 | } else { | 3056 | } else { |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 148c6e630df..17497d0cd8b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -1882,12 +1882,12 @@ static void shrink_zone(int priority, struct zone *zone, | |||
| 1882 | unsigned long nr[NR_LRU_LISTS]; | 1882 | unsigned long nr[NR_LRU_LISTS]; |
| 1883 | unsigned long nr_to_scan; | 1883 | unsigned long nr_to_scan; |
| 1884 | enum lru_list l; | 1884 | enum lru_list l; |
| 1885 | unsigned long nr_reclaimed; | 1885 | unsigned long nr_reclaimed, nr_scanned; |
| 1886 | unsigned long nr_to_reclaim = sc->nr_to_reclaim; | 1886 | unsigned long nr_to_reclaim = sc->nr_to_reclaim; |
| 1887 | unsigned long nr_scanned = sc->nr_scanned; | ||
| 1888 | 1887 | ||
| 1889 | restart: | 1888 | restart: |
| 1890 | nr_reclaimed = 0; | 1889 | nr_reclaimed = 0; |
| 1890 | nr_scanned = sc->nr_scanned; | ||
| 1891 | get_scan_count(zone, sc, nr, priority); | 1891 | get_scan_count(zone, sc, nr, priority); |
| 1892 | 1892 | ||
| 1893 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || | 1893 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || |
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index ee41fef04b2..d1a61132254 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
| @@ -50,12 +50,12 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, | |||
| 50 | skb = tfp->skb; | 50 | skb = tfp->skb; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0) | ||
| 54 | goto err; | ||
| 55 | |||
| 53 | skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); | 56 | skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); |
| 54 | if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) { | 57 | if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) |
| 55 | /* free buffered skb, skb will be freed later */ | 58 | goto err; |
| 56 | kfree_skb(tfp->skb); | ||
| 57 | return NULL; | ||
| 58 | } | ||
| 59 | 59 | ||
| 60 | /* move free entry to end */ | 60 | /* move free entry to end */ |
| 61 | tfp->skb = NULL; | 61 | tfp->skb = NULL; |
| @@ -70,6 +70,11 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, | |||
| 70 | unicast_packet->packet_type = BAT_UNICAST; | 70 | unicast_packet->packet_type = BAT_UNICAST; |
| 71 | 71 | ||
| 72 | return skb; | 72 | return skb; |
| 73 | |||
| 74 | err: | ||
| 75 | /* free buffered skb, skb will be freed later */ | ||
| 76 | kfree_skb(tfp->skb); | ||
| 77 | return NULL; | ||
| 73 | } | 78 | } |
| 74 | 79 | ||
| 75 | static void frag_create_entry(struct list_head *head, struct sk_buff *skb) | 80 | static void frag_create_entry(struct list_head *head, struct sk_buff *skb) |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index cd4c4231fa4..de1022cacaf 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
| @@ -64,6 +64,7 @@ static void free_info(struct kref *ref) | |||
| 64 | 64 | ||
| 65 | spin_unlock_bh(&bat_priv->vis_list_lock); | 65 | spin_unlock_bh(&bat_priv->vis_list_lock); |
| 66 | kfree_skb(info->skb_packet); | 66 | kfree_skb(info->skb_packet); |
| 67 | kfree(info); | ||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | /* Compare two vis packets, used by the hashing algorithm */ | 70 | /* Compare two vis packets, used by the hashing algorithm */ |
| @@ -268,10 +269,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) | |||
| 268 | buff_pos += sprintf(buff + buff_pos, "%pM,", | 269 | buff_pos += sprintf(buff + buff_pos, "%pM,", |
| 269 | entry->addr); | 270 | entry->addr); |
| 270 | 271 | ||
| 271 | for (i = 0; i < packet->entries; i++) | 272 | for (j = 0; j < packet->entries; j++) |
| 272 | buff_pos += vis_data_read_entry( | 273 | buff_pos += vis_data_read_entry( |
| 273 | buff + buff_pos, | 274 | buff + buff_pos, |
| 274 | &entries[i], | 275 | &entries[j], |
| 275 | entry->addr, | 276 | entry->addr, |
| 276 | entry->primary); | 277 | entry->primary); |
| 277 | 278 | ||
| @@ -444,7 +445,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, | |||
| 444 | info); | 445 | info); |
| 445 | if (hash_added < 0) { | 446 | if (hash_added < 0) { |
| 446 | /* did not work (for some reason) */ | 447 | /* did not work (for some reason) */ |
| 447 | kref_put(&old_info->refcount, free_info); | 448 | kref_put(&info->refcount, free_info); |
| 448 | info = NULL; | 449 | info = NULL; |
| 449 | } | 450 | } |
| 450 | 451 | ||
| @@ -815,7 +816,7 @@ static void send_vis_packets(struct work_struct *work) | |||
| 815 | container_of(work, struct delayed_work, work); | 816 | container_of(work, struct delayed_work, work); |
| 816 | struct bat_priv *bat_priv = | 817 | struct bat_priv *bat_priv = |
| 817 | container_of(delayed_work, struct bat_priv, vis_work); | 818 | container_of(delayed_work, struct bat_priv, vis_work); |
| 818 | struct vis_info *info, *temp; | 819 | struct vis_info *info; |
| 819 | 820 | ||
| 820 | spin_lock_bh(&bat_priv->vis_hash_lock); | 821 | spin_lock_bh(&bat_priv->vis_hash_lock); |
| 821 | purge_vis_packets(bat_priv); | 822 | purge_vis_packets(bat_priv); |
| @@ -825,8 +826,9 @@ static void send_vis_packets(struct work_struct *work) | |||
| 825 | send_list_add(bat_priv, bat_priv->my_vis_info); | 826 | send_list_add(bat_priv, bat_priv->my_vis_info); |
| 826 | } | 827 | } |
| 827 | 828 | ||
| 828 | list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, | 829 | while (!list_empty(&bat_priv->vis_send_list)) { |
| 829 | send_list) { | 830 | info = list_first_entry(&bat_priv->vis_send_list, |
| 831 | typeof(*info), send_list); | ||
| 830 | 832 | ||
| 831 | kref_get(&info->refcount); | 833 | kref_get(&info->refcount); |
| 832 | spin_unlock_bh(&bat_priv->vis_hash_lock); | 834 | spin_unlock_bh(&bat_priv->vis_hash_lock); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 7550abb0c96..675614e38e1 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -859,6 +859,7 @@ static void __l2cap_sock_close(struct sock *sk, int reason) | |||
| 859 | result = L2CAP_CR_SEC_BLOCK; | 859 | result = L2CAP_CR_SEC_BLOCK; |
| 860 | else | 860 | else |
| 861 | result = L2CAP_CR_BAD_PSM; | 861 | result = L2CAP_CR_BAD_PSM; |
| 862 | sk->sk_state = BT_DISCONN; | ||
| 862 | 863 | ||
| 863 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 864 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
| 864 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 865 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 2872393b293..88485cc74dc 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -328,12 +328,12 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, | |||
| 328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); | 328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); |
| 329 | if (fdb) { | 329 | if (fdb) { |
| 330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); | 330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); |
| 331 | hlist_add_head_rcu(&fdb->hlist, head); | ||
| 332 | |||
| 333 | fdb->dst = source; | 331 | fdb->dst = source; |
| 334 | fdb->is_local = is_local; | 332 | fdb->is_local = is_local; |
| 335 | fdb->is_static = is_local; | 333 | fdb->is_static = is_local; |
| 336 | fdb->ageing_timer = jiffies; | 334 | fdb->ageing_timer = jiffies; |
| 335 | |||
| 336 | hlist_add_head_rcu(&fdb->hlist, head); | ||
| 337 | } | 337 | } |
| 338 | return fdb; | 338 | return fdb; |
| 339 | } | 339 | } |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 6f6d8e1b776..88e4aa9cb1f 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -80,7 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 80 | if (is_multicast_ether_addr(dest)) { | 80 | if (is_multicast_ether_addr(dest)) { |
| 81 | mdst = br_mdb_get(br, skb); | 81 | mdst = br_mdb_get(br, skb); |
| 82 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { | 82 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { |
| 83 | if ((mdst && !hlist_unhashed(&mdst->mglist)) || | 83 | if ((mdst && mdst->mglist) || |
| 84 | br_multicast_is_router(br)) | 84 | br_multicast_is_router(br)) |
| 85 | skb2 = skb; | 85 | skb2 = skb; |
| 86 | br_multicast_forward(mdst, skb, skb2); | 86 | br_multicast_forward(mdst, skb, skb2); |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index f701a21acb3..09d5c098792 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -232,8 +232,7 @@ static void br_multicast_group_expired(unsigned long data) | |||
| 232 | if (!netif_running(br->dev) || timer_pending(&mp->timer)) | 232 | if (!netif_running(br->dev) || timer_pending(&mp->timer)) |
| 233 | goto out; | 233 | goto out; |
| 234 | 234 | ||
| 235 | if (!hlist_unhashed(&mp->mglist)) | 235 | mp->mglist = false; |
| 236 | hlist_del_init(&mp->mglist); | ||
| 237 | 236 | ||
| 238 | if (mp->ports) | 237 | if (mp->ports) |
| 239 | goto out; | 238 | goto out; |
| @@ -276,7 +275,7 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
| 276 | del_timer(&p->query_timer); | 275 | del_timer(&p->query_timer); |
| 277 | call_rcu_bh(&p->rcu, br_multicast_free_pg); | 276 | call_rcu_bh(&p->rcu, br_multicast_free_pg); |
| 278 | 277 | ||
| 279 | if (!mp->ports && hlist_unhashed(&mp->mglist) && | 278 | if (!mp->ports && !mp->mglist && |
| 280 | netif_running(br->dev)) | 279 | netif_running(br->dev)) |
| 281 | mod_timer(&mp->timer, jiffies); | 280 | mod_timer(&mp->timer, jiffies); |
| 282 | 281 | ||
| @@ -528,7 +527,7 @@ static void br_multicast_group_query_expired(unsigned long data) | |||
| 528 | struct net_bridge *br = mp->br; | 527 | struct net_bridge *br = mp->br; |
| 529 | 528 | ||
| 530 | spin_lock(&br->multicast_lock); | 529 | spin_lock(&br->multicast_lock); |
| 531 | if (!netif_running(br->dev) || hlist_unhashed(&mp->mglist) || | 530 | if (!netif_running(br->dev) || !mp->mglist || |
| 532 | mp->queries_sent >= br->multicast_last_member_count) | 531 | mp->queries_sent >= br->multicast_last_member_count) |
| 533 | goto out; | 532 | goto out; |
| 534 | 533 | ||
| @@ -719,7 +718,7 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
| 719 | goto err; | 718 | goto err; |
| 720 | 719 | ||
| 721 | if (!port) { | 720 | if (!port) { |
| 722 | hlist_add_head(&mp->mglist, &br->mglist); | 721 | mp->mglist = true; |
| 723 | mod_timer(&mp->timer, now + br->multicast_membership_interval); | 722 | mod_timer(&mp->timer, now + br->multicast_membership_interval); |
| 724 | goto out; | 723 | goto out; |
| 725 | } | 724 | } |
| @@ -1165,7 +1164,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
| 1165 | 1164 | ||
| 1166 | max_delay *= br->multicast_last_member_count; | 1165 | max_delay *= br->multicast_last_member_count; |
| 1167 | 1166 | ||
| 1168 | if (!hlist_unhashed(&mp->mglist) && | 1167 | if (mp->mglist && |
| 1169 | (timer_pending(&mp->timer) ? | 1168 | (timer_pending(&mp->timer) ? |
| 1170 | time_after(mp->timer.expires, now + max_delay) : | 1169 | time_after(mp->timer.expires, now + max_delay) : |
| 1171 | try_to_del_timer_sync(&mp->timer) >= 0)) | 1170 | try_to_del_timer_sync(&mp->timer) >= 0)) |
| @@ -1177,7 +1176,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
| 1177 | if (timer_pending(&p->timer) ? | 1176 | if (timer_pending(&p->timer) ? |
| 1178 | time_after(p->timer.expires, now + max_delay) : | 1177 | time_after(p->timer.expires, now + max_delay) : |
| 1179 | try_to_del_timer_sync(&p->timer) >= 0) | 1178 | try_to_del_timer_sync(&p->timer) >= 0) |
| 1180 | mod_timer(&mp->timer, now + max_delay); | 1179 | mod_timer(&p->timer, now + max_delay); |
| 1181 | } | 1180 | } |
| 1182 | 1181 | ||
| 1183 | out: | 1182 | out: |
| @@ -1236,7 +1235,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1236 | goto out; | 1235 | goto out; |
| 1237 | 1236 | ||
| 1238 | max_delay *= br->multicast_last_member_count; | 1237 | max_delay *= br->multicast_last_member_count; |
| 1239 | if (!hlist_unhashed(&mp->mglist) && | 1238 | if (mp->mglist && |
| 1240 | (timer_pending(&mp->timer) ? | 1239 | (timer_pending(&mp->timer) ? |
| 1241 | time_after(mp->timer.expires, now + max_delay) : | 1240 | time_after(mp->timer.expires, now + max_delay) : |
| 1242 | try_to_del_timer_sync(&mp->timer) >= 0)) | 1241 | try_to_del_timer_sync(&mp->timer) >= 0)) |
| @@ -1248,7 +1247,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
| 1248 | if (timer_pending(&p->timer) ? | 1247 | if (timer_pending(&p->timer) ? |
| 1249 | time_after(p->timer.expires, now + max_delay) : | 1248 | time_after(p->timer.expires, now + max_delay) : |
| 1250 | try_to_del_timer_sync(&p->timer) >= 0) | 1249 | try_to_del_timer_sync(&p->timer) >= 0) |
| 1251 | mod_timer(&mp->timer, now + max_delay); | 1250 | mod_timer(&p->timer, now + max_delay); |
| 1252 | } | 1251 | } |
| 1253 | 1252 | ||
| 1254 | out: | 1253 | out: |
| @@ -1283,7 +1282,7 @@ static void br_multicast_leave_group(struct net_bridge *br, | |||
| 1283 | br->multicast_last_member_interval; | 1282 | br->multicast_last_member_interval; |
| 1284 | 1283 | ||
| 1285 | if (!port) { | 1284 | if (!port) { |
| 1286 | if (!hlist_unhashed(&mp->mglist) && | 1285 | if (mp->mglist && |
| 1287 | (timer_pending(&mp->timer) ? | 1286 | (timer_pending(&mp->timer) ? |
| 1288 | time_after(mp->timer.expires, time) : | 1287 | time_after(mp->timer.expires, time) : |
| 1289 | try_to_del_timer_sync(&mp->timer) >= 0)) { | 1288 | try_to_del_timer_sync(&mp->timer) >= 0)) { |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 84aac7734bf..4e1b620b6be 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -84,13 +84,13 @@ struct net_bridge_port_group { | |||
| 84 | struct net_bridge_mdb_entry | 84 | struct net_bridge_mdb_entry |
| 85 | { | 85 | { |
| 86 | struct hlist_node hlist[2]; | 86 | struct hlist_node hlist[2]; |
| 87 | struct hlist_node mglist; | ||
| 88 | struct net_bridge *br; | 87 | struct net_bridge *br; |
| 89 | struct net_bridge_port_group __rcu *ports; | 88 | struct net_bridge_port_group __rcu *ports; |
| 90 | struct rcu_head rcu; | 89 | struct rcu_head rcu; |
| 91 | struct timer_list timer; | 90 | struct timer_list timer; |
| 92 | struct timer_list query_timer; | 91 | struct timer_list query_timer; |
| 93 | struct br_ip addr; | 92 | struct br_ip addr; |
| 93 | bool mglist; | ||
| 94 | u32 queries_sent; | 94 | u32 queries_sent; |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| @@ -238,7 +238,6 @@ struct net_bridge | |||
| 238 | spinlock_t multicast_lock; | 238 | spinlock_t multicast_lock; |
| 239 | struct net_bridge_mdb_htable __rcu *mdb; | 239 | struct net_bridge_mdb_htable __rcu *mdb; |
| 240 | struct hlist_head router_list; | 240 | struct hlist_head router_list; |
| 241 | struct hlist_head mglist; | ||
| 242 | 241 | ||
| 243 | struct timer_list multicast_router_timer; | 242 | struct timer_list multicast_router_timer; |
| 244 | struct timer_list multicast_querier_timer; | 243 | struct timer_list multicast_querier_timer; |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index fa9dab372b6..6008d6dc18a 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
| @@ -394,9 +394,7 @@ static void ipcaif_net_setup(struct net_device *dev) | |||
| 394 | priv->conn_req.sockaddr.u.dgm.connection_id = -1; | 394 | priv->conn_req.sockaddr.u.dgm.connection_id = -1; |
| 395 | priv->flowenabled = false; | 395 | priv->flowenabled = false; |
| 396 | 396 | ||
| 397 | ASSERT_RTNL(); | ||
| 398 | init_waitqueue_head(&priv->netmgmt_wq); | 397 | init_waitqueue_head(&priv->netmgmt_wq); |
| 399 | list_add(&priv->list_field, &chnl_net_list); | ||
| 400 | } | 398 | } |
| 401 | 399 | ||
| 402 | 400 | ||
| @@ -453,6 +451,8 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, | |||
| 453 | ret = register_netdevice(dev); | 451 | ret = register_netdevice(dev); |
| 454 | if (ret) | 452 | if (ret) |
| 455 | pr_warn("device rtml registration failed\n"); | 453 | pr_warn("device rtml registration failed\n"); |
| 454 | else | ||
| 455 | list_add(&caifdev->list_field, &chnl_net_list); | ||
| 456 | return ret; | 456 | return ret; |
| 457 | } | 457 | } |
| 458 | 458 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 24ea2d71e7e..8ae6631abcc 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1280,10 +1280,13 @@ static int __dev_close_many(struct list_head *head) | |||
| 1280 | 1280 | ||
| 1281 | static int __dev_close(struct net_device *dev) | 1281 | static int __dev_close(struct net_device *dev) |
| 1282 | { | 1282 | { |
| 1283 | int retval; | ||
| 1283 | LIST_HEAD(single); | 1284 | LIST_HEAD(single); |
| 1284 | 1285 | ||
| 1285 | list_add(&dev->unreg_list, &single); | 1286 | list_add(&dev->unreg_list, &single); |
| 1286 | return __dev_close_many(&single); | 1287 | retval = __dev_close_many(&single); |
| 1288 | list_del(&single); | ||
| 1289 | return retval; | ||
| 1287 | } | 1290 | } |
| 1288 | 1291 | ||
| 1289 | int dev_close_many(struct list_head *head) | 1292 | int dev_close_many(struct list_head *head) |
| @@ -1325,7 +1328,7 @@ int dev_close(struct net_device *dev) | |||
| 1325 | 1328 | ||
| 1326 | list_add(&dev->unreg_list, &single); | 1329 | list_add(&dev->unreg_list, &single); |
| 1327 | dev_close_many(&single); | 1330 | dev_close_many(&single); |
| 1328 | 1331 | list_del(&single); | |
| 1329 | return 0; | 1332 | return 0; |
| 1330 | } | 1333 | } |
| 1331 | EXPORT_SYMBOL(dev_close); | 1334 | EXPORT_SYMBOL(dev_close); |
| @@ -2563,7 +2566,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
| 2563 | 2566 | ||
| 2564 | map = rcu_dereference(rxqueue->rps_map); | 2567 | map = rcu_dereference(rxqueue->rps_map); |
| 2565 | if (map) { | 2568 | if (map) { |
| 2566 | if (map->len == 1) { | 2569 | if (map->len == 1 && |
| 2570 | !rcu_dereference_raw(rxqueue->rps_flow_table)) { | ||
| 2567 | tcpu = map->cpus[0]; | 2571 | tcpu = map->cpus[0]; |
| 2568 | if (cpu_online(tcpu)) | 2572 | if (cpu_online(tcpu)) |
| 2569 | cpu = tcpu; | 2573 | cpu = tcpu; |
| @@ -3424,6 +3428,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
| 3424 | __skb_pull(skb, skb_headlen(skb)); | 3428 | __skb_pull(skb, skb_headlen(skb)); |
| 3425 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 3429 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
| 3426 | skb->vlan_tci = 0; | 3430 | skb->vlan_tci = 0; |
| 3431 | skb->dev = napi->dev; | ||
| 3432 | skb->skb_iif = 0; | ||
| 3427 | 3433 | ||
| 3428 | napi->skb = skb; | 3434 | napi->skb = skb; |
| 3429 | } | 3435 | } |
| @@ -5060,6 +5066,7 @@ static void rollback_registered(struct net_device *dev) | |||
| 5060 | 5066 | ||
| 5061 | list_add(&dev->unreg_list, &single); | 5067 | list_add(&dev->unreg_list, &single); |
| 5062 | rollback_registered_many(&single); | 5068 | rollback_registered_many(&single); |
| 5069 | list_del(&single); | ||
| 5063 | } | 5070 | } |
| 5064 | 5071 | ||
| 5065 | unsigned long netdev_fix_features(unsigned long features, const char *name) | 5072 | unsigned long netdev_fix_features(unsigned long features, const char *name) |
| @@ -5657,30 +5664,35 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
| 5657 | 5664 | ||
| 5658 | dev_net_set(dev, &init_net); | 5665 | dev_net_set(dev, &init_net); |
| 5659 | 5666 | ||
| 5667 | dev->gso_max_size = GSO_MAX_SIZE; | ||
| 5668 | |||
| 5669 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
| 5670 | dev->ethtool_ntuple_list.count = 0; | ||
| 5671 | INIT_LIST_HEAD(&dev->napi_list); | ||
| 5672 | INIT_LIST_HEAD(&dev->unreg_list); | ||
| 5673 | INIT_LIST_HEAD(&dev->link_watch_list); | ||
| 5674 | dev->priv_flags = IFF_XMIT_DST_RELEASE; | ||
| 5675 | setup(dev); | ||
| 5676 | |||
| 5660 | dev->num_tx_queues = txqs; | 5677 | dev->num_tx_queues = txqs; |
| 5661 | dev->real_num_tx_queues = txqs; | 5678 | dev->real_num_tx_queues = txqs; |
| 5662 | if (netif_alloc_netdev_queues(dev)) | 5679 | if (netif_alloc_netdev_queues(dev)) |
| 5663 | goto free_pcpu; | 5680 | goto free_all; |
| 5664 | 5681 | ||
| 5665 | #ifdef CONFIG_RPS | 5682 | #ifdef CONFIG_RPS |
| 5666 | dev->num_rx_queues = rxqs; | 5683 | dev->num_rx_queues = rxqs; |
| 5667 | dev->real_num_rx_queues = rxqs; | 5684 | dev->real_num_rx_queues = rxqs; |
| 5668 | if (netif_alloc_rx_queues(dev)) | 5685 | if (netif_alloc_rx_queues(dev)) |
| 5669 | goto free_pcpu; | 5686 | goto free_all; |
| 5670 | #endif | 5687 | #endif |
| 5671 | 5688 | ||
| 5672 | dev->gso_max_size = GSO_MAX_SIZE; | ||
| 5673 | |||
| 5674 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
| 5675 | dev->ethtool_ntuple_list.count = 0; | ||
| 5676 | INIT_LIST_HEAD(&dev->napi_list); | ||
| 5677 | INIT_LIST_HEAD(&dev->unreg_list); | ||
| 5678 | INIT_LIST_HEAD(&dev->link_watch_list); | ||
| 5679 | dev->priv_flags = IFF_XMIT_DST_RELEASE; | ||
| 5680 | setup(dev); | ||
| 5681 | strcpy(dev->name, name); | 5689 | strcpy(dev->name, name); |
| 5682 | return dev; | 5690 | return dev; |
| 5683 | 5691 | ||
| 5692 | free_all: | ||
| 5693 | free_netdev(dev); | ||
| 5694 | return NULL; | ||
| 5695 | |||
| 5684 | free_pcpu: | 5696 | free_pcpu: |
| 5685 | free_percpu(dev->pcpu_refcnt); | 5697 | free_percpu(dev->pcpu_refcnt); |
| 5686 | kfree(dev->_tx); | 5698 | kfree(dev->_tx); |
| @@ -6208,6 +6220,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) | |||
| 6208 | } | 6220 | } |
| 6209 | } | 6221 | } |
| 6210 | unregister_netdevice_many(&dev_kill_list); | 6222 | unregister_netdevice_many(&dev_kill_list); |
| 6223 | list_del(&dev_kill_list); | ||
| 6211 | rtnl_unlock(); | 6224 | rtnl_unlock(); |
| 6212 | } | 6225 | } |
| 6213 | 6226 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 750db57f3bb..2d65c6bb24c 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -1121,8 +1121,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | |||
| 1121 | return -EOPNOTSUPP; | 1121 | return -EOPNOTSUPP; |
| 1122 | 1122 | ||
| 1123 | if (af_ops->validate_link_af) { | 1123 | if (af_ops->validate_link_af) { |
| 1124 | err = af_ops->validate_link_af(dev, | 1124 | err = af_ops->validate_link_af(dev, af); |
| 1125 | tb[IFLA_AF_SPEC]); | ||
| 1126 | if (err < 0) | 1125 | if (err < 0) |
| 1127 | return err; | 1126 | return err; |
| 1128 | } | 1127 | } |
| @@ -1672,6 +1671,9 @@ replay: | |||
| 1672 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); | 1671 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); |
| 1673 | 1672 | ||
| 1674 | dest_net = rtnl_link_get_net(net, tb); | 1673 | dest_net = rtnl_link_get_net(net, tb); |
| 1674 | if (IS_ERR(dest_net)) | ||
| 1675 | return PTR_ERR(dest_net); | ||
| 1676 | |||
| 1675 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); | 1677 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); |
| 1676 | 1678 | ||
| 1677 | if (IS_ERR(dev)) | 1679 | if (IS_ERR(dev)) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7cd1bc86d59..d883dcc78b6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -210,6 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
| 210 | shinfo = skb_shinfo(skb); | 210 | shinfo = skb_shinfo(skb); |
| 211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | 211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); |
| 212 | atomic_set(&shinfo->dataref, 1); | 212 | atomic_set(&shinfo->dataref, 1); |
| 213 | kmemcheck_annotate_variable(shinfo->destructor_arg); | ||
| 213 | 214 | ||
| 214 | if (fclone) { | 215 | if (fclone) { |
| 215 | struct sk_buff *child = skb + 1; | 216 | struct sk_buff *child = skb + 1; |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 6b03f561cae..d5074a56728 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
| @@ -626,6 +626,9 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | |||
| 626 | dcb->cmd = DCB_CMD_GAPP; | 626 | dcb->cmd = DCB_CMD_GAPP; |
| 627 | 627 | ||
| 628 | app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); | 628 | app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); |
| 629 | if (!app_nest) | ||
| 630 | goto out_cancel; | ||
| 631 | |||
| 629 | ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); | 632 | ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); |
| 630 | if (ret) | 633 | if (ret) |
| 631 | goto out_cancel; | 634 | goto out_cancel; |
| @@ -1613,6 +1616,10 @@ EXPORT_SYMBOL(dcb_getapp); | |||
| 1613 | u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) | 1616 | u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) |
| 1614 | { | 1617 | { |
| 1615 | struct dcb_app_type *itr; | 1618 | struct dcb_app_type *itr; |
| 1619 | struct dcb_app_type event; | ||
| 1620 | |||
| 1621 | memcpy(&event.name, dev->name, sizeof(event.name)); | ||
| 1622 | memcpy(&event.app, new, sizeof(event.app)); | ||
| 1616 | 1623 | ||
| 1617 | spin_lock(&dcb_lock); | 1624 | spin_lock(&dcb_lock); |
| 1618 | /* Search for existing match and replace */ | 1625 | /* Search for existing match and replace */ |
| @@ -1644,7 +1651,7 @@ u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) | |||
| 1644 | } | 1651 | } |
| 1645 | out: | 1652 | out: |
| 1646 | spin_unlock(&dcb_lock); | 1653 | spin_unlock(&dcb_lock); |
| 1647 | call_dcbevent_notifiers(DCB_APP_EVENT, new); | 1654 | call_dcbevent_notifiers(DCB_APP_EVENT, &event); |
| 1648 | return 0; | 1655 | return 0; |
| 1649 | } | 1656 | } |
| 1650 | EXPORT_SYMBOL(dcb_setapp); | 1657 | EXPORT_SYMBOL(dcb_setapp); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 15dcc1a586b..0c282633791 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
| @@ -265,13 +265,13 @@ static void ec_tx_done(struct sk_buff *skb, int result) | |||
| 265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | 265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, |
| 266 | struct msghdr *msg, size_t len) | 266 | struct msghdr *msg, size_t len) |
| 267 | { | 267 | { |
| 268 | struct sock *sk = sock->sk; | ||
| 269 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; | 268 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; |
| 270 | struct net_device *dev; | 269 | struct net_device *dev; |
| 271 | struct ec_addr addr; | 270 | struct ec_addr addr; |
| 272 | int err; | 271 | int err; |
| 273 | unsigned char port, cb; | 272 | unsigned char port, cb; |
| 274 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) | 273 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) |
| 274 | struct sock *sk = sock->sk; | ||
| 275 | struct sk_buff *skb; | 275 | struct sk_buff *skb; |
| 276 | struct ec_cb *eb; | 276 | struct ec_cb *eb; |
| 277 | #endif | 277 | #endif |
| @@ -488,10 +488,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 488 | 488 | ||
| 489 | error_free_buf: | 489 | error_free_buf: |
| 490 | vfree(userbuf); | 490 | vfree(userbuf); |
| 491 | error: | ||
| 491 | #else | 492 | #else |
| 492 | err = -EPROTOTYPE; | 493 | err = -EPROTOTYPE; |
| 493 | #endif | 494 | #endif |
| 494 | error: | ||
| 495 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
| 496 | 496 | ||
| 497 | return err; | 497 | return err; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f2b61107df6..45b89d7bda5 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -880,6 +880,19 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 880 | } | 880 | } |
| 881 | EXPORT_SYMBOL(inet_ioctl); | 881 | EXPORT_SYMBOL(inet_ioctl); |
| 882 | 882 | ||
| 883 | #ifdef CONFIG_COMPAT | ||
| 884 | int inet_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
| 885 | { | ||
| 886 | struct sock *sk = sock->sk; | ||
| 887 | int err = -ENOIOCTLCMD; | ||
| 888 | |||
| 889 | if (sk->sk_prot->compat_ioctl) | ||
| 890 | err = sk->sk_prot->compat_ioctl(sk, cmd, arg); | ||
| 891 | |||
| 892 | return err; | ||
| 893 | } | ||
| 894 | #endif | ||
| 895 | |||
| 883 | const struct proto_ops inet_stream_ops = { | 896 | const struct proto_ops inet_stream_ops = { |
| 884 | .family = PF_INET, | 897 | .family = PF_INET, |
| 885 | .owner = THIS_MODULE, | 898 | .owner = THIS_MODULE, |
| @@ -903,6 +916,7 @@ const struct proto_ops inet_stream_ops = { | |||
| 903 | #ifdef CONFIG_COMPAT | 916 | #ifdef CONFIG_COMPAT |
| 904 | .compat_setsockopt = compat_sock_common_setsockopt, | 917 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 905 | .compat_getsockopt = compat_sock_common_getsockopt, | 918 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 919 | .compat_ioctl = inet_compat_ioctl, | ||
| 906 | #endif | 920 | #endif |
| 907 | }; | 921 | }; |
| 908 | EXPORT_SYMBOL(inet_stream_ops); | 922 | EXPORT_SYMBOL(inet_stream_ops); |
| @@ -929,6 +943,7 @@ const struct proto_ops inet_dgram_ops = { | |||
| 929 | #ifdef CONFIG_COMPAT | 943 | #ifdef CONFIG_COMPAT |
| 930 | .compat_setsockopt = compat_sock_common_setsockopt, | 944 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 931 | .compat_getsockopt = compat_sock_common_getsockopt, | 945 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 946 | .compat_ioctl = inet_compat_ioctl, | ||
| 932 | #endif | 947 | #endif |
| 933 | }; | 948 | }; |
| 934 | EXPORT_SYMBOL(inet_dgram_ops); | 949 | EXPORT_SYMBOL(inet_dgram_ops); |
| @@ -959,6 +974,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
| 959 | #ifdef CONFIG_COMPAT | 974 | #ifdef CONFIG_COMPAT |
| 960 | .compat_setsockopt = compat_sock_common_setsockopt, | 975 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 961 | .compat_getsockopt = compat_sock_common_getsockopt, | 976 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 977 | .compat_ioctl = inet_compat_ioctl, | ||
| 962 | #endif | 978 | #endif |
| 963 | }; | 979 | }; |
| 964 | 980 | ||
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 748cb5b337b..df4616fce92 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -1030,6 +1030,21 @@ static inline bool inetdev_valid_mtu(unsigned mtu) | |||
| 1030 | return mtu >= 68; | 1030 | return mtu >= 68; |
| 1031 | } | 1031 | } |
| 1032 | 1032 | ||
| 1033 | static void inetdev_send_gratuitous_arp(struct net_device *dev, | ||
| 1034 | struct in_device *in_dev) | ||
| 1035 | |||
| 1036 | { | ||
| 1037 | struct in_ifaddr *ifa = in_dev->ifa_list; | ||
| 1038 | |||
| 1039 | if (!ifa) | ||
| 1040 | return; | ||
| 1041 | |||
| 1042 | arp_send(ARPOP_REQUEST, ETH_P_ARP, | ||
| 1043 | ifa->ifa_address, dev, | ||
| 1044 | ifa->ifa_address, NULL, | ||
| 1045 | dev->dev_addr, NULL); | ||
| 1046 | } | ||
| 1047 | |||
| 1033 | /* Called only under RTNL semaphore */ | 1048 | /* Called only under RTNL semaphore */ |
| 1034 | 1049 | ||
| 1035 | static int inetdev_event(struct notifier_block *this, unsigned long event, | 1050 | static int inetdev_event(struct notifier_block *this, unsigned long event, |
| @@ -1082,18 +1097,13 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
| 1082 | } | 1097 | } |
| 1083 | ip_mc_up(in_dev); | 1098 | ip_mc_up(in_dev); |
| 1084 | /* fall through */ | 1099 | /* fall through */ |
| 1085 | case NETDEV_NOTIFY_PEERS: | ||
| 1086 | case NETDEV_CHANGEADDR: | 1100 | case NETDEV_CHANGEADDR: |
| 1101 | if (!IN_DEV_ARP_NOTIFY(in_dev)) | ||
| 1102 | break; | ||
| 1103 | /* fall through */ | ||
| 1104 | case NETDEV_NOTIFY_PEERS: | ||
| 1087 | /* Send gratuitous ARP to notify of link change */ | 1105 | /* Send gratuitous ARP to notify of link change */ |
| 1088 | if (IN_DEV_ARP_NOTIFY(in_dev)) { | 1106 | inetdev_send_gratuitous_arp(dev, in_dev); |
| 1089 | struct in_ifaddr *ifa = in_dev->ifa_list; | ||
| 1090 | |||
| 1091 | if (ifa) | ||
| 1092 | arp_send(ARPOP_REQUEST, ETH_P_ARP, | ||
| 1093 | ifa->ifa_address, dev, | ||
| 1094 | ifa->ifa_address, NULL, | ||
| 1095 | dev->dev_addr, NULL); | ||
| 1096 | } | ||
| 1097 | break; | 1107 | break; |
| 1098 | case NETDEV_DOWN: | 1108 | case NETDEV_DOWN: |
| 1099 | ip_mc_down(in_dev); | 1109 | ip_mc_down(in_dev); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index eb68a0e34e4..6613edfac28 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -775,6 +775,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 775 | .fl4_dst = dst, | 775 | .fl4_dst = dst, |
| 776 | .fl4_src = tiph->saddr, | 776 | .fl4_src = tiph->saddr, |
| 777 | .fl4_tos = RT_TOS(tos), | 777 | .fl4_tos = RT_TOS(tos), |
| 778 | .proto = IPPROTO_GRE, | ||
| 778 | .fl_gre_key = tunnel->parms.o_key | 779 | .fl_gre_key = tunnel->parms.o_key |
| 779 | }; | 780 | }; |
| 780 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | 781 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3f3a9afd73e..8b65a12654e 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
| 61 | #include <linux/if_arp.h> | 61 | #include <linux/if_arp.h> |
| 62 | #include <linux/netfilter_ipv4.h> | 62 | #include <linux/netfilter_ipv4.h> |
| 63 | #include <linux/compat.h> | ||
| 63 | #include <net/ipip.h> | 64 | #include <net/ipip.h> |
| 64 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
| 65 | #include <net/netlink.h> | 66 | #include <net/netlink.h> |
| @@ -1434,6 +1435,81 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
| 1434 | } | 1435 | } |
| 1435 | } | 1436 | } |
| 1436 | 1437 | ||
| 1438 | #ifdef CONFIG_COMPAT | ||
| 1439 | struct compat_sioc_sg_req { | ||
| 1440 | struct in_addr src; | ||
| 1441 | struct in_addr grp; | ||
| 1442 | compat_ulong_t pktcnt; | ||
| 1443 | compat_ulong_t bytecnt; | ||
| 1444 | compat_ulong_t wrong_if; | ||
| 1445 | }; | ||
| 1446 | |||
| 1447 | struct compat_sioc_vif_req { | ||
| 1448 | vifi_t vifi; /* Which iface */ | ||
| 1449 | compat_ulong_t icount; | ||
| 1450 | compat_ulong_t ocount; | ||
| 1451 | compat_ulong_t ibytes; | ||
| 1452 | compat_ulong_t obytes; | ||
| 1453 | }; | ||
| 1454 | |||
| 1455 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
| 1456 | { | ||
| 1457 | struct compat_sioc_sg_req sr; | ||
| 1458 | struct compat_sioc_vif_req vr; | ||
| 1459 | struct vif_device *vif; | ||
| 1460 | struct mfc_cache *c; | ||
| 1461 | struct net *net = sock_net(sk); | ||
| 1462 | struct mr_table *mrt; | ||
| 1463 | |||
| 1464 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
| 1465 | if (mrt == NULL) | ||
| 1466 | return -ENOENT; | ||
| 1467 | |||
| 1468 | switch (cmd) { | ||
| 1469 | case SIOCGETVIFCNT: | ||
| 1470 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
| 1471 | return -EFAULT; | ||
| 1472 | if (vr.vifi >= mrt->maxvif) | ||
| 1473 | return -EINVAL; | ||
| 1474 | read_lock(&mrt_lock); | ||
| 1475 | vif = &mrt->vif_table[vr.vifi]; | ||
| 1476 | if (VIF_EXISTS(mrt, vr.vifi)) { | ||
| 1477 | vr.icount = vif->pkt_in; | ||
| 1478 | vr.ocount = vif->pkt_out; | ||
| 1479 | vr.ibytes = vif->bytes_in; | ||
| 1480 | vr.obytes = vif->bytes_out; | ||
| 1481 | read_unlock(&mrt_lock); | ||
| 1482 | |||
| 1483 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
| 1484 | return -EFAULT; | ||
| 1485 | return 0; | ||
| 1486 | } | ||
| 1487 | read_unlock(&mrt_lock); | ||
| 1488 | return -EADDRNOTAVAIL; | ||
| 1489 | case SIOCGETSGCNT: | ||
| 1490 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
| 1491 | return -EFAULT; | ||
| 1492 | |||
| 1493 | rcu_read_lock(); | ||
| 1494 | c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); | ||
| 1495 | if (c) { | ||
| 1496 | sr.pktcnt = c->mfc_un.res.pkt; | ||
| 1497 | sr.bytecnt = c->mfc_un.res.bytes; | ||
| 1498 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
| 1499 | rcu_read_unlock(); | ||
| 1500 | |||
| 1501 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
| 1502 | return -EFAULT; | ||
| 1503 | return 0; | ||
| 1504 | } | ||
| 1505 | rcu_read_unlock(); | ||
| 1506 | return -EADDRNOTAVAIL; | ||
| 1507 | default: | ||
| 1508 | return -ENOIOCTLCMD; | ||
| 1509 | } | ||
| 1510 | } | ||
| 1511 | #endif | ||
| 1512 | |||
| 1437 | 1513 | ||
| 1438 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) | 1514 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 1439 | { | 1515 | { |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index b8ddcc480ed..a5e52a9f0a1 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
| @@ -60,12 +60,12 @@ static int checkentry(const struct xt_tgchk_param *par) | |||
| 60 | 60 | ||
| 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
| 62 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
| 63 | return false; | 63 | return -EINVAL; |
| 64 | 64 | ||
| 65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && | 65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && |
| 66 | mangle->target != XT_CONTINUE) | 66 | mangle->target != XT_CONTINUE) |
| 67 | return false; | 67 | return -EINVAL; |
| 68 | return true; | 68 | return 0; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static struct xt_target arpt_mangle_reg __read_mostly = { | 71 | static struct xt_target arpt_mangle_reg __read_mostly = { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a3d5ab786e8..6390ba299b3 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -76,6 +76,7 @@ | |||
| 76 | #include <linux/seq_file.h> | 76 | #include <linux/seq_file.h> |
| 77 | #include <linux/netfilter.h> | 77 | #include <linux/netfilter.h> |
| 78 | #include <linux/netfilter_ipv4.h> | 78 | #include <linux/netfilter_ipv4.h> |
| 79 | #include <linux/compat.h> | ||
| 79 | 80 | ||
| 80 | static struct raw_hashinfo raw_v4_hashinfo = { | 81 | static struct raw_hashinfo raw_v4_hashinfo = { |
| 81 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), | 82 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), |
| @@ -838,6 +839,23 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 838 | } | 839 | } |
| 839 | } | 840 | } |
| 840 | 841 | ||
| 842 | #ifdef CONFIG_COMPAT | ||
| 843 | static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
| 844 | { | ||
| 845 | switch (cmd) { | ||
| 846 | case SIOCOUTQ: | ||
| 847 | case SIOCINQ: | ||
| 848 | return -ENOIOCTLCMD; | ||
| 849 | default: | ||
| 850 | #ifdef CONFIG_IP_MROUTE | ||
| 851 | return ipmr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
| 852 | #else | ||
| 853 | return -ENOIOCTLCMD; | ||
| 854 | #endif | ||
| 855 | } | ||
| 856 | } | ||
| 857 | #endif | ||
| 858 | |||
| 841 | struct proto raw_prot = { | 859 | struct proto raw_prot = { |
| 842 | .name = "RAW", | 860 | .name = "RAW", |
| 843 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
| @@ -860,6 +878,7 @@ struct proto raw_prot = { | |||
| 860 | #ifdef CONFIG_COMPAT | 878 | #ifdef CONFIG_COMPAT |
| 861 | .compat_setsockopt = compat_raw_setsockopt, | 879 | .compat_setsockopt = compat_raw_setsockopt, |
| 862 | .compat_getsockopt = compat_raw_getsockopt, | 880 | .compat_getsockopt = compat_raw_getsockopt, |
| 881 | .compat_ioctl = compat_raw_ioctl, | ||
| 863 | #endif | 882 | #endif |
| 864 | }; | 883 | }; |
| 865 | 884 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 351dc4e8524..6ed6603c2f6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2707,6 +2707,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo | |||
| 2707 | return NULL; | 2707 | return NULL; |
| 2708 | } | 2708 | } |
| 2709 | 2709 | ||
| 2710 | static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst) | ||
| 2711 | { | ||
| 2712 | return 0; | ||
| 2713 | } | ||
| 2714 | |||
| 2710 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2715 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
| 2711 | { | 2716 | { |
| 2712 | } | 2717 | } |
| @@ -2716,6 +2721,8 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
| 2716 | .protocol = cpu_to_be16(ETH_P_IP), | 2721 | .protocol = cpu_to_be16(ETH_P_IP), |
| 2717 | .destroy = ipv4_dst_destroy, | 2722 | .destroy = ipv4_dst_destroy, |
| 2718 | .check = ipv4_blackhole_dst_check, | 2723 | .check = ipv4_blackhole_dst_check, |
| 2724 | .default_mtu = ipv4_blackhole_default_mtu, | ||
| 2725 | .default_advmss = ipv4_default_advmss, | ||
| 2719 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2726 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
| 2720 | }; | 2727 | }; |
| 2721 | 2728 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 9fab274019c..0e1d53bcf1e 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
| 35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 37 | #include <linux/compat.h> | ||
| 37 | #include <net/protocol.h> | 38 | #include <net/protocol.h> |
| 38 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
| 39 | #include <net/sock.h> | 40 | #include <net/sock.h> |
| @@ -1804,6 +1805,80 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
| 1804 | } | 1805 | } |
| 1805 | } | 1806 | } |
| 1806 | 1807 | ||
| 1808 | #ifdef CONFIG_COMPAT | ||
| 1809 | struct compat_sioc_sg_req6 { | ||
| 1810 | struct sockaddr_in6 src; | ||
| 1811 | struct sockaddr_in6 grp; | ||
| 1812 | compat_ulong_t pktcnt; | ||
| 1813 | compat_ulong_t bytecnt; | ||
| 1814 | compat_ulong_t wrong_if; | ||
| 1815 | }; | ||
| 1816 | |||
| 1817 | struct compat_sioc_mif_req6 { | ||
| 1818 | mifi_t mifi; | ||
| 1819 | compat_ulong_t icount; | ||
| 1820 | compat_ulong_t ocount; | ||
| 1821 | compat_ulong_t ibytes; | ||
| 1822 | compat_ulong_t obytes; | ||
| 1823 | }; | ||
| 1824 | |||
| 1825 | int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
| 1826 | { | ||
| 1827 | struct compat_sioc_sg_req6 sr; | ||
| 1828 | struct compat_sioc_mif_req6 vr; | ||
| 1829 | struct mif_device *vif; | ||
| 1830 | struct mfc6_cache *c; | ||
| 1831 | struct net *net = sock_net(sk); | ||
| 1832 | struct mr6_table *mrt; | ||
| 1833 | |||
| 1834 | mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT); | ||
| 1835 | if (mrt == NULL) | ||
| 1836 | return -ENOENT; | ||
| 1837 | |||
| 1838 | switch (cmd) { | ||
| 1839 | case SIOCGETMIFCNT_IN6: | ||
| 1840 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
| 1841 | return -EFAULT; | ||
| 1842 | if (vr.mifi >= mrt->maxvif) | ||
| 1843 | return -EINVAL; | ||
| 1844 | read_lock(&mrt_lock); | ||
| 1845 | vif = &mrt->vif6_table[vr.mifi]; | ||
| 1846 | if (MIF_EXISTS(mrt, vr.mifi)) { | ||
| 1847 | vr.icount = vif->pkt_in; | ||
| 1848 | vr.ocount = vif->pkt_out; | ||
| 1849 | vr.ibytes = vif->bytes_in; | ||
| 1850 | vr.obytes = vif->bytes_out; | ||
| 1851 | read_unlock(&mrt_lock); | ||
| 1852 | |||
| 1853 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
| 1854 | return -EFAULT; | ||
| 1855 | return 0; | ||
| 1856 | } | ||
| 1857 | read_unlock(&mrt_lock); | ||
| 1858 | return -EADDRNOTAVAIL; | ||
| 1859 | case SIOCGETSGCNT_IN6: | ||
| 1860 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
| 1861 | return -EFAULT; | ||
| 1862 | |||
| 1863 | read_lock(&mrt_lock); | ||
| 1864 | c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); | ||
| 1865 | if (c) { | ||
| 1866 | sr.pktcnt = c->mfc_un.res.pkt; | ||
| 1867 | sr.bytecnt = c->mfc_un.res.bytes; | ||
| 1868 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
| 1869 | read_unlock(&mrt_lock); | ||
| 1870 | |||
| 1871 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
| 1872 | return -EFAULT; | ||
| 1873 | return 0; | ||
| 1874 | } | ||
| 1875 | read_unlock(&mrt_lock); | ||
| 1876 | return -EADDRNOTAVAIL; | ||
| 1877 | default: | ||
| 1878 | return -ENOIOCTLCMD; | ||
| 1879 | } | ||
| 1880 | } | ||
| 1881 | #endif | ||
| 1807 | 1882 | ||
| 1808 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) | 1883 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) |
| 1809 | { | 1884 | { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 86c39526ba5..c5b0915d106 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/netfilter.h> | 31 | #include <linux/netfilter.h> |
| 32 | #include <linux/netfilter_ipv6.h> | 32 | #include <linux/netfilter_ipv6.h> |
| 33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
| 34 | #include <linux/compat.h> | ||
| 34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 35 | #include <asm/ioctls.h> | 36 | #include <asm/ioctls.h> |
| 36 | 37 | ||
| @@ -1157,6 +1158,23 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 1157 | } | 1158 | } |
| 1158 | } | 1159 | } |
| 1159 | 1160 | ||
| 1161 | #ifdef CONFIG_COMPAT | ||
| 1162 | static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
| 1163 | { | ||
| 1164 | switch (cmd) { | ||
| 1165 | case SIOCOUTQ: | ||
| 1166 | case SIOCINQ: | ||
| 1167 | return -ENOIOCTLCMD; | ||
| 1168 | default: | ||
| 1169 | #ifdef CONFIG_IPV6_MROUTE | ||
| 1170 | return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
| 1171 | #else | ||
| 1172 | return -ENOIOCTLCMD; | ||
| 1173 | #endif | ||
| 1174 | } | ||
| 1175 | } | ||
| 1176 | #endif | ||
| 1177 | |||
| 1160 | static void rawv6_close(struct sock *sk, long timeout) | 1178 | static void rawv6_close(struct sock *sk, long timeout) |
| 1161 | { | 1179 | { |
| 1162 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) | 1180 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) |
| @@ -1215,6 +1233,7 @@ struct proto rawv6_prot = { | |||
| 1215 | #ifdef CONFIG_COMPAT | 1233 | #ifdef CONFIG_COMPAT |
| 1216 | .compat_setsockopt = compat_rawv6_setsockopt, | 1234 | .compat_setsockopt = compat_rawv6_setsockopt, |
| 1217 | .compat_getsockopt = compat_rawv6_getsockopt, | 1235 | .compat_getsockopt = compat_rawv6_getsockopt, |
| 1236 | .compat_ioctl = compat_rawv6_ioctl, | ||
| 1218 | #endif | 1237 | #endif |
| 1219 | }; | 1238 | }; |
| 1220 | 1239 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1534508f6c6..a998db6e789 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -113,6 +113,11 @@ static struct dst_ops ip6_dst_ops_template = { | |||
| 113 | .local_out = __ip6_local_out, | 113 | .local_out = __ip6_local_out, |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | ||
| 117 | { | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 116 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 121 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
| 117 | { | 122 | { |
| 118 | } | 123 | } |
| @@ -122,6 +127,8 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
| 122 | .protocol = cpu_to_be16(ETH_P_IPV6), | 127 | .protocol = cpu_to_be16(ETH_P_IPV6), |
| 123 | .destroy = ip6_dst_destroy, | 128 | .destroy = ip6_dst_destroy, |
| 124 | .check = ip6_dst_check, | 129 | .check = ip6_dst_check, |
| 130 | .default_mtu = ip6_blackhole_default_mtu, | ||
| 131 | .default_advmss = ip6_default_advmss, | ||
| 125 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 132 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
| 126 | }; | 133 | }; |
| 127 | 134 | ||
| @@ -194,7 +201,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
| 194 | in6_dev_put(idev); | 201 | in6_dev_put(idev); |
| 195 | } | 202 | } |
| 196 | if (peer) { | 203 | if (peer) { |
| 197 | BUG_ON(!(rt->rt6i_flags & RTF_CACHE)); | ||
| 198 | rt->rt6i_peer = NULL; | 204 | rt->rt6i_peer = NULL; |
| 199 | inet_putpeer(peer); | 205 | inet_putpeer(peer); |
| 200 | } | 206 | } |
| @@ -204,9 +210,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create) | |||
| 204 | { | 210 | { |
| 205 | struct inet_peer *peer; | 211 | struct inet_peer *peer; |
| 206 | 212 | ||
| 207 | if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE))) | ||
| 208 | return; | ||
| 209 | |||
| 210 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); | 213 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); |
| 211 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) | 214 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) |
| 212 | inet_putpeer(peer); | 215 | inet_putpeer(peer); |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index fa1d8f4e005..7cb65ef79f9 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <net/addrconf.h> | 15 | #include <net/addrconf.h> |
| 16 | #include <net/inet_frag.h> | 16 | #include <net/inet_frag.h> |
| 17 | 17 | ||
| 18 | static struct ctl_table empty[1]; | ||
| 19 | |||
| 18 | static ctl_table ipv6_table_template[] = { | 20 | static ctl_table ipv6_table_template[] = { |
| 19 | { | 21 | { |
| 20 | .procname = "route", | 22 | .procname = "route", |
| @@ -35,6 +37,12 @@ static ctl_table ipv6_table_template[] = { | |||
| 35 | .mode = 0644, | 37 | .mode = 0644, |
| 36 | .proc_handler = proc_dointvec | 38 | .proc_handler = proc_dointvec |
| 37 | }, | 39 | }, |
| 40 | { | ||
| 41 | .procname = "neigh", | ||
| 42 | .maxlen = 0, | ||
| 43 | .mode = 0555, | ||
| 44 | .child = empty, | ||
| 45 | }, | ||
| 38 | { } | 46 | { } |
| 39 | }; | 47 | }; |
| 40 | 48 | ||
| @@ -152,7 +160,6 @@ static struct ctl_table_header *ip6_base; | |||
| 152 | 160 | ||
| 153 | int ipv6_static_sysctl_register(void) | 161 | int ipv6_static_sysctl_register(void) |
| 154 | { | 162 | { |
| 155 | static struct ctl_table empty[1]; | ||
| 156 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); | 163 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
| 157 | if (ip6_base == NULL) | 164 | if (ip6_base == NULL) |
| 158 | return -ENOMEM; | 165 | return -ENOMEM; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4bc8a9250cf..9cd73b11506 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1822,6 +1822,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
| 1822 | *cookie ^= 2; | 1822 | *cookie ^= 2; |
| 1823 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | 1823 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; |
| 1824 | local->hw_roc_skb = skb; | 1824 | local->hw_roc_skb = skb; |
| 1825 | local->hw_roc_skb_for_status = skb; | ||
| 1825 | mutex_unlock(&local->mtx); | 1826 | mutex_unlock(&local->mtx); |
| 1826 | 1827 | ||
| 1827 | return 0; | 1828 | return 0; |
| @@ -1875,6 +1876,7 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | |||
| 1875 | if (ret == 0) { | 1876 | if (ret == 0) { |
| 1876 | kfree_skb(local->hw_roc_skb); | 1877 | kfree_skb(local->hw_roc_skb); |
| 1877 | local->hw_roc_skb = NULL; | 1878 | local->hw_roc_skb = NULL; |
| 1879 | local->hw_roc_skb_for_status = NULL; | ||
| 1878 | } | 1880 | } |
| 1879 | 1881 | ||
| 1880 | mutex_unlock(&local->mtx); | 1882 | mutex_unlock(&local->mtx); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c47d7c0e48a..533fd32f49f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -953,7 +953,7 @@ struct ieee80211_local { | |||
| 953 | 953 | ||
| 954 | struct ieee80211_channel *hw_roc_channel; | 954 | struct ieee80211_channel *hw_roc_channel; |
| 955 | struct net_device *hw_roc_dev; | 955 | struct net_device *hw_roc_dev; |
| 956 | struct sk_buff *hw_roc_skb; | 956 | struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status; |
| 957 | struct work_struct hw_roc_start, hw_roc_done; | 957 | struct work_struct hw_roc_start, hw_roc_done; |
| 958 | enum nl80211_channel_type hw_roc_channel_type; | 958 | enum nl80211_channel_type hw_roc_channel_type; |
| 959 | unsigned int hw_roc_duration; | 959 | unsigned int hw_roc_duration; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 38a797217a9..071ac95c4aa 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
| @@ -323,6 +323,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 323 | 323 | ||
| 324 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 324 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
| 325 | struct ieee80211_work *wk; | 325 | struct ieee80211_work *wk; |
| 326 | u64 cookie = (unsigned long)skb; | ||
| 326 | 327 | ||
| 327 | rcu_read_lock(); | 328 | rcu_read_lock(); |
| 328 | list_for_each_entry_rcu(wk, &local->work_list, list) { | 329 | list_for_each_entry_rcu(wk, &local->work_list, list) { |
| @@ -334,8 +335,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 334 | break; | 335 | break; |
| 335 | } | 336 | } |
| 336 | rcu_read_unlock(); | 337 | rcu_read_unlock(); |
| 338 | if (local->hw_roc_skb_for_status == skb) { | ||
| 339 | cookie = local->hw_roc_cookie ^ 2; | ||
| 340 | local->hw_roc_skb_for_status = NULL; | ||
| 341 | } | ||
| 337 | cfg80211_mgmt_tx_status( | 342 | cfg80211_mgmt_tx_status( |
| 338 | skb->dev, (unsigned long) skb, skb->data, skb->len, | 343 | skb->dev, cookie, skb->data, skb->len, |
| 339 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); | 344 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); |
| 340 | } | 345 | } |
| 341 | 346 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b64b42bc774..b0beaa58246 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1547,7 +1547,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
| 1547 | skb_orphan(skb); | 1547 | skb_orphan(skb); |
| 1548 | } | 1548 | } |
| 1549 | 1549 | ||
| 1550 | if (skb_header_cloned(skb)) | 1550 | if (skb_cloned(skb)) |
| 1551 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | 1551 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); |
| 1552 | else if (head_need || tail_need) | 1552 | else if (head_need || tail_need) |
| 1553 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1553 | I802_DEBUG_INC(local->tx_expand_skb_head); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cf68700abff..d036597aabb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -1210,7 +1210,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1210 | switch (sdata->vif.type) { | 1210 | switch (sdata->vif.type) { |
| 1211 | case NL80211_IFTYPE_STATION: | 1211 | case NL80211_IFTYPE_STATION: |
| 1212 | changed |= BSS_CHANGED_ASSOC; | 1212 | changed |= BSS_CHANGED_ASSOC; |
| 1213 | mutex_lock(&sdata->u.mgd.mtx); | ||
| 1213 | ieee80211_bss_info_change_notify(sdata, changed); | 1214 | ieee80211_bss_info_change_notify(sdata, changed); |
| 1215 | mutex_unlock(&sdata->u.mgd.mtx); | ||
| 1214 | break; | 1216 | break; |
| 1215 | case NL80211_IFTYPE_ADHOC: | 1217 | case NL80211_IFTYPE_ADHOC: |
| 1216 | changed |= BSS_CHANGED_IBSS; | 1218 | changed |= BSS_CHANGED_IBSS; |
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 32fcbe290c0..4aa614b8a96 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
| @@ -133,6 +133,7 @@ unsigned int nf_iterate(struct list_head *head, | |||
| 133 | 133 | ||
| 134 | /* Optimization: we don't need to hold module | 134 | /* Optimization: we don't need to hold module |
| 135 | reference here, since function can't sleep. --RR */ | 135 | reference here, since function can't sleep. --RR */ |
| 136 | repeat: | ||
| 136 | verdict = elem->hook(hook, skb, indev, outdev, okfn); | 137 | verdict = elem->hook(hook, skb, indev, outdev, okfn); |
| 137 | if (verdict != NF_ACCEPT) { | 138 | if (verdict != NF_ACCEPT) { |
| 138 | #ifdef CONFIG_NETFILTER_DEBUG | 139 | #ifdef CONFIG_NETFILTER_DEBUG |
| @@ -145,7 +146,7 @@ unsigned int nf_iterate(struct list_head *head, | |||
| 145 | #endif | 146 | #endif |
| 146 | if (verdict != NF_REPEAT) | 147 | if (verdict != NF_REPEAT) |
| 147 | return verdict; | 148 | return verdict; |
| 148 | *i = (*i)->prev; | 149 | goto repeat; |
| 149 | } | 150 | } |
| 150 | } | 151 | } |
| 151 | return NF_ACCEPT; | 152 | return NF_ACCEPT; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e61511929c6..84f4fcc5884 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -942,8 +942,15 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, | |||
| 942 | if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) | 942 | if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) |
| 943 | nf_conntrack_event_cache(IPCT_REPLY, ct); | 943 | nf_conntrack_event_cache(IPCT_REPLY, ct); |
| 944 | out: | 944 | out: |
| 945 | if (tmpl) | 945 | if (tmpl) { |
| 946 | nf_ct_put(tmpl); | 946 | /* Special case: we have to repeat this hook, assign the |
| 947 | * template again to this packet. We assume that this packet | ||
| 948 | * has no conntrack assigned. This is used by nf_ct_tcp. */ | ||
| 949 | if (ret == NF_REPEAT) | ||
| 950 | skb->nfct = (struct nf_conntrack *)tmpl; | ||
| 951 | else | ||
| 952 | nf_ct_put(tmpl); | ||
| 953 | } | ||
| 947 | 954 | ||
| 948 | return ret; | 955 | return ret; |
| 949 | } | 956 | } |
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index 5702de35e2b..63a1b915a7e 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c | |||
| @@ -63,6 +63,9 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct) | |||
| 63 | * this does not harm and it happens very rarely. */ | 63 | * this does not harm and it happens very rarely. */ |
| 64 | unsigned long missed = e->missed; | 64 | unsigned long missed = e->missed; |
| 65 | 65 | ||
| 66 | if (!((events | missed) & e->ctmask)) | ||
| 67 | goto out_unlock; | ||
| 68 | |||
| 66 | ret = notify->fcn(events | missed, &item); | 69 | ret = notify->fcn(events | missed, &item); |
| 67 | if (unlikely(ret < 0 || missed)) { | 70 | if (unlikely(ret < 0 || missed)) { |
| 68 | spin_lock_bh(&ct->lock); | 71 | spin_lock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 93297aaceb2..eead9db6f89 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -667,6 +667,7 @@ restart: | |||
| 667 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, | 667 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, |
| 668 | cb->nlh->nlmsg_seq, | 668 | cb->nlh->nlmsg_seq, |
| 669 | IPCTNL_MSG_CT_NEW, ct) < 0) { | 669 | IPCTNL_MSG_CT_NEW, ct) < 0) { |
| 670 | nf_conntrack_get(&ct->ct_general); | ||
| 670 | cb->args[1] = (unsigned long)ct; | 671 | cb->args[1] = (unsigned long)ct; |
| 671 | goto out; | 672 | goto out; |
| 672 | } | 673 | } |
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index 88f7c3511c7..73c33a42f87 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c | |||
| @@ -53,15 +53,13 @@ iprange_mt4(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static inline int | 55 | static inline int |
| 56 | iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b) | 56 | iprange_ipv6_lt(const struct in6_addr *a, const struct in6_addr *b) |
| 57 | { | 57 | { |
| 58 | unsigned int i; | 58 | unsigned int i; |
| 59 | int r; | ||
| 60 | 59 | ||
| 61 | for (i = 0; i < 4; ++i) { | 60 | for (i = 0; i < 4; ++i) { |
| 62 | r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]); | 61 | if (a->s6_addr32[i] != b->s6_addr32[i]) |
| 63 | if (r != 0) | 62 | return ntohl(a->s6_addr32[i]) < ntohl(b->s6_addr32[i]); |
| 64 | return r; | ||
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | return 0; | 65 | return 0; |
| @@ -75,15 +73,15 @@ iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 75 | bool m; | 73 | bool m; |
| 76 | 74 | ||
| 77 | if (info->flags & IPRANGE_SRC) { | 75 | if (info->flags & IPRANGE_SRC) { |
| 78 | m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0; | 76 | m = iprange_ipv6_lt(&iph->saddr, &info->src_min.in6); |
| 79 | m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0; | 77 | m |= iprange_ipv6_lt(&info->src_max.in6, &iph->saddr); |
| 80 | m ^= !!(info->flags & IPRANGE_SRC_INV); | 78 | m ^= !!(info->flags & IPRANGE_SRC_INV); |
| 81 | if (m) | 79 | if (m) |
| 82 | return false; | 80 | return false; |
| 83 | } | 81 | } |
| 84 | if (info->flags & IPRANGE_DST) { | 82 | if (info->flags & IPRANGE_DST) { |
| 85 | m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0; | 83 | m = iprange_ipv6_lt(&iph->daddr, &info->dst_min.in6); |
| 86 | m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0; | 84 | m |= iprange_ipv6_lt(&info->dst_max.in6, &iph->daddr); |
| 87 | m ^= !!(info->flags & IPRANGE_DST_INV); | 85 | m ^= !!(info->flags & IPRANGE_DST_INV); |
| 88 | if (m) | 86 | if (m) |
| 89 | return false; | 87 | return false; |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 55187c8f642..406207515b5 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
| @@ -27,9 +27,19 @@ | |||
| 27 | #include <net/sock.h> | 27 | #include <net/sock.h> |
| 28 | #include <net/x25.h> | 28 | #include <net/x25.h> |
| 29 | 29 | ||
| 30 | /* | 30 | /** |
| 31 | * Parse a set of facilities into the facilities structures. Unrecognised | 31 | * x25_parse_facilities - Parse facilities from skb into the facilities structs |
| 32 | * facilities are written to the debug log file. | 32 | * |
| 33 | * @skb: sk_buff to parse | ||
| 34 | * @facilities: Regular facilites, updated as facilities are found | ||
| 35 | * @dte_facs: ITU DTE facilities, updated as DTE facilities are found | ||
| 36 | * @vc_fac_mask: mask is updated with all facilities found | ||
| 37 | * | ||
| 38 | * Return codes: | ||
| 39 | * -1 - Parsing error, caller should drop call and clean up | ||
| 40 | * 0 - Parse OK, this skb has no facilities | ||
| 41 | * >0 - Parse OK, returns the length of the facilities header | ||
| 42 | * | ||
| 33 | */ | 43 | */ |
| 34 | int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | 44 | int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, |
| 35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) | 45 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
| @@ -62,7 +72,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
| 62 | switch (*p & X25_FAC_CLASS_MASK) { | 72 | switch (*p & X25_FAC_CLASS_MASK) { |
| 63 | case X25_FAC_CLASS_A: | 73 | case X25_FAC_CLASS_A: |
| 64 | if (len < 2) | 74 | if (len < 2) |
| 65 | return 0; | 75 | return -1; |
| 66 | switch (*p) { | 76 | switch (*p) { |
| 67 | case X25_FAC_REVERSE: | 77 | case X25_FAC_REVERSE: |
| 68 | if((p[1] & 0x81) == 0x81) { | 78 | if((p[1] & 0x81) == 0x81) { |
| @@ -107,7 +117,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
| 107 | break; | 117 | break; |
| 108 | case X25_FAC_CLASS_B: | 118 | case X25_FAC_CLASS_B: |
| 109 | if (len < 3) | 119 | if (len < 3) |
| 110 | return 0; | 120 | return -1; |
| 111 | switch (*p) { | 121 | switch (*p) { |
| 112 | case X25_FAC_PACKET_SIZE: | 122 | case X25_FAC_PACKET_SIZE: |
| 113 | facilities->pacsize_in = p[1]; | 123 | facilities->pacsize_in = p[1]; |
| @@ -130,7 +140,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
| 130 | break; | 140 | break; |
| 131 | case X25_FAC_CLASS_C: | 141 | case X25_FAC_CLASS_C: |
| 132 | if (len < 4) | 142 | if (len < 4) |
| 133 | return 0; | 143 | return -1; |
| 134 | printk(KERN_DEBUG "X.25: unknown facility %02X, " | 144 | printk(KERN_DEBUG "X.25: unknown facility %02X, " |
| 135 | "values %02X, %02X, %02X\n", | 145 | "values %02X, %02X, %02X\n", |
| 136 | p[0], p[1], p[2], p[3]); | 146 | p[0], p[1], p[2], p[3]); |
| @@ -139,18 +149,18 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
| 139 | break; | 149 | break; |
| 140 | case X25_FAC_CLASS_D: | 150 | case X25_FAC_CLASS_D: |
| 141 | if (len < p[1] + 2) | 151 | if (len < p[1] + 2) |
| 142 | return 0; | 152 | return -1; |
| 143 | switch (*p) { | 153 | switch (*p) { |
| 144 | case X25_FAC_CALLING_AE: | 154 | case X25_FAC_CALLING_AE: |
| 145 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) | 155 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
| 146 | return 0; | 156 | return -1; |
| 147 | dte_facs->calling_len = p[2]; | 157 | dte_facs->calling_len = p[2]; |
| 148 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | 158 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); |
| 149 | *vc_fac_mask |= X25_MASK_CALLING_AE; | 159 | *vc_fac_mask |= X25_MASK_CALLING_AE; |
| 150 | break; | 160 | break; |
| 151 | case X25_FAC_CALLED_AE: | 161 | case X25_FAC_CALLED_AE: |
| 152 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) | 162 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
| 153 | return 0; | 163 | return -1; |
| 154 | dte_facs->called_len = p[2]; | 164 | dte_facs->called_len = p[2]; |
| 155 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | 165 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); |
| 156 | *vc_fac_mask |= X25_MASK_CALLED_AE; | 166 | *vc_fac_mask |= X25_MASK_CALLED_AE; |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index f729f022be6..15de65f0471 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
| @@ -91,10 +91,10 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 91 | { | 91 | { |
| 92 | struct x25_address source_addr, dest_addr; | 92 | struct x25_address source_addr, dest_addr; |
| 93 | int len; | 93 | int len; |
| 94 | struct x25_sock *x25 = x25_sk(sk); | ||
| 94 | 95 | ||
| 95 | switch (frametype) { | 96 | switch (frametype) { |
| 96 | case X25_CALL_ACCEPTED: { | 97 | case X25_CALL_ACCEPTED: { |
| 97 | struct x25_sock *x25 = x25_sk(sk); | ||
| 98 | 98 | ||
| 99 | x25_stop_timer(sk); | 99 | x25_stop_timer(sk); |
| 100 | x25->condition = 0x00; | 100 | x25->condition = 0x00; |
| @@ -113,14 +113,16 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 113 | &dest_addr); | 113 | &dest_addr); |
| 114 | if (len > 0) | 114 | if (len > 0) |
| 115 | skb_pull(skb, len); | 115 | skb_pull(skb, len); |
| 116 | else if (len < 0) | ||
| 117 | goto out_clear; | ||
| 116 | 118 | ||
| 117 | len = x25_parse_facilities(skb, &x25->facilities, | 119 | len = x25_parse_facilities(skb, &x25->facilities, |
| 118 | &x25->dte_facilities, | 120 | &x25->dte_facilities, |
| 119 | &x25->vc_facil_mask); | 121 | &x25->vc_facil_mask); |
| 120 | if (len > 0) | 122 | if (len > 0) |
| 121 | skb_pull(skb, len); | 123 | skb_pull(skb, len); |
| 122 | else | 124 | else if (len < 0) |
| 123 | return -1; | 125 | goto out_clear; |
| 124 | /* | 126 | /* |
| 125 | * Copy any Call User Data. | 127 | * Copy any Call User Data. |
| 126 | */ | 128 | */ |
| @@ -144,6 +146,12 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 144 | } | 146 | } |
| 145 | 147 | ||
| 146 | return 0; | 148 | return 0; |
| 149 | |||
| 150 | out_clear: | ||
| 151 | x25_write_internal(sk, X25_CLEAR_REQUEST); | ||
| 152 | x25->state = X25_STATE_2; | ||
| 153 | x25_start_t23timer(sk); | ||
| 154 | return 0; | ||
| 147 | } | 155 | } |
| 148 | 156 | ||
| 149 | /* | 157 | /* |
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 4cbc942f762..21306928d47 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
| @@ -396,9 +396,12 @@ void __exit x25_link_free(void) | |||
| 396 | write_lock_bh(&x25_neigh_list_lock); | 396 | write_lock_bh(&x25_neigh_list_lock); |
| 397 | 397 | ||
| 398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
| 399 | struct net_device *dev; | ||
| 400 | |||
| 399 | nb = list_entry(entry, struct x25_neigh, node); | 401 | nb = list_entry(entry, struct x25_neigh, node); |
| 402 | dev = nb->dev; | ||
| 400 | __x25_remove_neigh(nb); | 403 | __x25_remove_neigh(nb); |
| 401 | dev_put(nb->dev); | 404 | dev_put(dev); |
| 402 | } | 405 | } |
| 403 | write_unlock_bh(&x25_neigh_list_lock); | 406 | write_unlock_bh(&x25_neigh_list_lock); |
| 404 | } | 407 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8b3ef404c79..6459588befc 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1340,10 +1340,13 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) | |||
| 1340 | default: | 1340 | default: |
| 1341 | BUG(); | 1341 | BUG(); |
| 1342 | } | 1342 | } |
| 1343 | xdst = dst_alloc(dst_ops) ?: ERR_PTR(-ENOBUFS); | 1343 | xdst = dst_alloc(dst_ops); |
| 1344 | xfrm_policy_put_afinfo(afinfo); | 1344 | xfrm_policy_put_afinfo(afinfo); |
| 1345 | 1345 | ||
| 1346 | xdst->flo.ops = &xfrm_bundle_fc_ops; | 1346 | if (likely(xdst)) |
| 1347 | xdst->flo.ops = &xfrm_bundle_fc_ops; | ||
| 1348 | else | ||
| 1349 | xdst = ERR_PTR(-ENOBUFS); | ||
| 1347 | 1350 | ||
| 1348 | return xdst; | 1351 | return xdst; |
| 1349 | } | 1352 | } |
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index b0b2357aef4..f6cbc3ddb68 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb | |||
| @@ -238,12 +238,12 @@ EOF | |||
| 238 | fi | 238 | fi |
| 239 | 239 | ||
| 240 | # Build header package | 240 | # Build header package |
| 241 | find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$ | 241 | (cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$) |
| 242 | find arch/x86/include include scripts -type f >> /tmp/files$$ | 242 | (cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$) |
| 243 | (cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$) | 243 | (cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$) |
| 244 | destdir=$kernel_headers_dir/usr/src/linux-headers-$version | 244 | destdir=$kernel_headers_dir/usr/src/linux-headers-$version |
| 245 | mkdir -p "$destdir" | 245 | mkdir -p "$destdir" |
| 246 | tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -) | 246 | (cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -) |
| 247 | (cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -) | 247 | (cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -) |
| 248 | rm -f /tmp/files$$ /tmp/objfiles$$ | 248 | rm -f /tmp/files$$ /tmp/objfiles$$ |
| 249 | arch=$(dpkg --print-architecture) | 249 | arch=$(dpkg --print-architecture) |
diff --git a/security/security.c b/security/security.c index 739e40362f4..7b7308ace8c 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -154,10 +154,9 @@ int security_capset(struct cred *new, const struct cred *old, | |||
| 154 | effective, inheritable, permitted); | 154 | effective, inheritable, permitted); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | int security_capable(int cap) | 157 | int security_capable(const struct cred *cred, int cap) |
| 158 | { | 158 | { |
| 159 | return security_ops->capable(current, current_cred(), cap, | 159 | return security_ops->capable(current, cred, cap, SECURITY_CAP_AUDIT); |
| 160 | SECURITY_CAP_AUDIT); | ||
| 161 | } | 160 | } |
| 162 | 161 | ||
| 163 | int security_real_capable(struct task_struct *tsk, int cap) | 162 | int security_real_capable(struct task_struct *tsk, int cap) |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e276eb46853..c8d69927068 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -3198,7 +3198,11 @@ static void selinux_cred_free(struct cred *cred) | |||
| 3198 | { | 3198 | { |
| 3199 | struct task_security_struct *tsec = cred->security; | 3199 | struct task_security_struct *tsec = cred->security; |
| 3200 | 3200 | ||
| 3201 | BUG_ON((unsigned long) cred->security < PAGE_SIZE); | 3201 | /* |
| 3202 | * cred->security == NULL if security_cred_alloc_blank() or | ||
| 3203 | * security_prepare_creds() returned an error. | ||
| 3204 | */ | ||
| 3205 | BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); | ||
| 3202 | cred->security = (void *) 0x7UL; | 3206 | cred->security = (void *) 0x7UL; |
| 3203 | kfree(tsec); | 3207 | kfree(tsec); |
| 3204 | } | 3208 | } |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 24d3013c023..7c1fc64cb53 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
| @@ -50,7 +50,11 @@ static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97) | |||
| 50 | if (v & SLFR_1RXV) | 50 | if (v & SLFR_1RXV) |
| 51 | readl(aaci->base + AACI_SL1RX); | 51 | readl(aaci->base + AACI_SL1RX); |
| 52 | 52 | ||
| 53 | writel(maincr, aaci->base + AACI_MAINCR); | 53 | if (maincr != readl(aaci->base + AACI_MAINCR)) { |
| 54 | writel(maincr, aaci->base + AACI_MAINCR); | ||
| 55 | readl(aaci->base + AACI_MAINCR); | ||
| 56 | udelay(1); | ||
| 57 | } | ||
| 54 | } | 58 | } |
| 55 | 59 | ||
| 56 | /* | 60 | /* |
| @@ -993,6 +997,8 @@ static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) | |||
| 993 | * disabling the channel doesn't clear the FIFO. | 997 | * disabling the channel doesn't clear the FIFO. |
| 994 | */ | 998 | */ |
| 995 | writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); | 999 | writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); |
| 1000 | readl(aaci->base + AACI_MAINCR); | ||
| 1001 | udelay(1); | ||
| 996 | writel(aaci->maincr, aaci->base + AACI_MAINCR); | 1002 | writel(aaci->maincr, aaci->base + AACI_MAINCR); |
| 997 | 1003 | ||
| 998 | /* | 1004 | /* |
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c index 7730575bfad..b8b31c433d6 100644 --- a/sound/core/hrtimer.c +++ b/sound/core/hrtimer.c | |||
| @@ -45,12 +45,13 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) | |||
| 45 | { | 45 | { |
| 46 | struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); | 46 | struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); |
| 47 | struct snd_timer *t = stime->timer; | 47 | struct snd_timer *t = stime->timer; |
| 48 | unsigned long oruns; | ||
| 48 | 49 | ||
| 49 | if (!atomic_read(&stime->running)) | 50 | if (!atomic_read(&stime->running)) |
| 50 | return HRTIMER_NORESTART; | 51 | return HRTIMER_NORESTART; |
| 51 | 52 | ||
| 52 | hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); | 53 | oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); |
| 53 | snd_timer_interrupt(stime->timer, t->sticks); | 54 | snd_timer_interrupt(stime->timer, t->sticks * oruns); |
| 54 | 55 | ||
| 55 | if (!atomic_read(&stime->running)) | 56 | if (!atomic_read(&stime->running)) |
| 56 | return HRTIMER_NORESTART; | 57 | return HRTIMER_NORESTART; |
| @@ -104,7 +105,7 @@ static int snd_hrtimer_stop(struct snd_timer *t) | |||
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | static struct snd_timer_hardware hrtimer_hw = { | 107 | static struct snd_timer_hardware hrtimer_hw = { |
| 107 | .flags = SNDRV_TIMER_HW_AUTO, | 108 | .flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET, |
| 108 | .open = snd_hrtimer_open, | 109 | .open = snd_hrtimer_open, |
| 109 | .close = snd_hrtimer_close, | 110 | .close = snd_hrtimer_close, |
| 110 | .start = snd_hrtimer_start, | 111 | .start = snd_hrtimer_start, |
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index da03597fc89..5c426df8767 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c | |||
| @@ -55,14 +55,13 @@ | |||
| 55 | #include <linux/err.h> | 55 | #include <linux/err.h> |
| 56 | #include <linux/platform_device.h> | 56 | #include <linux/platform_device.h> |
| 57 | #include <linux/ioport.h> | 57 | #include <linux/ioport.h> |
| 58 | #include <linux/io.h> | ||
| 58 | #include <linux/moduleparam.h> | 59 | #include <linux/moduleparam.h> |
| 59 | #include <sound/core.h> | 60 | #include <sound/core.h> |
| 60 | #include <sound/initval.h> | 61 | #include <sound/initval.h> |
| 61 | #include <sound/rawmidi.h> | 62 | #include <sound/rawmidi.h> |
| 62 | #include <linux/delay.h> | 63 | #include <linux/delay.h> |
| 63 | 64 | ||
| 64 | #include <asm/io.h> | ||
| 65 | |||
| 66 | /* | 65 | /* |
| 67 | * globals | 66 | * globals |
| 68 | */ | 67 | */ |
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 96f14dcd0cd..90ffb99c6b1 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
| @@ -87,7 +87,7 @@ ifeq ($(CONFIG_PSS_HAVE_BOOT),y) | |||
| 87 | $(obj)/bin2hex pss_synth < $< > $@ | 87 | $(obj)/bin2hex pss_synth < $< > $@ |
| 88 | else | 88 | else |
| 89 | $(obj)/pss_boot.h: | 89 | $(obj)/pss_boot.h: |
| 90 | ( \ | 90 | $(Q)( \ |
| 91 | echo 'static unsigned char * pss_synth = NULL;'; \ | 91 | echo 'static unsigned char * pss_synth = NULL;'; \ |
| 92 | echo 'static int pss_synthLen = 0;'; \ | 92 | echo 'static int pss_synthLen = 0;'; \ |
| 93 | ) > $@ | 93 | ) > $@ |
| @@ -102,7 +102,7 @@ ifeq ($(CONFIG_TRIX_HAVE_BOOT),y) | |||
| 102 | $(obj)/hex2hex -i trix_boot < $< > $@ | 102 | $(obj)/hex2hex -i trix_boot < $< > $@ |
| 103 | else | 103 | else |
| 104 | $(obj)/trix_boot.h: | 104 | $(obj)/trix_boot.h: |
| 105 | ( \ | 105 | $(Q)( \ |
| 106 | echo 'static unsigned char * trix_boot = NULL;'; \ | 106 | echo 'static unsigned char * trix_boot = NULL;'; \ |
| 107 | echo 'static int trix_boot_len = 0;'; \ | 107 | echo 'static int trix_boot_len = 0;'; \ |
| 108 | ) > $@ | 108 | ) > $@ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2e91a991eb1..0baffcdee8f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -2703,7 +2703,7 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
| 2703 | if (err < 0) | 2703 | if (err < 0) |
| 2704 | goto out_free; | 2704 | goto out_free; |
| 2705 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 2705 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
| 2706 | if (patch[dev]) { | 2706 | if (patch[dev] && *patch[dev]) { |
| 2707 | snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", | 2707 | snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", |
| 2708 | patch[dev]); | 2708 | patch[dev]); |
| 2709 | err = snd_hda_load_patch(chip->bus, patch[dev]); | 2709 | err = snd_hda_load_patch(chip->bus, patch[dev]); |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 9bb030a469c..fbe97d32140 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -85,6 +85,7 @@ struct conexant_spec { | |||
| 85 | unsigned int auto_mic; | 85 | unsigned int auto_mic; |
| 86 | int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ | 86 | int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ |
| 87 | unsigned int need_dac_fix; | 87 | unsigned int need_dac_fix; |
| 88 | hda_nid_t slave_dig_outs[2]; | ||
| 88 | 89 | ||
| 89 | /* capture */ | 90 | /* capture */ |
| 90 | unsigned int num_adc_nids; | 91 | unsigned int num_adc_nids; |
| @@ -127,6 +128,7 @@ struct conexant_spec { | |||
| 127 | unsigned int ideapad:1; | 128 | unsigned int ideapad:1; |
| 128 | unsigned int thinkpad:1; | 129 | unsigned int thinkpad:1; |
| 129 | unsigned int hp_laptop:1; | 130 | unsigned int hp_laptop:1; |
| 131 | unsigned int asus:1; | ||
| 130 | 132 | ||
| 131 | unsigned int ext_mic_present; | 133 | unsigned int ext_mic_present; |
| 132 | unsigned int recording; | 134 | unsigned int recording; |
| @@ -352,6 +354,8 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
| 352 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 354 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
| 353 | spec->dig_in_nid; | 355 | spec->dig_in_nid; |
| 354 | } | 356 | } |
| 357 | if (spec->slave_dig_outs[0]) | ||
| 358 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
| 355 | } | 359 | } |
| 356 | 360 | ||
| 357 | return 0; | 361 | return 0; |
| @@ -403,10 +407,16 @@ static int conexant_add_jack(struct hda_codec *codec, | |||
| 403 | struct conexant_spec *spec; | 407 | struct conexant_spec *spec; |
| 404 | struct conexant_jack *jack; | 408 | struct conexant_jack *jack; |
| 405 | const char *name; | 409 | const char *name; |
| 406 | int err; | 410 | int i, err; |
| 407 | 411 | ||
| 408 | spec = codec->spec; | 412 | spec = codec->spec; |
| 409 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | 413 | snd_array_init(&spec->jacks, sizeof(*jack), 32); |
| 414 | |||
| 415 | jack = spec->jacks.list; | ||
| 416 | for (i = 0; i < spec->jacks.used; i++, jack++) | ||
| 417 | if (jack->nid == nid) | ||
| 418 | return 0 ; /* already present */ | ||
| 419 | |||
| 410 | jack = snd_array_new(&spec->jacks); | 420 | jack = snd_array_new(&spec->jacks); |
| 411 | name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; | 421 | name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; |
| 412 | 422 | ||
| @@ -2100,7 +2110,7 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
| 2100 | static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; | 2110 | static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; |
| 2101 | static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; | 2111 | static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; |
| 2102 | static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; | 2112 | static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; |
| 2103 | #define CXT5066_SPDIF_OUT 0x21 | 2113 | static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; |
| 2104 | 2114 | ||
| 2105 | /* OLPC's microphone port is DC coupled for use with external sensors, | 2115 | /* OLPC's microphone port is DC coupled for use with external sensors, |
| 2106 | * therefore we use a 50% mic bias in order to center the input signal with | 2116 | * therefore we use a 50% mic bias in order to center the input signal with |
| @@ -2312,6 +2322,19 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) | |||
| 2312 | } | 2322 | } |
| 2313 | } | 2323 | } |
| 2314 | 2324 | ||
| 2325 | |||
| 2326 | /* toggle input of built-in digital mic and mic jack appropriately */ | ||
| 2327 | static void cxt5066_asus_automic(struct hda_codec *codec) | ||
| 2328 | { | ||
| 2329 | unsigned int present; | ||
| 2330 | |||
| 2331 | present = snd_hda_jack_detect(codec, 0x1b); | ||
| 2332 | snd_printdd("CXT5066: external microphone present=%d\n", present); | ||
| 2333 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, | ||
| 2334 | present ? 1 : 0); | ||
| 2335 | } | ||
| 2336 | |||
| 2337 | |||
| 2315 | /* toggle input of built-in digital mic and mic jack appropriately */ | 2338 | /* toggle input of built-in digital mic and mic jack appropriately */ |
| 2316 | static void cxt5066_hp_laptop_automic(struct hda_codec *codec) | 2339 | static void cxt5066_hp_laptop_automic(struct hda_codec *codec) |
| 2317 | { | 2340 | { |
| @@ -2387,79 +2410,55 @@ static void cxt5066_hp_automute(struct hda_codec *codec) | |||
| 2387 | cxt5066_update_speaker(codec); | 2410 | cxt5066_update_speaker(codec); |
| 2388 | } | 2411 | } |
| 2389 | 2412 | ||
| 2390 | /* unsolicited event for jack sensing */ | 2413 | /* Dispatch the right mic autoswitch function */ |
| 2391 | static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res) | 2414 | static void cxt5066_automic(struct hda_codec *codec) |
| 2392 | { | 2415 | { |
| 2393 | struct conexant_spec *spec = codec->spec; | 2416 | struct conexant_spec *spec = codec->spec; |
| 2394 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); | ||
| 2395 | switch (res >> 26) { | ||
| 2396 | case CONEXANT_HP_EVENT: | ||
| 2397 | cxt5066_hp_automute(codec); | ||
| 2398 | break; | ||
| 2399 | case CONEXANT_MIC_EVENT: | ||
| 2400 | /* ignore mic events in DC mode; we're always using the jack */ | ||
| 2401 | if (!spec->dc_enable) | ||
| 2402 | cxt5066_olpc_automic(codec); | ||
| 2403 | break; | ||
| 2404 | } | ||
| 2405 | } | ||
| 2406 | 2417 | ||
| 2407 | /* unsolicited event for jack sensing */ | 2418 | if (spec->dell_vostro) |
| 2408 | static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res) | ||
| 2409 | { | ||
| 2410 | snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26); | ||
| 2411 | switch (res >> 26) { | ||
| 2412 | case CONEXANT_HP_EVENT: | ||
| 2413 | cxt5066_hp_automute(codec); | ||
| 2414 | break; | ||
| 2415 | case CONEXANT_MIC_EVENT: | ||
| 2416 | cxt5066_vostro_automic(codec); | 2419 | cxt5066_vostro_automic(codec); |
| 2417 | break; | 2420 | else if (spec->ideapad) |
| 2418 | } | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | /* unsolicited event for jack sensing */ | ||
| 2422 | static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res) | ||
| 2423 | { | ||
| 2424 | snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26); | ||
| 2425 | switch (res >> 26) { | ||
| 2426 | case CONEXANT_HP_EVENT: | ||
| 2427 | cxt5066_hp_automute(codec); | ||
| 2428 | break; | ||
| 2429 | case CONEXANT_MIC_EVENT: | ||
| 2430 | cxt5066_ideapad_automic(codec); | 2421 | cxt5066_ideapad_automic(codec); |
| 2431 | break; | 2422 | else if (spec->thinkpad) |
| 2432 | } | 2423 | cxt5066_thinkpad_automic(codec); |
| 2424 | else if (spec->hp_laptop) | ||
| 2425 | cxt5066_hp_laptop_automic(codec); | ||
| 2426 | else if (spec->asus) | ||
| 2427 | cxt5066_asus_automic(codec); | ||
| 2433 | } | 2428 | } |
| 2434 | 2429 | ||
| 2435 | /* unsolicited event for jack sensing */ | 2430 | /* unsolicited event for jack sensing */ |
| 2436 | static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res) | 2431 | static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res) |
| 2437 | { | 2432 | { |
| 2438 | snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26); | 2433 | struct conexant_spec *spec = codec->spec; |
| 2434 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); | ||
| 2439 | switch (res >> 26) { | 2435 | switch (res >> 26) { |
| 2440 | case CONEXANT_HP_EVENT: | 2436 | case CONEXANT_HP_EVENT: |
| 2441 | cxt5066_hp_automute(codec); | 2437 | cxt5066_hp_automute(codec); |
| 2442 | break; | 2438 | break; |
| 2443 | case CONEXANT_MIC_EVENT: | 2439 | case CONEXANT_MIC_EVENT: |
| 2444 | cxt5066_hp_laptop_automic(codec); | 2440 | /* ignore mic events in DC mode; we're always using the jack */ |
| 2441 | if (!spec->dc_enable) | ||
| 2442 | cxt5066_olpc_automic(codec); | ||
| 2445 | break; | 2443 | break; |
| 2446 | } | 2444 | } |
| 2447 | } | 2445 | } |
| 2448 | 2446 | ||
| 2449 | /* unsolicited event for jack sensing */ | 2447 | /* unsolicited event for jack sensing */ |
| 2450 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) | 2448 | static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) |
| 2451 | { | 2449 | { |
| 2452 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); | 2450 | snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); |
| 2453 | switch (res >> 26) { | 2451 | switch (res >> 26) { |
| 2454 | case CONEXANT_HP_EVENT: | 2452 | case CONEXANT_HP_EVENT: |
| 2455 | cxt5066_hp_automute(codec); | 2453 | cxt5066_hp_automute(codec); |
| 2456 | break; | 2454 | break; |
| 2457 | case CONEXANT_MIC_EVENT: | 2455 | case CONEXANT_MIC_EVENT: |
| 2458 | cxt5066_thinkpad_automic(codec); | 2456 | cxt5066_automic(codec); |
| 2459 | break; | 2457 | break; |
| 2460 | } | 2458 | } |
| 2461 | } | 2459 | } |
| 2462 | 2460 | ||
| 2461 | |||
| 2463 | static const struct hda_input_mux cxt5066_analog_mic_boost = { | 2462 | static const struct hda_input_mux cxt5066_analog_mic_boost = { |
| 2464 | .num_items = 5, | 2463 | .num_items = 5, |
| 2465 | .items = { | 2464 | .items = { |
| @@ -2633,6 +2632,27 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec) | |||
| 2633 | spec->recording = 0; | 2632 | spec->recording = 0; |
| 2634 | } | 2633 | } |
| 2635 | 2634 | ||
| 2635 | static void conexant_check_dig_outs(struct hda_codec *codec, | ||
| 2636 | hda_nid_t *dig_pins, | ||
| 2637 | int num_pins) | ||
| 2638 | { | ||
| 2639 | struct conexant_spec *spec = codec->spec; | ||
| 2640 | hda_nid_t *nid_loc = &spec->multiout.dig_out_nid; | ||
| 2641 | int i; | ||
| 2642 | |||
| 2643 | for (i = 0; i < num_pins; i++, dig_pins++) { | ||
| 2644 | unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins); | ||
| 2645 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE) | ||
| 2646 | continue; | ||
| 2647 | if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) | ||
| 2648 | continue; | ||
| 2649 | if (spec->slave_dig_outs[0]) | ||
| 2650 | nid_loc++; | ||
| 2651 | else | ||
| 2652 | nid_loc = spec->slave_dig_outs; | ||
| 2653 | } | ||
| 2654 | } | ||
| 2655 | |||
| 2636 | static struct hda_input_mux cxt5066_capture_source = { | 2656 | static struct hda_input_mux cxt5066_capture_source = { |
| 2637 | .num_items = 4, | 2657 | .num_items = 4, |
| 2638 | .items = { | 2658 | .items = { |
| @@ -3039,20 +3059,11 @@ static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { | |||
| 3039 | /* initialize jack-sensing, too */ | 3059 | /* initialize jack-sensing, too */ |
| 3040 | static int cxt5066_init(struct hda_codec *codec) | 3060 | static int cxt5066_init(struct hda_codec *codec) |
| 3041 | { | 3061 | { |
| 3042 | struct conexant_spec *spec = codec->spec; | ||
| 3043 | |||
| 3044 | snd_printdd("CXT5066: init\n"); | 3062 | snd_printdd("CXT5066: init\n"); |
| 3045 | conexant_init(codec); | 3063 | conexant_init(codec); |
| 3046 | if (codec->patch_ops.unsol_event) { | 3064 | if (codec->patch_ops.unsol_event) { |
| 3047 | cxt5066_hp_automute(codec); | 3065 | cxt5066_hp_automute(codec); |
| 3048 | if (spec->dell_vostro) | 3066 | cxt5066_automic(codec); |
| 3049 | cxt5066_vostro_automic(codec); | ||
| 3050 | else if (spec->ideapad) | ||
| 3051 | cxt5066_ideapad_automic(codec); | ||
| 3052 | else if (spec->thinkpad) | ||
| 3053 | cxt5066_thinkpad_automic(codec); | ||
| 3054 | else if (spec->hp_laptop) | ||
| 3055 | cxt5066_hp_laptop_automic(codec); | ||
| 3056 | } | 3067 | } |
| 3057 | cxt5066_set_mic_boost(codec); | 3068 | cxt5066_set_mic_boost(codec); |
| 3058 | return 0; | 3069 | return 0; |
| @@ -3080,6 +3091,7 @@ enum { | |||
| 3080 | CXT5066_DELL_VOSTRO, /* Dell Vostro 1015i */ | 3091 | CXT5066_DELL_VOSTRO, /* Dell Vostro 1015i */ |
| 3081 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ | 3092 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ |
| 3082 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ | 3093 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ |
| 3094 | CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ | ||
| 3083 | CXT5066_HP_LAPTOP, /* HP Laptop */ | 3095 | CXT5066_HP_LAPTOP, /* HP Laptop */ |
| 3084 | CXT5066_MODELS | 3096 | CXT5066_MODELS |
| 3085 | }; | 3097 | }; |
| @@ -3091,6 +3103,7 @@ static const char * const cxt5066_models[CXT5066_MODELS] = { | |||
| 3091 | [CXT5066_DELL_VOSTRO] = "dell-vostro", | 3103 | [CXT5066_DELL_VOSTRO] = "dell-vostro", |
| 3092 | [CXT5066_IDEAPAD] = "ideapad", | 3104 | [CXT5066_IDEAPAD] = "ideapad", |
| 3093 | [CXT5066_THINKPAD] = "thinkpad", | 3105 | [CXT5066_THINKPAD] = "thinkpad", |
| 3106 | [CXT5066_ASUS] = "asus", | ||
| 3094 | [CXT5066_HP_LAPTOP] = "hp-laptop", | 3107 | [CXT5066_HP_LAPTOP] = "hp-laptop", |
| 3095 | }; | 3108 | }; |
| 3096 | 3109 | ||
| @@ -3102,7 +3115,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
| 3102 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3115 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), |
| 3103 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3116 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
| 3104 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), | 3117 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), |
| 3105 | SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP), | 3118 | SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS), |
| 3119 | SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS), | ||
| 3120 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), | ||
| 3106 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), | 3121 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), |
| 3107 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3122 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
| 3108 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | 3123 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), |
| @@ -3111,7 +3126,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
| 3111 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3126 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
| 3112 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 3127 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
| 3113 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | 3128 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), |
| 3129 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), | ||
| 3114 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3130 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
| 3131 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | ||
| 3115 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ | 3132 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ |
| 3116 | {} | 3133 | {} |
| 3117 | }; | 3134 | }; |
| @@ -3133,7 +3150,8 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 3133 | spec->multiout.max_channels = 2; | 3150 | spec->multiout.max_channels = 2; |
| 3134 | spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids); | 3151 | spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids); |
| 3135 | spec->multiout.dac_nids = cxt5066_dac_nids; | 3152 | spec->multiout.dac_nids = cxt5066_dac_nids; |
| 3136 | spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT; | 3153 | conexant_check_dig_outs(codec, cxt5066_digout_pin_nids, |
| 3154 | ARRAY_SIZE(cxt5066_digout_pin_nids)); | ||
| 3137 | spec->num_adc_nids = 1; | 3155 | spec->num_adc_nids = 1; |
| 3138 | spec->adc_nids = cxt5066_adc_nids; | 3156 | spec->adc_nids = cxt5066_adc_nids; |
| 3139 | spec->capsrc_nids = cxt5066_capsrc_nids; | 3157 | spec->capsrc_nids = cxt5066_capsrc_nids; |
| @@ -3167,17 +3185,20 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 3167 | spec->num_init_verbs++; | 3185 | spec->num_init_verbs++; |
| 3168 | spec->dell_automute = 1; | 3186 | spec->dell_automute = 1; |
| 3169 | break; | 3187 | break; |
| 3188 | case CXT5066_ASUS: | ||
| 3170 | case CXT5066_HP_LAPTOP: | 3189 | case CXT5066_HP_LAPTOP: |
| 3171 | codec->patch_ops.init = cxt5066_init; | 3190 | codec->patch_ops.init = cxt5066_init; |
| 3172 | codec->patch_ops.unsol_event = cxt5066_hp_laptop_event; | 3191 | codec->patch_ops.unsol_event = cxt5066_unsol_event; |
| 3173 | spec->init_verbs[spec->num_init_verbs] = | 3192 | spec->init_verbs[spec->num_init_verbs] = |
| 3174 | cxt5066_init_verbs_hp_laptop; | 3193 | cxt5066_init_verbs_hp_laptop; |
| 3175 | spec->num_init_verbs++; | 3194 | spec->num_init_verbs++; |
| 3176 | spec->hp_laptop = 1; | 3195 | spec->hp_laptop = board_config == CXT5066_HP_LAPTOP; |
| 3196 | spec->asus = board_config == CXT5066_ASUS; | ||
| 3177 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | 3197 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; |
| 3178 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 3198 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
| 3179 | /* no S/PDIF out */ | 3199 | /* no S/PDIF out */ |
| 3180 | spec->multiout.dig_out_nid = 0; | 3200 | if (board_config == CXT5066_HP_LAPTOP) |
| 3201 | spec->multiout.dig_out_nid = 0; | ||
| 3181 | /* input source automatically selected */ | 3202 | /* input source automatically selected */ |
| 3182 | spec->input_mux = NULL; | 3203 | spec->input_mux = NULL; |
| 3183 | spec->port_d_mode = 0; | 3204 | spec->port_d_mode = 0; |
| @@ -3207,7 +3228,7 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 3207 | break; | 3228 | break; |
| 3208 | case CXT5066_DELL_VOSTRO: | 3229 | case CXT5066_DELL_VOSTRO: |
| 3209 | codec->patch_ops.init = cxt5066_init; | 3230 | codec->patch_ops.init = cxt5066_init; |
| 3210 | codec->patch_ops.unsol_event = cxt5066_vostro_event; | 3231 | codec->patch_ops.unsol_event = cxt5066_unsol_event; |
| 3211 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; | 3232 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; |
| 3212 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | 3233 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; |
| 3213 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 3234 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
| @@ -3224,7 +3245,7 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 3224 | break; | 3245 | break; |
| 3225 | case CXT5066_IDEAPAD: | 3246 | case CXT5066_IDEAPAD: |
| 3226 | codec->patch_ops.init = cxt5066_init; | 3247 | codec->patch_ops.init = cxt5066_init; |
| 3227 | codec->patch_ops.unsol_event = cxt5066_ideapad_event; | 3248 | codec->patch_ops.unsol_event = cxt5066_unsol_event; |
| 3228 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | 3249 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; |
| 3229 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 3250 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
| 3230 | spec->init_verbs[0] = cxt5066_init_verbs_ideapad; | 3251 | spec->init_verbs[0] = cxt5066_init_verbs_ideapad; |
| @@ -3240,7 +3261,7 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 3240 | break; | 3261 | break; |
| 3241 | case CXT5066_THINKPAD: | 3262 | case CXT5066_THINKPAD: |
| 3242 | codec->patch_ops.init = cxt5066_init; | 3263 | codec->patch_ops.init = cxt5066_init; |
| 3243 | codec->patch_ops.unsol_event = cxt5066_thinkpad_event; | 3264 | codec->patch_ops.unsol_event = cxt5066_unsol_event; |
| 3244 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | 3265 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; |
| 3245 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 3266 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
| 3246 | spec->init_verbs[0] = cxt5066_init_verbs_thinkpad; | 3267 | spec->init_verbs[0] = cxt5066_init_verbs_thinkpad; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2d5b83fa8d2..a5876773672 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -642,6 +642,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 642 | hdmi_ai->ver = 0x01; | 642 | hdmi_ai->ver = 0x01; |
| 643 | hdmi_ai->len = 0x0a; | 643 | hdmi_ai->len = 0x0a; |
| 644 | hdmi_ai->CC02_CT47 = channels - 1; | 644 | hdmi_ai->CC02_CT47 = channels - 1; |
| 645 | hdmi_ai->CA = ca; | ||
| 645 | hdmi_checksum_audio_infoframe(hdmi_ai); | 646 | hdmi_checksum_audio_infoframe(hdmi_ai); |
| 646 | } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ | 647 | } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ |
| 647 | struct dp_audio_infoframe *dp_ai; | 648 | struct dp_audio_infoframe *dp_ai; |
| @@ -651,6 +652,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
| 651 | dp_ai->len = 0x1b; | 652 | dp_ai->len = 0x1b; |
| 652 | dp_ai->ver = 0x11 << 2; | 653 | dp_ai->ver = 0x11 << 2; |
| 653 | dp_ai->CC02_CT47 = channels - 1; | 654 | dp_ai->CC02_CT47 = channels - 1; |
| 655 | dp_ai->CA = ca; | ||
| 654 | } else { | 656 | } else { |
| 655 | snd_printd("HDMI: unknown connection type at pin %d\n", | 657 | snd_printd("HDMI: unknown connection type at pin %d\n", |
| 656 | pin_nid); | 658 | pin_nid); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2fa9ed99c32..3328a259a24 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -2290,6 +2290,29 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
| 2290 | { } /* end */ | 2290 | { } /* end */ |
| 2291 | }; | 2291 | }; |
| 2292 | 2292 | ||
| 2293 | static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { | ||
| 2294 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
| 2295 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 2296 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
| 2297 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
| 2298 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0, | ||
| 2299 | HDA_OUTPUT), | ||
| 2300 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT), | ||
| 2301 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), | ||
| 2302 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), | ||
| 2303 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | ||
| 2304 | HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT), | ||
| 2305 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 2306 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 2307 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 2308 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 2309 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 2310 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 2311 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 2312 | { } /* end */ | ||
| 2313 | }; | ||
| 2314 | |||
| 2315 | |||
| 2293 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { | 2316 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { |
| 2294 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2317 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
| 2295 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2318 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
| @@ -10359,7 +10382,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
| 10359 | .init_hook = alc_automute_amp, | 10382 | .init_hook = alc_automute_amp, |
| 10360 | }, | 10383 | }, |
| 10361 | [ALC888_ACER_ASPIRE_4930G] = { | 10384 | [ALC888_ACER_ASPIRE_4930G] = { |
| 10362 | .mixers = { alc888_base_mixer, | 10385 | .mixers = { alc888_acer_aspire_4930g_mixer, |
| 10363 | alc883_chmode_mixer }, | 10386 | alc883_chmode_mixer }, |
| 10364 | .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, | 10387 | .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, |
| 10365 | alc888_acer_aspire_4930g_verbs }, | 10388 | alc888_acer_aspire_4930g_verbs }, |
| @@ -18802,6 +18825,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
| 18802 | ALC662_3ST_6ch_DIG), | 18825 | ALC662_3ST_6ch_DIG), |
| 18803 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", | 18826 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", |
| 18804 | ALC663_ASUS_H13), | 18827 | ALC663_ASUS_H13), |
| 18828 | SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E), | ||
| 18805 | {} | 18829 | {} |
| 18806 | }; | 18830 | }; |
| 18807 | 18831 | ||
| @@ -19494,6 +19518,7 @@ static const struct alc_fixup alc662_fixups[] = { | |||
| 19494 | }; | 19518 | }; |
| 19495 | 19519 | ||
| 19496 | static struct snd_pci_quirk alc662_fixup_tbl[] = { | 19520 | static struct snd_pci_quirk alc662_fixup_tbl[] = { |
| 19521 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | ||
| 19497 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 19522 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
| 19498 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 19523 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
| 19499 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 19524 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index c2ae63d17cd..f53897a708b 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
| @@ -92,6 +92,8 @@ struct oxygen_model { | |||
| 92 | void (*update_dac_volume)(struct oxygen *chip); | 92 | void (*update_dac_volume)(struct oxygen *chip); |
| 93 | void (*update_dac_mute)(struct oxygen *chip); | 93 | void (*update_dac_mute)(struct oxygen *chip); |
| 94 | void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed); | 94 | void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed); |
| 95 | unsigned int (*adjust_dac_routing)(struct oxygen *chip, | ||
| 96 | unsigned int play_routing); | ||
| 95 | void (*gpio_changed)(struct oxygen *chip); | 97 | void (*gpio_changed)(struct oxygen *chip); |
| 96 | void (*uart_input)(struct oxygen *chip); | 98 | void (*uart_input)(struct oxygen *chip); |
| 97 | void (*ac97_switch)(struct oxygen *chip, | 99 | void (*ac97_switch)(struct oxygen *chip, |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 9bff14d5895..26c7e8bcb22 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
| @@ -180,6 +180,8 @@ void oxygen_update_dac_routing(struct oxygen *chip) | |||
| 180 | (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | | 180 | (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | |
| 181 | (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | | 181 | (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | |
| 182 | (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT); | 182 | (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT); |
| 183 | if (chip->model.adjust_dac_routing) | ||
| 184 | reg_value = chip->model.adjust_dac_routing(chip, reg_value); | ||
| 183 | oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value, | 185 | oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value, |
| 184 | OXYGEN_PLAY_DAC0_SOURCE_MASK | | 186 | OXYGEN_PLAY_DAC0_SOURCE_MASK | |
| 185 | OXYGEN_PLAY_DAC1_SOURCE_MASK | | 187 | OXYGEN_PLAY_DAC1_SOURCE_MASK | |
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c index e1fa602eba7..bc6eb58be38 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c | |||
| @@ -24,6 +24,11 @@ | |||
| 24 | * | 24 | * |
| 25 | * SPI 0 -> CS4245 | 25 | * SPI 0 -> CS4245 |
| 26 | * | 26 | * |
| 27 | * I²S 1 -> CS4245 | ||
| 28 | * I²S 2 -> CS4361 (center/LFE) | ||
| 29 | * I²S 3 -> CS4361 (surround) | ||
| 30 | * I²S 4 -> CS4361 (front) | ||
| 31 | * | ||
| 27 | * GPIO 3 <- ? | 32 | * GPIO 3 <- ? |
| 28 | * GPIO 4 <- headphone detect | 33 | * GPIO 4 <- headphone detect |
| 29 | * GPIO 5 -> route input jack to line-in (0) or mic-in (1) | 34 | * GPIO 5 -> route input jack to line-in (0) or mic-in (1) |
| @@ -36,6 +41,7 @@ | |||
| 36 | * input 1 <- aux | 41 | * input 1 <- aux |
| 37 | * input 2 <- front mic | 42 | * input 2 <- front mic |
| 38 | * input 4 <- line/mic | 43 | * input 4 <- line/mic |
| 44 | * DAC out -> headphones | ||
| 39 | * aux out -> front panel headphones | 45 | * aux out -> front panel headphones |
| 40 | */ | 46 | */ |
| 41 | 47 | ||
| @@ -207,6 +213,35 @@ static void set_cs4245_adc_params(struct oxygen *chip, | |||
| 207 | cs4245_write_cached(chip, CS4245_ADC_CTRL, value); | 213 | cs4245_write_cached(chip, CS4245_ADC_CTRL, value); |
| 208 | } | 214 | } |
| 209 | 215 | ||
| 216 | static inline unsigned int shift_bits(unsigned int value, | ||
| 217 | unsigned int shift_from, | ||
| 218 | unsigned int shift_to, | ||
| 219 | unsigned int mask) | ||
| 220 | { | ||
| 221 | if (shift_from < shift_to) | ||
| 222 | return (value << (shift_to - shift_from)) & mask; | ||
| 223 | else | ||
| 224 | return (value >> (shift_from - shift_to)) & mask; | ||
| 225 | } | ||
| 226 | |||
| 227 | static unsigned int adjust_dg_dac_routing(struct oxygen *chip, | ||
| 228 | unsigned int play_routing) | ||
| 229 | { | ||
| 230 | return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) | | ||
| 231 | shift_bits(play_routing, | ||
| 232 | OXYGEN_PLAY_DAC2_SOURCE_SHIFT, | ||
| 233 | OXYGEN_PLAY_DAC1_SOURCE_SHIFT, | ||
| 234 | OXYGEN_PLAY_DAC1_SOURCE_MASK) | | ||
| 235 | shift_bits(play_routing, | ||
| 236 | OXYGEN_PLAY_DAC1_SOURCE_SHIFT, | ||
| 237 | OXYGEN_PLAY_DAC2_SOURCE_SHIFT, | ||
| 238 | OXYGEN_PLAY_DAC2_SOURCE_MASK) | | ||
| 239 | shift_bits(play_routing, | ||
| 240 | OXYGEN_PLAY_DAC0_SOURCE_SHIFT, | ||
| 241 | OXYGEN_PLAY_DAC3_SOURCE_SHIFT, | ||
| 242 | OXYGEN_PLAY_DAC3_SOURCE_MASK); | ||
| 243 | } | ||
| 244 | |||
| 210 | static int output_switch_info(struct snd_kcontrol *ctl, | 245 | static int output_switch_info(struct snd_kcontrol *ctl, |
| 211 | struct snd_ctl_elem_info *info) | 246 | struct snd_ctl_elem_info *info) |
| 212 | { | 247 | { |
| @@ -557,6 +592,7 @@ struct oxygen_model model_xonar_dg = { | |||
| 557 | .resume = dg_resume, | 592 | .resume = dg_resume, |
| 558 | .set_dac_params = set_cs4245_dac_params, | 593 | .set_dac_params = set_cs4245_dac_params, |
| 559 | .set_adc_params = set_cs4245_adc_params, | 594 | .set_adc_params = set_cs4245_adc_params, |
| 595 | .adjust_dac_routing = adjust_dg_dac_routing, | ||
| 560 | .dump_registers = dump_cs4245_registers, | 596 | .dump_registers = dump_cs4245_registers, |
| 561 | .model_data_size = sizeof(struct dg), | 597 | .model_data_size = sizeof(struct dg), |
| 562 | .device_config = PLAYBACK_0_TO_I2S | | 598 | .device_config = PLAYBACK_0_TO_I2S | |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h index bd26e092aea..6ce9ad70029 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define __PDAUDIOCF_H | 22 | #define __PDAUDIOCF_H |
| 23 | 23 | ||
| 24 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
| 25 | #include <asm/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <pcmcia/cistpl.h> | 27 | #include <pcmcia/cistpl.h> |
| 28 | #include <pcmcia/ds.h> | 28 | #include <pcmcia/ds.h> |
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c index 989e04abb52..fe33e122e37 100644 --- a/sound/pcmcia/vx/vxp_ops.c +++ b/sound/pcmcia/vx/vxp_ops.c | |||
| @@ -23,8 +23,8 @@ | |||
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
| 25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
| 26 | #include <linux/io.h> | ||
| 26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
| 27 | #include <asm/io.h> | ||
| 28 | #include "vxpocket.h" | 28 | #include "vxpocket.h" |
| 29 | 29 | ||
| 30 | 30 | ||
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 46dbfd067f7..347a567b01e 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
| @@ -153,7 +153,7 @@ static int cq93vc_resume(struct snd_soc_codec *codec) | |||
| 153 | 153 | ||
| 154 | static int cq93vc_probe(struct snd_soc_codec *codec) | 154 | static int cq93vc_probe(struct snd_soc_codec *codec) |
| 155 | { | 155 | { |
| 156 | struct davinci_vc *davinci_vc = codec->dev->platform_data; | 156 | struct davinci_vc *davinci_vc = snd_soc_codec_get_drvdata(codec); |
| 157 | 157 | ||
| 158 | davinci_vc->cq93vc.codec = codec; | 158 | davinci_vc->cq93vc.codec = codec; |
| 159 | codec->control_data = davinci_vc; | 159 | codec->control_data = davinci_vc; |
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 03d1e860d22..bb4bf65b9e7 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
| @@ -367,9 +367,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) | |||
| 367 | return 0; | 367 | return 0; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | static const u8 cx20442_reg = CX20442_TELOUT | CX20442_MIC; | ||
| 371 | |||
| 370 | static struct snd_soc_codec_driver cx20442_codec_dev = { | 372 | static struct snd_soc_codec_driver cx20442_codec_dev = { |
| 371 | .probe = cx20442_codec_probe, | 373 | .probe = cx20442_codec_probe, |
| 372 | .remove = cx20442_codec_remove, | 374 | .remove = cx20442_codec_remove, |
| 375 | .reg_cache_default = &cx20442_reg, | ||
| 373 | .reg_cache_size = 1, | 376 | .reg_cache_size = 1, |
| 374 | .reg_word_size = sizeof(u8), | 377 | .reg_word_size = sizeof(u8), |
| 375 | .read = cx20442_read_reg_cache, | 378 | .read = cx20442_read_reg_cache, |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3351f77607b..37b8aa8a680 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -1287,9 +1287,9 @@ SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), | |||
| 1287 | SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), | 1287 | SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), |
| 1288 | SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), | 1288 | SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), |
| 1289 | 1289 | ||
| 1290 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", | 1290 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, |
| 1291 | 0, WM8994_POWER_MANAGEMENT_4, 9, 0), | 1291 | 0, WM8994_POWER_MANAGEMENT_4, 9, 0), |
| 1292 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", | 1292 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, |
| 1293 | 0, WM8994_POWER_MANAGEMENT_4, 8, 0), | 1293 | 0, WM8994_POWER_MANAGEMENT_4, 8, 0), |
| 1294 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, | 1294 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, |
| 1295 | WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, | 1295 | WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, |
| @@ -1298,9 +1298,9 @@ SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, | |||
| 1298 | WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, | 1298 | WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, |
| 1299 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 1299 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), |
| 1300 | 1300 | ||
| 1301 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", | 1301 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL, |
| 1302 | 0, WM8994_POWER_MANAGEMENT_4, 11, 0), | 1302 | 0, WM8994_POWER_MANAGEMENT_4, 11, 0), |
| 1303 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", | 1303 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL, |
| 1304 | 0, WM8994_POWER_MANAGEMENT_4, 10, 0), | 1304 | 0, WM8994_POWER_MANAGEMENT_4, 10, 0), |
| 1305 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, | 1305 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, |
| 1306 | WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, | 1306 | WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, |
| @@ -1345,6 +1345,7 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, | |||
| 1345 | 1345 | ||
| 1346 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | 1346 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), |
| 1347 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | 1347 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), |
| 1348 | SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1348 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | 1349 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), |
| 1349 | 1350 | ||
| 1350 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), | 1351 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), |
| @@ -1546,6 +1547,11 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
| 1546 | { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, | 1547 | { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, |
| 1547 | { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, | 1548 | { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, |
| 1548 | 1549 | ||
| 1550 | { "AIF1ADCDAT", NULL, "AIF1ADC1L" }, | ||
| 1551 | { "AIF1ADCDAT", NULL, "AIF1ADC1R" }, | ||
| 1552 | { "AIF1ADCDAT", NULL, "AIF1ADC2L" }, | ||
| 1553 | { "AIF1ADCDAT", NULL, "AIF1ADC2R" }, | ||
| 1554 | |||
| 1549 | { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, | 1555 | { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, |
| 1550 | 1556 | ||
| 1551 | /* AIF3 output */ | 1557 | /* AIF3 output */ |
| @@ -1578,6 +1584,13 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
| 1578 | { "Right Headphone Mux", "DAC", "DAC1R" }, | 1584 | { "Right Headphone Mux", "DAC", "DAC1R" }, |
| 1579 | }; | 1585 | }; |
| 1580 | 1586 | ||
| 1587 | static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { | ||
| 1588 | { "AIF1DACDAT", NULL, "AIF2DACDAT" }, | ||
| 1589 | { "AIF2DACDAT", NULL, "AIF1DACDAT" }, | ||
| 1590 | { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, | ||
| 1591 | { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, | ||
| 1592 | }; | ||
| 1593 | |||
| 1581 | static const struct snd_soc_dapm_route wm8994_intercon[] = { | 1594 | static const struct snd_soc_dapm_route wm8994_intercon[] = { |
| 1582 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, | 1595 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, |
| 1583 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, | 1596 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, |
| @@ -3129,6 +3142,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3129 | case WM8994: | 3142 | case WM8994: |
| 3130 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 3143 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
| 3131 | ARRAY_SIZE(wm8994_intercon)); | 3144 | ARRAY_SIZE(wm8994_intercon)); |
| 3145 | |||
| 3146 | if (wm8994->revision < 4) | ||
| 3147 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | ||
| 3148 | ARRAY_SIZE(wm8994_revd_intercon)); | ||
| 3149 | |||
| 3132 | break; | 3150 | break; |
| 3133 | case WM8958: | 3151 | case WM8958: |
| 3134 | snd_soc_dapm_add_routes(dapm, wm8958_intercon, | 3152 | snd_soc_dapm_add_routes(dapm, wm8958_intercon, |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index b36f0b39b09..fe7984221eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
| @@ -218,7 +218,19 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = { | |||
| 218 | .ops = &evm_spdif_ops, | 218 | .ops = &evm_spdif_ops, |
| 219 | }, | 219 | }, |
| 220 | }; | 220 | }; |
| 221 | static struct snd_soc_dai_link da8xx_evm_dai = { | 221 | |
| 222 | static struct snd_soc_dai_link da830_evm_dai = { | ||
| 223 | .name = "TLV320AIC3X", | ||
| 224 | .stream_name = "AIC3X", | ||
| 225 | .cpu_dai_name = "davinci-mcasp.1", | ||
| 226 | .codec_dai_name = "tlv320aic3x-hifi", | ||
| 227 | .codec_name = "tlv320aic3x-codec.1-0018", | ||
| 228 | .platform_name = "davinci-pcm-audio", | ||
| 229 | .init = evm_aic3x_init, | ||
| 230 | .ops = &evm_ops, | ||
| 231 | }; | ||
| 232 | |||
| 233 | static struct snd_soc_dai_link da850_evm_dai = { | ||
| 222 | .name = "TLV320AIC3X", | 234 | .name = "TLV320AIC3X", |
| 223 | .stream_name = "AIC3X", | 235 | .stream_name = "AIC3X", |
| 224 | .cpu_dai_name= "davinci-mcasp.0", | 236 | .cpu_dai_name= "davinci-mcasp.0", |
| @@ -259,13 +271,13 @@ static struct snd_soc_card dm6467_snd_soc_card_evm = { | |||
| 259 | 271 | ||
| 260 | static struct snd_soc_card da830_snd_soc_card = { | 272 | static struct snd_soc_card da830_snd_soc_card = { |
| 261 | .name = "DA830/OMAP-L137 EVM", | 273 | .name = "DA830/OMAP-L137 EVM", |
| 262 | .dai_link = &da8xx_evm_dai, | 274 | .dai_link = &da830_evm_dai, |
| 263 | .num_links = 1, | 275 | .num_links = 1, |
| 264 | }; | 276 | }; |
| 265 | 277 | ||
| 266 | static struct snd_soc_card da850_snd_soc_card = { | 278 | static struct snd_soc_card da850_snd_soc_card = { |
| 267 | .name = "DA850/OMAP-L138 EVM", | 279 | .name = "DA850/OMAP-L138 EVM", |
| 268 | .dai_link = &da8xx_evm_dai, | 280 | .dai_link = &da850_evm_dai, |
| 269 | .num_links = 1, | 281 | .num_links = 1, |
| 270 | }; | 282 | }; |
| 271 | 283 | ||
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 2101bdcee21..3167be68962 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
| @@ -507,8 +507,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
| 507 | /* Set up digital mute if not provided by the codec */ | 507 | /* Set up digital mute if not provided by the codec */ |
| 508 | if (!codec_dai->driver->ops) { | 508 | if (!codec_dai->driver->ops) { |
| 509 | codec_dai->driver->ops = &ams_delta_dai_ops; | 509 | codec_dai->driver->ops = &ams_delta_dai_ops; |
| 510 | } else if (!codec_dai->driver->ops->digital_mute) { | ||
| 511 | codec_dai->driver->ops->digital_mute = ams_delta_digital_mute; | ||
| 512 | } else { | 510 | } else { |
| 513 | ams_delta_ops.startup = ams_delta_startup; | 511 | ams_delta_ops.startup = ams_delta_startup; |
| 514 | ams_delta_ops.shutdown = ams_delta_shutdown; | 512 | ams_delta_ops.shutdown = ams_delta_shutdown; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bac7291b6ff..c3f6f1e7279 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -1449,6 +1449,7 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
| 1449 | rtd = &card->rtd_aux[num]; | 1449 | rtd = &card->rtd_aux[num]; |
| 1450 | name = aux_dev->name; | 1450 | name = aux_dev->name; |
| 1451 | } | 1451 | } |
| 1452 | rtd->card = card; | ||
| 1452 | 1453 | ||
| 1453 | /* machine controls, routes and widgets are not prefixed */ | 1454 | /* machine controls, routes and widgets are not prefixed */ |
| 1454 | temp = codec->name_prefix; | 1455 | temp = codec->name_prefix; |
| @@ -1471,7 +1472,6 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
| 1471 | 1472 | ||
| 1472 | /* register the rtd device */ | 1473 | /* register the rtd device */ |
| 1473 | rtd->codec = codec; | 1474 | rtd->codec = codec; |
| 1474 | rtd->card = card; | ||
| 1475 | rtd->dev.parent = card->dev; | 1475 | rtd->dev.parent = card->dev; |
| 1476 | rtd->dev.release = rtd_release; | 1476 | rtd->dev.release = rtd_release; |
| 1477 | rtd->dev.init_name = name; | 1477 | rtd->dev.init_name = name; |
| @@ -1664,9 +1664,6 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | |||
| 1664 | goto out; | 1664 | goto out; |
| 1665 | 1665 | ||
| 1666 | found: | 1666 | found: |
| 1667 | if (!try_module_get(codec->dev->driver->owner)) | ||
| 1668 | return -ENODEV; | ||
| 1669 | |||
| 1670 | ret = soc_probe_codec(card, codec); | 1667 | ret = soc_probe_codec(card, codec); |
| 1671 | if (ret < 0) | 1668 | if (ret < 0) |
| 1672 | return ret; | 1669 | return ret; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 499730ab563..8194f150bab 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -1742,7 +1742,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 1742 | int max = mc->max; | 1742 | int max = mc->max; |
| 1743 | unsigned int mask = (1 << fls(max)) - 1; | 1743 | unsigned int mask = (1 << fls(max)) - 1; |
| 1744 | unsigned int invert = mc->invert; | 1744 | unsigned int invert = mc->invert; |
| 1745 | unsigned int val, val_mask; | 1745 | unsigned int val; |
| 1746 | int connect, change; | 1746 | int connect, change; |
| 1747 | struct snd_soc_dapm_update update; | 1747 | struct snd_soc_dapm_update update; |
| 1748 | 1748 | ||
| @@ -1750,13 +1750,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 1750 | 1750 | ||
| 1751 | if (invert) | 1751 | if (invert) |
| 1752 | val = max - val; | 1752 | val = max - val; |
| 1753 | val_mask = mask << shift; | 1753 | mask = mask << shift; |
| 1754 | val = val << shift; | 1754 | val = val << shift; |
| 1755 | 1755 | ||
| 1756 | mutex_lock(&widget->codec->mutex); | 1756 | mutex_lock(&widget->codec->mutex); |
| 1757 | widget->value = val; | 1757 | widget->value = val; |
| 1758 | 1758 | ||
| 1759 | change = snd_soc_test_bits(widget->codec, reg, val_mask, val); | 1759 | change = snd_soc_test_bits(widget->codec, reg, mask, val); |
| 1760 | if (change) { | 1760 | if (change) { |
| 1761 | if (val) | 1761 | if (val) |
| 1762 | /* new connection */ | 1762 | /* new connection */ |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 7df89b3d7de..85af6051b52 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -95,7 +95,7 @@ enum { | |||
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | /*E-mu 0202(0404) eXtension Unit(XU) control*/ | 98 | /*E-mu 0202/0404/0204 eXtension Unit(XU) control*/ |
| 99 | enum { | 99 | enum { |
| 100 | USB_XU_CLOCK_RATE = 0xe301, | 100 | USB_XU_CLOCK_RATE = 0xe301, |
| 101 | USB_XU_CLOCK_SOURCE = 0xe302, | 101 | USB_XU_CLOCK_SOURCE = 0xe302, |
| @@ -1566,7 +1566,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
| 1566 | cval->initialized = 1; | 1566 | cval->initialized = 1; |
| 1567 | } else { | 1567 | } else { |
| 1568 | if (type == USB_XU_CLOCK_RATE) { | 1568 | if (type == USB_XU_CLOCK_RATE) { |
| 1569 | /* E-Mu USB 0404/0202/TrackerPre | 1569 | /* E-Mu USB 0404/0202/TrackerPre/0204 |
| 1570 | * samplerate control quirk | 1570 | * samplerate control quirk |
| 1571 | */ | 1571 | */ |
| 1572 | cval->min = 0; | 1572 | cval->min = 0; |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 35999874d30..921a86fd988 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -79,6 +79,13 @@ | |||
| 79 | .idProduct = 0x3f0a, | 79 | .idProduct = 0x3f0a, |
| 80 | .bInterfaceClass = USB_CLASS_AUDIO, | 80 | .bInterfaceClass = USB_CLASS_AUDIO, |
| 81 | }, | 81 | }, |
| 82 | { | ||
| 83 | /* E-Mu 0204 USB */ | ||
| 84 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
| 85 | .idVendor = 0x041e, | ||
| 86 | .idProduct = 0x3f19, | ||
| 87 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
| 88 | }, | ||
| 82 | 89 | ||
| 83 | /* | 90 | /* |
| 84 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface | 91 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index cf8bf088394..e314cdb8500 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
| @@ -532,7 +532,7 @@ int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat | |||
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | /* | 534 | /* |
| 535 | * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device, | 535 | * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device, |
| 536 | * not for interface. | 536 | * not for interface. |
| 537 | */ | 537 | */ |
| 538 | 538 | ||
| @@ -589,6 +589,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | |||
| 589 | case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ | 589 | case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ |
| 590 | case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ | 590 | case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ |
| 591 | case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */ | 591 | case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */ |
| 592 | case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */ | ||
| 592 | set_format_emu_quirk(subs, fmt); | 593 | set_format_emu_quirk(subs, fmt); |
| 593 | break; | 594 | break; |
| 594 | } | 595 | } |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b2f729fdb31..60cac6f92e8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -759,8 +759,8 @@ static int __cmd_record(int argc, const char **argv) | |||
| 759 | perf_session__process_machines(session, event__synthesize_guest_os); | 759 | perf_session__process_machines(session, event__synthesize_guest_os); |
| 760 | 760 | ||
| 761 | if (!system_wide) | 761 | if (!system_wide) |
| 762 | event__synthesize_thread(target_tid, process_synthesized_event, | 762 | event__synthesize_thread_map(threads, process_synthesized_event, |
| 763 | session); | 763 | session); |
| 764 | else | 764 | else |
| 765 | event__synthesize_threads(process_synthesized_event, session); | 765 | event__synthesize_threads(process_synthesized_event, session); |
| 766 | 766 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b6998e05576..5a29d9cd948 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -1306,7 +1306,7 @@ static int __cmd_top(void) | |||
| 1306 | return -ENOMEM; | 1306 | return -ENOMEM; |
| 1307 | 1307 | ||
| 1308 | if (target_tid != -1) | 1308 | if (target_tid != -1) |
| 1309 | event__synthesize_thread(target_tid, event__process, session); | 1309 | event__synthesize_thread_map(threads, event__process, session); |
| 1310 | else | 1310 | else |
| 1311 | event__synthesize_threads(event__process, session); | 1311 | event__synthesize_threads(event__process, session); |
| 1312 | 1312 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1478ab4ee22..50d0a931497 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -263,11 +263,12 @@ static int __event__synthesize_thread(event_t *comm_event, event_t *mmap_event, | |||
| 263 | process, session); | 263 | process, session); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | int event__synthesize_thread(pid_t pid, event__handler_t process, | 266 | int event__synthesize_thread_map(struct thread_map *threads, |
| 267 | struct perf_session *session) | 267 | event__handler_t process, |
| 268 | struct perf_session *session) | ||
| 268 | { | 269 | { |
| 269 | event_t *comm_event, *mmap_event; | 270 | event_t *comm_event, *mmap_event; |
| 270 | int err = -1; | 271 | int err = -1, thread; |
| 271 | 272 | ||
| 272 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 273 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); |
| 273 | if (comm_event == NULL) | 274 | if (comm_event == NULL) |
| @@ -277,8 +278,15 @@ int event__synthesize_thread(pid_t pid, event__handler_t process, | |||
| 277 | if (mmap_event == NULL) | 278 | if (mmap_event == NULL) |
| 278 | goto out_free_comm; | 279 | goto out_free_comm; |
| 279 | 280 | ||
| 280 | err = __event__synthesize_thread(comm_event, mmap_event, pid, | 281 | err = 0; |
| 281 | process, session); | 282 | for (thread = 0; thread < threads->nr; ++thread) { |
| 283 | if (__event__synthesize_thread(comm_event, mmap_event, | ||
| 284 | threads->map[thread], | ||
| 285 | process, session)) { | ||
| 286 | err = -1; | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | } | ||
| 282 | free(mmap_event); | 290 | free(mmap_event); |
| 283 | out_free_comm: | 291 | out_free_comm: |
| 284 | free(comm_event); | 292 | free(comm_event); |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 2b7e91902f1..cc7b52f9b49 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -135,14 +135,16 @@ typedef union event_union { | |||
| 135 | void event__print_totals(void); | 135 | void event__print_totals(void); |
| 136 | 136 | ||
| 137 | struct perf_session; | 137 | struct perf_session; |
| 138 | struct thread_map; | ||
| 138 | 139 | ||
| 139 | typedef int (*event__handler_synth_t)(event_t *event, | 140 | typedef int (*event__handler_synth_t)(event_t *event, |
| 140 | struct perf_session *session); | 141 | struct perf_session *session); |
| 141 | typedef int (*event__handler_t)(event_t *event, struct sample_data *sample, | 142 | typedef int (*event__handler_t)(event_t *event, struct sample_data *sample, |
| 142 | struct perf_session *session); | 143 | struct perf_session *session); |
| 143 | 144 | ||
| 144 | int event__synthesize_thread(pid_t pid, event__handler_t process, | 145 | int event__synthesize_thread_map(struct thread_map *threads, |
| 145 | struct perf_session *session); | 146 | event__handler_t process, |
| 147 | struct perf_session *session); | ||
| 146 | int event__synthesize_threads(event__handler_t process, | 148 | int event__synthesize_threads(event__handler_t process, |
| 147 | struct perf_session *session); | 149 | struct perf_session *session); |
| 148 | int event__synthesize_kernel_mmap(event__handler_t process, | 150 | int event__synthesize_kernel_mmap(event__handler_t process, |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f5cfed60af9..d8575d31ee6 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -90,7 +90,7 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
| 90 | int cpu, thread; | 90 | int cpu, thread; |
| 91 | struct perf_counts_values *aggr = &evsel->counts->aggr, count; | 91 | struct perf_counts_values *aggr = &evsel->counts->aggr, count; |
| 92 | 92 | ||
| 93 | aggr->val = 0; | 93 | aggr->val = aggr->ena = aggr->run = 0; |
| 94 | 94 | ||
| 95 | for (cpu = 0; cpu < ncpus; cpu++) { | 95 | for (cpu = 0; cpu < ncpus; cpu++) { |
| 96 | for (thread = 0; thread < nthreads; thread++) { | 96 | for (thread = 0; thread < nthreads; thread++) { |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 4c6983de6fd..362a0cb448d 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -72,7 +72,7 @@ int need_reinitialize; | |||
| 72 | 72 | ||
| 73 | int num_cpus; | 73 | int num_cpus; |
| 74 | 74 | ||
| 75 | typedef struct per_cpu_counters { | 75 | struct counters { |
| 76 | unsigned long long tsc; /* per thread */ | 76 | unsigned long long tsc; /* per thread */ |
| 77 | unsigned long long aperf; /* per thread */ | 77 | unsigned long long aperf; /* per thread */ |
| 78 | unsigned long long mperf; /* per thread */ | 78 | unsigned long long mperf; /* per thread */ |
| @@ -88,13 +88,13 @@ typedef struct per_cpu_counters { | |||
| 88 | int pkg; | 88 | int pkg; |
| 89 | int core; | 89 | int core; |
| 90 | int cpu; | 90 | int cpu; |
| 91 | struct per_cpu_counters *next; | 91 | struct counters *next; |
| 92 | } PCC; | 92 | }; |
| 93 | 93 | ||
| 94 | PCC *pcc_even; | 94 | struct counters *cnt_even; |
| 95 | PCC *pcc_odd; | 95 | struct counters *cnt_odd; |
| 96 | PCC *pcc_delta; | 96 | struct counters *cnt_delta; |
| 97 | PCC *pcc_average; | 97 | struct counters *cnt_average; |
| 98 | struct timeval tv_even; | 98 | struct timeval tv_even; |
| 99 | struct timeval tv_odd; | 99 | struct timeval tv_odd; |
| 100 | struct timeval tv_delta; | 100 | struct timeval tv_delta; |
| @@ -125,7 +125,7 @@ unsigned long long get_msr(int cpu, off_t offset) | |||
| 125 | return msr; | 125 | return msr; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void print_header() | 128 | void print_header(void) |
| 129 | { | 129 | { |
| 130 | if (show_pkg) | 130 | if (show_pkg) |
| 131 | fprintf(stderr, "pkg "); | 131 | fprintf(stderr, "pkg "); |
| @@ -160,39 +160,39 @@ void print_header() | |||
| 160 | putc('\n', stderr); | 160 | putc('\n', stderr); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | void dump_pcc(PCC *pcc) | 163 | void dump_cnt(struct counters *cnt) |
| 164 | { | 164 | { |
| 165 | fprintf(stderr, "package: %d ", pcc->pkg); | 165 | fprintf(stderr, "package: %d ", cnt->pkg); |
| 166 | fprintf(stderr, "core:: %d ", pcc->core); | 166 | fprintf(stderr, "core:: %d ", cnt->core); |
| 167 | fprintf(stderr, "CPU: %d ", pcc->cpu); | 167 | fprintf(stderr, "CPU: %d ", cnt->cpu); |
| 168 | fprintf(stderr, "TSC: %016llX\n", pcc->tsc); | 168 | fprintf(stderr, "TSC: %016llX\n", cnt->tsc); |
| 169 | fprintf(stderr, "c3: %016llX\n", pcc->c3); | 169 | fprintf(stderr, "c3: %016llX\n", cnt->c3); |
| 170 | fprintf(stderr, "c6: %016llX\n", pcc->c6); | 170 | fprintf(stderr, "c6: %016llX\n", cnt->c6); |
| 171 | fprintf(stderr, "c7: %016llX\n", pcc->c7); | 171 | fprintf(stderr, "c7: %016llX\n", cnt->c7); |
| 172 | fprintf(stderr, "aperf: %016llX\n", pcc->aperf); | 172 | fprintf(stderr, "aperf: %016llX\n", cnt->aperf); |
| 173 | fprintf(stderr, "pc2: %016llX\n", pcc->pc2); | 173 | fprintf(stderr, "pc2: %016llX\n", cnt->pc2); |
| 174 | fprintf(stderr, "pc3: %016llX\n", pcc->pc3); | 174 | fprintf(stderr, "pc3: %016llX\n", cnt->pc3); |
| 175 | fprintf(stderr, "pc6: %016llX\n", pcc->pc6); | 175 | fprintf(stderr, "pc6: %016llX\n", cnt->pc6); |
| 176 | fprintf(stderr, "pc7: %016llX\n", pcc->pc7); | 176 | fprintf(stderr, "pc7: %016llX\n", cnt->pc7); |
| 177 | fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, pcc->extra_msr); | 177 | fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, cnt->extra_msr); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | void dump_list(PCC *pcc) | 180 | void dump_list(struct counters *cnt) |
| 181 | { | 181 | { |
| 182 | printf("dump_list 0x%p\n", pcc); | 182 | printf("dump_list 0x%p\n", cnt); |
| 183 | 183 | ||
| 184 | for (; pcc; pcc = pcc->next) | 184 | for (; cnt; cnt = cnt->next) |
| 185 | dump_pcc(pcc); | 185 | dump_cnt(cnt); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | void print_pcc(PCC *p) | 188 | void print_cnt(struct counters *p) |
| 189 | { | 189 | { |
| 190 | double interval_float; | 190 | double interval_float; |
| 191 | 191 | ||
| 192 | interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; | 192 | interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; |
| 193 | 193 | ||
| 194 | /* topology columns, print blanks on 1st (average) line */ | 194 | /* topology columns, print blanks on 1st (average) line */ |
| 195 | if (p == pcc_average) { | 195 | if (p == cnt_average) { |
| 196 | if (show_pkg) | 196 | if (show_pkg) |
| 197 | fprintf(stderr, " "); | 197 | fprintf(stderr, " "); |
| 198 | if (show_core) | 198 | if (show_core) |
| @@ -262,24 +262,24 @@ void print_pcc(PCC *p) | |||
| 262 | putc('\n', stderr); | 262 | putc('\n', stderr); |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | void print_counters(PCC *cnt) | 265 | void print_counters(struct counters *counters) |
| 266 | { | 266 | { |
| 267 | PCC *pcc; | 267 | struct counters *cnt; |
| 268 | 268 | ||
| 269 | print_header(); | 269 | print_header(); |
| 270 | 270 | ||
| 271 | if (num_cpus > 1) | 271 | if (num_cpus > 1) |
| 272 | print_pcc(pcc_average); | 272 | print_cnt(cnt_average); |
| 273 | 273 | ||
| 274 | for (pcc = cnt; pcc != NULL; pcc = pcc->next) | 274 | for (cnt = counters; cnt != NULL; cnt = cnt->next) |
| 275 | print_pcc(pcc); | 275 | print_cnt(cnt); |
| 276 | 276 | ||
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | #define SUBTRACT_COUNTER(after, before, delta) (delta = (after - before), (before > after)) | 279 | #define SUBTRACT_COUNTER(after, before, delta) (delta = (after - before), (before > after)) |
| 280 | 280 | ||
| 281 | 281 | int compute_delta(struct counters *after, | |
| 282 | int compute_delta(PCC *after, PCC *before, PCC *delta) | 282 | struct counters *before, struct counters *delta) |
| 283 | { | 283 | { |
| 284 | int errors = 0; | 284 | int errors = 0; |
| 285 | int perf_err = 0; | 285 | int perf_err = 0; |
| @@ -391,20 +391,20 @@ int compute_delta(PCC *after, PCC *before, PCC *delta) | |||
| 391 | delta->extra_msr = after->extra_msr; | 391 | delta->extra_msr = after->extra_msr; |
| 392 | if (errors) { | 392 | if (errors) { |
| 393 | fprintf(stderr, "ERROR cpu%d before:\n", before->cpu); | 393 | fprintf(stderr, "ERROR cpu%d before:\n", before->cpu); |
| 394 | dump_pcc(before); | 394 | dump_cnt(before); |
| 395 | fprintf(stderr, "ERROR cpu%d after:\n", before->cpu); | 395 | fprintf(stderr, "ERROR cpu%d after:\n", before->cpu); |
| 396 | dump_pcc(after); | 396 | dump_cnt(after); |
| 397 | errors = 0; | 397 | errors = 0; |
| 398 | } | 398 | } |
| 399 | } | 399 | } |
| 400 | return 0; | 400 | return 0; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | void compute_average(PCC *delta, PCC *avg) | 403 | void compute_average(struct counters *delta, struct counters *avg) |
| 404 | { | 404 | { |
| 405 | PCC *sum; | 405 | struct counters *sum; |
| 406 | 406 | ||
| 407 | sum = calloc(1, sizeof(PCC)); | 407 | sum = calloc(1, sizeof(struct counters)); |
| 408 | if (sum == NULL) { | 408 | if (sum == NULL) { |
| 409 | perror("calloc sum"); | 409 | perror("calloc sum"); |
| 410 | exit(1); | 410 | exit(1); |
| @@ -438,35 +438,34 @@ void compute_average(PCC *delta, PCC *avg) | |||
| 438 | free(sum); | 438 | free(sum); |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | void get_counters(PCC *pcc) | 441 | void get_counters(struct counters *cnt) |
| 442 | { | 442 | { |
| 443 | for ( ; pcc; pcc = pcc->next) { | 443 | for ( ; cnt; cnt = cnt->next) { |
| 444 | pcc->tsc = get_msr(pcc->cpu, MSR_TSC); | 444 | cnt->tsc = get_msr(cnt->cpu, MSR_TSC); |
| 445 | if (do_nhm_cstates) | 445 | if (do_nhm_cstates) |
| 446 | pcc->c3 = get_msr(pcc->cpu, MSR_CORE_C3_RESIDENCY); | 446 | cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); |
| 447 | if (do_nhm_cstates) | 447 | if (do_nhm_cstates) |
| 448 | pcc->c6 = get_msr(pcc->cpu, MSR_CORE_C6_RESIDENCY); | 448 | cnt->c6 = get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY); |
| 449 | if (do_snb_cstates) | 449 | if (do_snb_cstates) |
| 450 | pcc->c7 = get_msr(pcc->cpu, MSR_CORE_C7_RESIDENCY); | 450 | cnt->c7 = get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY); |
| 451 | if (has_aperf) | 451 | if (has_aperf) |
| 452 | pcc->aperf = get_msr(pcc->cpu, MSR_APERF); | 452 | cnt->aperf = get_msr(cnt->cpu, MSR_APERF); |
| 453 | if (has_aperf) | 453 | if (has_aperf) |
| 454 | pcc->mperf = get_msr(pcc->cpu, MSR_MPERF); | 454 | cnt->mperf = get_msr(cnt->cpu, MSR_MPERF); |
| 455 | if (do_snb_cstates) | 455 | if (do_snb_cstates) |
| 456 | pcc->pc2 = get_msr(pcc->cpu, MSR_PKG_C2_RESIDENCY); | 456 | cnt->pc2 = get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY); |
| 457 | if (do_nhm_cstates) | 457 | if (do_nhm_cstates) |
| 458 | pcc->pc3 = get_msr(pcc->cpu, MSR_PKG_C3_RESIDENCY); | 458 | cnt->pc3 = get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY); |
| 459 | if (do_nhm_cstates) | 459 | if (do_nhm_cstates) |
| 460 | pcc->pc6 = get_msr(pcc->cpu, MSR_PKG_C6_RESIDENCY); | 460 | cnt->pc6 = get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY); |
| 461 | if (do_snb_cstates) | 461 | if (do_snb_cstates) |
| 462 | pcc->pc7 = get_msr(pcc->cpu, MSR_PKG_C7_RESIDENCY); | 462 | cnt->pc7 = get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY); |
| 463 | if (extra_msr_offset) | 463 | if (extra_msr_offset) |
| 464 | pcc->extra_msr = get_msr(pcc->cpu, extra_msr_offset); | 464 | cnt->extra_msr = get_msr(cnt->cpu, extra_msr_offset); |
| 465 | } | 465 | } |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | 468 | void print_nehalem_info(void) | |
| 469 | void print_nehalem_info() | ||
| 470 | { | 469 | { |
| 471 | unsigned long long msr; | 470 | unsigned long long msr; |
| 472 | unsigned int ratio; | 471 | unsigned int ratio; |
| @@ -514,38 +513,38 @@ void print_nehalem_info() | |||
| 514 | 513 | ||
| 515 | } | 514 | } |
| 516 | 515 | ||
| 517 | void free_counter_list(PCC *list) | 516 | void free_counter_list(struct counters *list) |
| 518 | { | 517 | { |
| 519 | PCC *p; | 518 | struct counters *p; |
| 520 | 519 | ||
| 521 | for (p = list; p; ) { | 520 | for (p = list; p; ) { |
| 522 | PCC *free_me; | 521 | struct counters *free_me; |
| 523 | 522 | ||
| 524 | free_me = p; | 523 | free_me = p; |
| 525 | p = p->next; | 524 | p = p->next; |
| 526 | free(free_me); | 525 | free(free_me); |
| 527 | } | 526 | } |
| 528 | return; | ||
| 529 | } | 527 | } |
| 530 | 528 | ||
| 531 | void free_all_counters(void) | 529 | void free_all_counters(void) |
| 532 | { | 530 | { |
| 533 | free_counter_list(pcc_even); | 531 | free_counter_list(cnt_even); |
| 534 | pcc_even = NULL; | 532 | cnt_even = NULL; |
| 535 | 533 | ||
| 536 | free_counter_list(pcc_odd); | 534 | free_counter_list(cnt_odd); |
| 537 | pcc_odd = NULL; | 535 | cnt_odd = NULL; |
| 538 | 536 | ||
| 539 | free_counter_list(pcc_delta); | 537 | free_counter_list(cnt_delta); |
| 540 | pcc_delta = NULL; | 538 | cnt_delta = NULL; |
| 541 | 539 | ||
| 542 | free_counter_list(pcc_average); | 540 | free_counter_list(cnt_average); |
| 543 | pcc_average = NULL; | 541 | cnt_average = NULL; |
| 544 | } | 542 | } |
| 545 | 543 | ||
| 546 | void insert_cpu_counters(PCC **list, PCC *new) | 544 | void insert_counters(struct counters **list, |
| 545 | struct counters *new) | ||
| 547 | { | 546 | { |
| 548 | PCC *prev; | 547 | struct counters *prev; |
| 549 | 548 | ||
| 550 | /* | 549 | /* |
| 551 | * list was empty | 550 | * list was empty |
| @@ -594,18 +593,16 @@ void insert_cpu_counters(PCC **list, PCC *new) | |||
| 594 | */ | 593 | */ |
| 595 | new->next = prev->next; | 594 | new->next = prev->next; |
| 596 | prev->next = new; | 595 | prev->next = new; |
| 597 | |||
| 598 | return; | ||
| 599 | } | 596 | } |
| 600 | 597 | ||
| 601 | void alloc_new_cpu_counters(int pkg, int core, int cpu) | 598 | void alloc_new_counters(int pkg, int core, int cpu) |
| 602 | { | 599 | { |
| 603 | PCC *new; | 600 | struct counters *new; |
| 604 | 601 | ||
| 605 | if (verbose > 1) | 602 | if (verbose > 1) |
| 606 | printf("pkg%d core%d, cpu%d\n", pkg, core, cpu); | 603 | printf("pkg%d core%d, cpu%d\n", pkg, core, cpu); |
| 607 | 604 | ||
| 608 | new = (PCC *)calloc(1, sizeof(PCC)); | 605 | new = (struct counters *)calloc(1, sizeof(struct counters)); |
| 609 | if (new == NULL) { | 606 | if (new == NULL) { |
| 610 | perror("calloc"); | 607 | perror("calloc"); |
| 611 | exit(1); | 608 | exit(1); |
| @@ -613,9 +610,10 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu) | |||
| 613 | new->pkg = pkg; | 610 | new->pkg = pkg; |
| 614 | new->core = core; | 611 | new->core = core; |
| 615 | new->cpu = cpu; | 612 | new->cpu = cpu; |
| 616 | insert_cpu_counters(&pcc_odd, new); | 613 | insert_counters(&cnt_odd, new); |
| 617 | 614 | ||
| 618 | new = (PCC *)calloc(1, sizeof(PCC)); | 615 | new = (struct counters *)calloc(1, |
| 616 | sizeof(struct counters)); | ||
| 619 | if (new == NULL) { | 617 | if (new == NULL) { |
| 620 | perror("calloc"); | 618 | perror("calloc"); |
| 621 | exit(1); | 619 | exit(1); |
| @@ -623,9 +621,9 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu) | |||
| 623 | new->pkg = pkg; | 621 | new->pkg = pkg; |
| 624 | new->core = core; | 622 | new->core = core; |
| 625 | new->cpu = cpu; | 623 | new->cpu = cpu; |
| 626 | insert_cpu_counters(&pcc_even, new); | 624 | insert_counters(&cnt_even, new); |
| 627 | 625 | ||
| 628 | new = (PCC *)calloc(1, sizeof(PCC)); | 626 | new = (struct counters *)calloc(1, sizeof(struct counters)); |
| 629 | if (new == NULL) { | 627 | if (new == NULL) { |
| 630 | perror("calloc"); | 628 | perror("calloc"); |
| 631 | exit(1); | 629 | exit(1); |
| @@ -633,9 +631,9 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu) | |||
| 633 | new->pkg = pkg; | 631 | new->pkg = pkg; |
| 634 | new->core = core; | 632 | new->core = core; |
| 635 | new->cpu = cpu; | 633 | new->cpu = cpu; |
| 636 | insert_cpu_counters(&pcc_delta, new); | 634 | insert_counters(&cnt_delta, new); |
| 637 | 635 | ||
| 638 | new = (PCC *)calloc(1, sizeof(PCC)); | 636 | new = (struct counters *)calloc(1, sizeof(struct counters)); |
| 639 | if (new == NULL) { | 637 | if (new == NULL) { |
| 640 | perror("calloc"); | 638 | perror("calloc"); |
| 641 | exit(1); | 639 | exit(1); |
| @@ -643,7 +641,7 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu) | |||
| 643 | new->pkg = pkg; | 641 | new->pkg = pkg; |
| 644 | new->core = core; | 642 | new->core = core; |
| 645 | new->cpu = cpu; | 643 | new->cpu = cpu; |
| 646 | pcc_average = new; | 644 | cnt_average = new; |
| 647 | } | 645 | } |
| 648 | 646 | ||
| 649 | int get_physical_package_id(int cpu) | 647 | int get_physical_package_id(int cpu) |
| @@ -719,7 +717,7 @@ void re_initialize(void) | |||
| 719 | { | 717 | { |
| 720 | printf("turbostat: topology changed, re-initializing.\n"); | 718 | printf("turbostat: topology changed, re-initializing.\n"); |
| 721 | free_all_counters(); | 719 | free_all_counters(); |
| 722 | num_cpus = for_all_cpus(alloc_new_cpu_counters); | 720 | num_cpus = for_all_cpus(alloc_new_counters); |
| 723 | need_reinitialize = 0; | 721 | need_reinitialize = 0; |
| 724 | printf("num_cpus is now %d\n", num_cpus); | 722 | printf("num_cpus is now %d\n", num_cpus); |
| 725 | } | 723 | } |
| @@ -728,7 +726,7 @@ void dummy(int pkg, int core, int cpu) { return; } | |||
| 728 | /* | 726 | /* |
| 729 | * check to see if a cpu came on-line | 727 | * check to see if a cpu came on-line |
| 730 | */ | 728 | */ |
| 731 | void verify_num_cpus() | 729 | void verify_num_cpus(void) |
| 732 | { | 730 | { |
| 733 | int new_num_cpus; | 731 | int new_num_cpus; |
| 734 | 732 | ||
| @@ -740,14 +738,12 @@ void verify_num_cpus() | |||
| 740 | num_cpus, new_num_cpus); | 738 | num_cpus, new_num_cpus); |
| 741 | need_reinitialize = 1; | 739 | need_reinitialize = 1; |
| 742 | } | 740 | } |
| 743 | |||
| 744 | return; | ||
| 745 | } | 741 | } |
| 746 | 742 | ||
| 747 | void turbostat_loop() | 743 | void turbostat_loop() |
| 748 | { | 744 | { |
| 749 | restart: | 745 | restart: |
| 750 | get_counters(pcc_even); | 746 | get_counters(cnt_even); |
| 751 | gettimeofday(&tv_even, (struct timezone *)NULL); | 747 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| 752 | 748 | ||
| 753 | while (1) { | 749 | while (1) { |
| @@ -757,24 +753,24 @@ restart: | |||
| 757 | goto restart; | 753 | goto restart; |
| 758 | } | 754 | } |
| 759 | sleep(interval_sec); | 755 | sleep(interval_sec); |
| 760 | get_counters(pcc_odd); | 756 | get_counters(cnt_odd); |
| 761 | gettimeofday(&tv_odd, (struct timezone *)NULL); | 757 | gettimeofday(&tv_odd, (struct timezone *)NULL); |
| 762 | 758 | ||
| 763 | compute_delta(pcc_odd, pcc_even, pcc_delta); | 759 | compute_delta(cnt_odd, cnt_even, cnt_delta); |
| 764 | timersub(&tv_odd, &tv_even, &tv_delta); | 760 | timersub(&tv_odd, &tv_even, &tv_delta); |
| 765 | compute_average(pcc_delta, pcc_average); | 761 | compute_average(cnt_delta, cnt_average); |
| 766 | print_counters(pcc_delta); | 762 | print_counters(cnt_delta); |
| 767 | if (need_reinitialize) { | 763 | if (need_reinitialize) { |
| 768 | re_initialize(); | 764 | re_initialize(); |
| 769 | goto restart; | 765 | goto restart; |
| 770 | } | 766 | } |
| 771 | sleep(interval_sec); | 767 | sleep(interval_sec); |
| 772 | get_counters(pcc_even); | 768 | get_counters(cnt_even); |
| 773 | gettimeofday(&tv_even, (struct timezone *)NULL); | 769 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| 774 | compute_delta(pcc_even, pcc_odd, pcc_delta); | 770 | compute_delta(cnt_even, cnt_odd, cnt_delta); |
| 775 | timersub(&tv_even, &tv_odd, &tv_delta); | 771 | timersub(&tv_even, &tv_odd, &tv_delta); |
| 776 | compute_average(pcc_delta, pcc_average); | 772 | compute_average(cnt_delta, cnt_average); |
| 777 | print_counters(pcc_delta); | 773 | print_counters(cnt_delta); |
| 778 | } | 774 | } |
| 779 | } | 775 | } |
| 780 | 776 | ||
| @@ -892,7 +888,7 @@ void check_cpuid() | |||
| 892 | * this check is valid for both Intel and AMD | 888 | * this check is valid for both Intel and AMD |
| 893 | */ | 889 | */ |
| 894 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); | 890 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); |
| 895 | has_invariant_tsc = edx && (1 << 8); | 891 | has_invariant_tsc = edx & (1 << 8); |
| 896 | 892 | ||
| 897 | if (!has_invariant_tsc) { | 893 | if (!has_invariant_tsc) { |
| 898 | fprintf(stderr, "No invariant TSC\n"); | 894 | fprintf(stderr, "No invariant TSC\n"); |
| @@ -905,7 +901,7 @@ void check_cpuid() | |||
| 905 | */ | 901 | */ |
| 906 | 902 | ||
| 907 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); | 903 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); |
| 908 | has_aperf = ecx && (1 << 0); | 904 | has_aperf = ecx & (1 << 0); |
| 909 | if (!has_aperf) { | 905 | if (!has_aperf) { |
| 910 | fprintf(stderr, "No APERF MSR\n"); | 906 | fprintf(stderr, "No APERF MSR\n"); |
| 911 | exit(1); | 907 | exit(1); |
| @@ -952,7 +948,7 @@ void turbostat_init() | |||
| 952 | check_dev_msr(); | 948 | check_dev_msr(); |
| 953 | check_super_user(); | 949 | check_super_user(); |
| 954 | 950 | ||
| 955 | num_cpus = for_all_cpus(alloc_new_cpu_counters); | 951 | num_cpus = for_all_cpus(alloc_new_counters); |
| 956 | 952 | ||
| 957 | if (verbose) | 953 | if (verbose) |
| 958 | print_nehalem_info(); | 954 | print_nehalem_info(); |
| @@ -962,7 +958,7 @@ int fork_it(char **argv) | |||
| 962 | { | 958 | { |
| 963 | int retval; | 959 | int retval; |
| 964 | pid_t child_pid; | 960 | pid_t child_pid; |
| 965 | get_counters(pcc_even); | 961 | get_counters(cnt_even); |
| 966 | gettimeofday(&tv_even, (struct timezone *)NULL); | 962 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| 967 | 963 | ||
| 968 | child_pid = fork(); | 964 | child_pid = fork(); |
| @@ -985,14 +981,14 @@ int fork_it(char **argv) | |||
| 985 | exit(1); | 981 | exit(1); |
| 986 | } | 982 | } |
| 987 | } | 983 | } |
| 988 | get_counters(pcc_odd); | 984 | get_counters(cnt_odd); |
| 989 | gettimeofday(&tv_odd, (struct timezone *)NULL); | 985 | gettimeofday(&tv_odd, (struct timezone *)NULL); |
| 990 | retval = compute_delta(pcc_odd, pcc_even, pcc_delta); | 986 | retval = compute_delta(cnt_odd, cnt_even, cnt_delta); |
| 991 | 987 | ||
| 992 | timersub(&tv_odd, &tv_even, &tv_delta); | 988 | timersub(&tv_odd, &tv_even, &tv_delta); |
| 993 | compute_average(pcc_delta, pcc_average); | 989 | compute_average(cnt_delta, cnt_average); |
| 994 | if (!retval) | 990 | if (!retval) |
| 995 | print_counters(pcc_delta); | 991 | print_counters(cnt_delta); |
| 996 | 992 | ||
| 997 | fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);; | 993 | fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);; |
| 998 | 994 | ||
