aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig37
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/asus_acpi.c9
-rw-r--r--drivers/acpi/battery.c4
-rw-r--r--drivers/acpi/bay.c490
-rw-r--r--drivers/acpi/blacklist.c29
-rw-r--r--drivers/acpi/bus.c44
-rw-r--r--drivers/acpi/button.c2
-rw-r--r--drivers/acpi/container.c6
-rw-r--r--drivers/acpi/debug.c62
-rw-r--r--drivers/acpi/dispatcher/dsfield.c32
-rw-r--r--drivers/acpi/dispatcher/dsinit.c25
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c55
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c2
-rw-r--r--drivers/acpi/dispatcher/dsobject.c78
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c6
-rw-r--r--drivers/acpi/dispatcher/dsutils.c2
-rw-r--r--drivers/acpi/dispatcher/dswexec.c12
-rw-r--r--drivers/acpi/dispatcher/dswload.c19
-rw-r--r--drivers/acpi/dispatcher/dswscope.c2
-rw-r--r--drivers/acpi/dispatcher/dswstate.c2
-rw-r--r--drivers/acpi/dock.c16
-rw-r--r--drivers/acpi/ec.c13
-rw-r--r--drivers/acpi/events/evevent.c17
-rw-r--r--drivers/acpi/events/evgpe.c91
-rw-r--r--drivers/acpi/events/evgpeblk.c64
-rw-r--r--drivers/acpi/events/evmisc.c201
-rw-r--r--drivers/acpi/events/evregion.c17
-rw-r--r--drivers/acpi/events/evrgnini.c168
-rw-r--r--drivers/acpi/events/evsci.c14
-rw-r--r--drivers/acpi/events/evxface.c8
-rw-r--r--drivers/acpi/events/evxfevnt.c27
-rw-r--r--drivers/acpi/events/evxfregn.c2
-rw-r--r--drivers/acpi/executer/exconfig.c235
-rw-r--r--drivers/acpi/executer/exconvrt.c2
-rw-r--r--drivers/acpi/executer/excreate.c21
-rw-r--r--drivers/acpi/executer/exdump.c29
-rw-r--r--drivers/acpi/executer/exfield.c2
-rw-r--r--drivers/acpi/executer/exfldio.c7
-rw-r--r--drivers/acpi/executer/exmisc.c2
-rw-r--r--drivers/acpi/executer/exmutex.c86
-rw-r--r--drivers/acpi/executer/exnames.c2
-rw-r--r--drivers/acpi/executer/exoparg1.c4
-rw-r--r--drivers/acpi/executer/exoparg2.c2
-rw-r--r--drivers/acpi/executer/exoparg3.c2
-rw-r--r--drivers/acpi/executer/exoparg6.c2
-rw-r--r--drivers/acpi/executer/exprep.c2
-rw-r--r--drivers/acpi/executer/exregion.c16
-rw-r--r--drivers/acpi/executer/exresnte.c2
-rw-r--r--drivers/acpi/executer/exresolv.c10
-rw-r--r--drivers/acpi/executer/exresop.c12
-rw-r--r--drivers/acpi/executer/exstore.c2
-rw-r--r--drivers/acpi/executer/exstoren.c2
-rw-r--r--drivers/acpi/executer/exstorob.c2
-rw-r--r--drivers/acpi/executer/exsystem.c110
-rw-r--r--drivers/acpi/executer/exutils.c106
-rw-r--r--drivers/acpi/fan.c8
-rw-r--r--drivers/acpi/glue.c123
-rw-r--r--drivers/acpi/hardware/hwacpi.c56
-rw-r--r--drivers/acpi/hardware/hwgpe.c15
-rw-r--r--drivers/acpi/hardware/hwregs.c98
-rw-r--r--drivers/acpi/hardware/hwsleep.c81
-rw-r--r--drivers/acpi/hardware/hwtimer.c9
-rw-r--r--drivers/acpi/motherboard.c191
-rw-r--r--drivers/acpi/namespace/nsaccess.c36
-rw-r--r--drivers/acpi/namespace/nsalloc.c14
-rw-r--r--drivers/acpi/namespace/nsdump.c13
-rw-r--r--drivers/acpi/namespace/nsdumpdv.c2
-rw-r--r--drivers/acpi/namespace/nseval.c13
-rw-r--r--drivers/acpi/namespace/nsinit.c9
-rw-r--r--drivers/acpi/namespace/nsload.c160
-rw-r--r--drivers/acpi/namespace/nsnames.c2
-rw-r--r--drivers/acpi/namespace/nsobject.c2
-rw-r--r--drivers/acpi/namespace/nsparse.c52
-rw-r--r--drivers/acpi/namespace/nssearch.c9
-rw-r--r--drivers/acpi/namespace/nsutils.c9
-rw-r--r--drivers/acpi/namespace/nswalk.c65
-rw-r--r--drivers/acpi/namespace/nsxfeval.c13
-rw-r--r--drivers/acpi/namespace/nsxfname.c47
-rw-r--r--drivers/acpi/namespace/nsxfobj.c2
-rw-r--r--drivers/acpi/numa.c77
-rw-r--r--drivers/acpi/osl.c97
-rw-r--r--drivers/acpi/parser/psargs.c2
-rw-r--r--drivers/acpi/parser/psloop.c1408
-rw-r--r--drivers/acpi/parser/psopcode.c2
-rw-r--r--drivers/acpi/parser/psparse.c7
-rw-r--r--drivers/acpi/parser/psscope.c2
-rw-r--r--drivers/acpi/parser/pstree.c2
-rw-r--r--drivers/acpi/parser/psutils.c2
-rw-r--r--drivers/acpi/parser/pswalk.c2
-rw-r--r--drivers/acpi/parser/psxface.c116
-rw-r--r--drivers/acpi/pci_link.c4
-rw-r--r--drivers/acpi/pci_root.c38
-rw-r--r--drivers/acpi/processor_core.c189
-rw-r--r--drivers/acpi/processor_idle.c52
-rw-r--r--drivers/acpi/processor_perflib.c27
-rw-r--r--drivers/acpi/processor_throttling.c4
-rw-r--r--drivers/acpi/resources/rsaddr.c2
-rw-r--r--drivers/acpi/resources/rscalc.c2
-rw-r--r--drivers/acpi/resources/rscreate.c2
-rw-r--r--drivers/acpi/resources/rsdump.c2
-rw-r--r--drivers/acpi/resources/rsinfo.c2
-rw-r--r--drivers/acpi/resources/rsio.c2
-rw-r--r--drivers/acpi/resources/rsirq.c2
-rw-r--r--drivers/acpi/resources/rslist.c2
-rw-r--r--drivers/acpi/resources/rsmemory.c2
-rw-r--r--drivers/acpi/resources/rsmisc.c2
-rw-r--r--drivers/acpi/resources/rsutils.c2
-rw-r--r--drivers/acpi/resources/rsxface.c2
-rw-r--r--drivers/acpi/scan.c1265
-rw-r--r--drivers/acpi/sleep/proc.c36
-rw-r--r--drivers/acpi/system.c39
-rw-r--r--drivers/acpi/tables.c508
-rw-r--r--drivers/acpi/tables/Makefile3
-rw-r--r--drivers/acpi/tables/tbconvrt.c622
-rw-r--r--drivers/acpi/tables/tbfadt.c434
-rw-r--r--drivers/acpi/tables/tbfind.c126
-rw-r--r--drivers/acpi/tables/tbget.c471
-rw-r--r--drivers/acpi/tables/tbgetall.c311
-rw-r--r--drivers/acpi/tables/tbinstal.c664
-rw-r--r--drivers/acpi/tables/tbrsdt.c307
-rw-r--r--drivers/acpi/tables/tbutils.c513
-rw-r--r--drivers/acpi/tables/tbxface.c671
-rw-r--r--drivers/acpi/tables/tbxfroot.c552
-rw-r--r--drivers/acpi/thermal.c4
-rw-r--r--drivers/acpi/utilities/utalloc.c11
-rw-r--r--drivers/acpi/utilities/utcache.c10
-rw-r--r--drivers/acpi/utilities/utcopy.c11
-rw-r--r--drivers/acpi/utilities/utdebug.c7
-rw-r--r--drivers/acpi/utilities/utdelete.c16
-rw-r--r--drivers/acpi/utilities/uteval.c2
-rw-r--r--drivers/acpi/utilities/utglobal.c199
-rw-r--r--drivers/acpi/utilities/utinit.c114
-rw-r--r--drivers/acpi/utilities/utmath.c2
-rw-r--r--drivers/acpi/utilities/utmisc.c102
-rw-r--r--drivers/acpi/utilities/utmutex.c2
-rw-r--r--drivers/acpi/utilities/utobject.c2
-rw-r--r--drivers/acpi/utilities/utresrc.c2
-rw-r--r--drivers/acpi/utilities/utstate.c2
-rw-r--r--drivers/acpi/utilities/utxface.c29
-rw-r--r--drivers/acpi/video.c166
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c18
-rw-r--r--drivers/char/tpm/tpm_bios.c8
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/firmware/pcdp.c2
-rw-r--r--drivers/hid/Kconfig14
-rw-r--r--drivers/hid/Makefile11
-rw-r--r--drivers/hid/hid-core.c8
-rw-r--r--drivers/hid/hid-debug.c764
-rw-r--r--drivers/hid/hid-input.c35
-rw-r--r--drivers/infiniband/core/addr.c3
-rw-r--r--drivers/infiniband/core/mad.c11
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h29
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c65
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h8
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c78
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c395
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c7
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
-rw-r--r--drivers/misc/Kconfig19
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/asus-laptop.c1165
-rw-r--r--drivers/misc/tifm_7xx1.c402
-rw-r--r--drivers/misc/tifm_core.c65
-rw-r--r--drivers/mmc/at91_mci.c3
-rw-r--r--drivers/mmc/au1xmmc.c13
-rw-r--r--drivers/mmc/imxmmc.c4
-rw-r--r--drivers/mmc/mmc.c182
-rw-r--r--drivers/mmc/mmc_block.c15
-rw-r--r--drivers/mmc/mmc_queue.c2
-rw-r--r--drivers/mmc/mmc_sysfs.c2
-rw-r--r--drivers/mmc/mmci.c15
-rw-r--r--drivers/mmc/omap.c6
-rw-r--r--drivers/mmc/pxamci.c10
-rw-r--r--drivers/mmc/sdhci.c91
-rw-r--r--drivers/mmc/sdhci.h2
-rw-r--r--drivers/mmc/tifm_sd.c487
-rw-r--r--drivers/mmc/wbsd.c102
-rw-r--r--drivers/mmc/wbsd.h1
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c10
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c155
-rw-r--r--drivers/pnp/pnpacpi/Kconfig4
-rw-r--r--drivers/pnp/system.c52
-rw-r--r--drivers/s390/Kconfig8
-rw-r--r--drivers/s390/Makefile2
-rw-r--r--drivers/s390/block/dasd.c33
-rw-r--r--drivers/s390/block/dasd_3990_erp.c5
-rw-r--r--drivers/s390/block/dasd_devmap.c6
-rw-r--r--drivers/s390/block/dasd_diag.c8
-rw-r--r--drivers/s390/block/dasd_eckd.c95
-rw-r--r--drivers/s390/block/dasd_eer.c24
-rw-r--r--drivers/s390/block/dasd_erp.c80
-rw-r--r--drivers/s390/block/dasd_fba.c4
-rw-r--r--drivers/s390/block/dasd_genhd.c2
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/dasd_proc.c8
-rw-r--r--drivers/s390/block/dcssblk.c6
-rw-r--r--drivers/s390/char/Makefile4
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/con3270.c3
-rw-r--r--drivers/s390/char/defkeymap.c2
-rw-r--r--drivers/s390/char/fs3270.c4
-rw-r--r--drivers/s390/char/keyboard.c2
-rw-r--r--drivers/s390/char/monwriter.c4
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/char/sclp.c93
-rw-r--r--drivers/s390/char/sclp.h18
-rw-r--r--drivers/s390/char/sclp_con.c2
-rw-r--r--drivers/s390/char/sclp_cpi.c2
-rw-r--r--drivers/s390/char/sclp_info.c57
-rw-r--r--drivers/s390/char/sclp_rw.c2
-rw-r--r--drivers/s390/char/sclp_tty.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c4
-rw-r--r--drivers/s390/char/tape.h22
-rw-r--r--drivers/s390/char/tape_3590.c479
-rw-r--r--drivers/s390/char/tape_3590.h53
-rw-r--r--drivers/s390/char/tape_block.c4
-rw-r--r--drivers/s390/char/tape_char.c27
-rw-r--r--drivers/s390/char/tape_core.c69
-rw-r--r--drivers/s390/char/tty3270.c13
-rw-r--r--drivers/s390/char/vmlogrdr.c5
-rw-r--r--drivers/s390/cio/blacklist.c10
-rw-r--r--drivers/s390/cio/ccwgroup.c6
-rw-r--r--drivers/s390/cio/chsc.c270
-rw-r--r--drivers/s390/cio/chsc.h11
-rw-r--r--drivers/s390/cio/cio.c37
-rw-r--r--drivers/s390/cio/cmf.c4
-rw-r--r--drivers/s390/cio/css.c13
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c12
-rw-r--r--drivers/s390/cio/device.h2
-rw-r--r--drivers/s390/cio/device_fsm.c8
-rw-r--r--drivers/s390/cio/device_ops.c2
-rw-r--r--drivers/s390/cio/device_status.c8
-rw-r--r--drivers/s390/cio/qdio.c77
-rw-r--r--drivers/s390/crypto/ap_bus.c8
-rw-r--r--drivers/s390/crypto/zcrypt_api.c20
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c8
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c3
-rw-r--r--drivers/s390/net/claw.c16
-rw-r--r--drivers/s390/net/ctcmain.c8
-rw-r--r--drivers/s390/net/cu3088.c2
-rw-r--r--drivers/s390/net/lcs.c6
-rw-r--r--drivers/s390/net/netiucv.c4
-rw-r--r--drivers/s390/net/qeth_eddp.c28
-rw-r--r--drivers/s390/net/qeth_main.c92
-rw-r--r--drivers/s390/net/qeth_sys.c30
-rw-r--r--drivers/s390/s390mach.c37
-rw-r--r--drivers/s390/s390mach.h3
-rw-r--r--drivers/s390/scsi/zfcp_aux.c25
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c44
-rw-r--r--drivers/s390/scsi/zfcp_erp.c7
-rw-r--r--drivers/s390/scsi/zfcp_ext.h4
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c2
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c38
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c18
-rw-r--r--drivers/s390/sysinfo.c63
-rw-r--r--drivers/usb/input/Kconfig8
-rw-r--r--drivers/usb/input/Makefile3
-rw-r--r--drivers/usb/input/hid-core.c81
-rw-r--r--drivers/usb/input/hid-ff.c3
-rw-r--r--drivers/usb/input/hid-plff.c129
-rw-r--r--drivers/video/output.c129
274 files changed, 10515 insertions, 8746 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f000abc4e9..20eacc2c9e0e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -3,6 +3,7 @@
3# 3#
4 4
5menu "ACPI (Advanced Configuration and Power Interface) Support" 5menu "ACPI (Advanced Configuration and Power Interface) Support"
6 depends on !X86_NUMAQ
6 depends on !X86_VISWS 7 depends on !X86_VISWS
7 depends on !IA64_HP_SIM 8 depends on !IA64_HP_SIM
8 depends on IA64 || X86 9 depends on IA64 || X86
@@ -77,6 +78,20 @@ config ACPI_SLEEP_PROC_SLEEP
77 Create /proc/acpi/sleep 78 Create /proc/acpi/sleep
78 Deprecated by /sys/power/state 79 Deprecated by /sys/power/state
79 80
81config ACPI_PROCFS
82 bool "Procfs interface (deprecated)"
83 depends on ACPI
84 default y
85 ---help---
86 Procfs interface for ACPI is made optional for back-compatible.
87 As the same functions are duplicated in sysfs interface
88 and this proc interface will be removed some time later,
89 it's marked as deprecated.
90 ( /proc/acpi/debug_layer && debug_level are deprecated by
91 /sys/module/acpi/parameters/debug_layer && debug_level.
92 /proc/acpi/info is deprecated by
93 /sys/module/acpi/parameters/acpica_version )
94
80config ACPI_AC 95config ACPI_AC
81 tristate "AC Adapter" 96 tristate "AC Adapter"
82 depends on X86 97 depends on X86
@@ -107,7 +122,7 @@ config ACPI_BUTTON
107 122
108config ACPI_VIDEO 123config ACPI_VIDEO
109 tristate "Video" 124 tristate "Video"
110 depends on X86 125 depends on X86 && BACKLIGHT_CLASS_DEVICE
111 help 126 help
112 This driver implement the ACPI Extensions For Display Adapters 127 This driver implement the ACPI Extensions For Display Adapters
113 for integrated graphics devices on motherboard, as specified in 128 for integrated graphics devices on motherboard, as specified in
@@ -139,6 +154,13 @@ config ACPI_DOCK
139 help 154 help
140 This driver adds support for ACPI controlled docking stations 155 This driver adds support for ACPI controlled docking stations
141 156
157config ACPI_BAY
158 tristate "Removable Drive Bay (EXPERIMENTAL)"
159 depends on EXPERIMENTAL
160 help
161 This driver adds support for ACPI controlled removable drive
162 bays such as the IBM ultrabay or the Dell Module Bay.
163
142config ACPI_PROCESSOR 164config ACPI_PROCESSOR
143 tristate "Processor" 165 tristate "Processor"
144 default y 166 default y
@@ -186,19 +208,22 @@ config ACPI_ASUS
186 208
187 Note: display switching code is currently considered EXPERIMENTAL, 209 Note: display switching code is currently considered EXPERIMENTAL,
188 toying with these values may even lock your machine. 210 toying with these values may even lock your machine.
189 211
190 All settings are changed via /proc/acpi/asus directory entries. Owner 212 All settings are changed via /proc/acpi/asus directory entries. Owner
191 and group for these entries can be set with asus_uid and asus_gid 213 and group for these entries can be set with asus_uid and asus_gid
192 parameters. 214 parameters.
193 215
194 More information and a userspace daemon for handling the extra buttons 216 More information and a userspace daemon for handling the extra buttons
195 at <http://sourceforge.net/projects/acpi4asus/>. 217 at <http://sourceforge.net/projects/acpi4asus/>.
196 218
197 If you have an ACPI-compatible ASUS laptop, say Y or M here. This 219 If you have an ACPI-compatible ASUS laptop, say Y or M here. This
198 driver is still under development, so if your laptop is unsupported or 220 driver is still under development, so if your laptop is unsupported or
199 something works not quite as expected, please use the mailing list 221 something works not quite as expected, please use the mailing list
200 available on the above page (acpi4asus-user@lists.sourceforge.net) 222 available on the above page (acpi4asus-user@lists.sourceforge.net).
201 223
224 NOTE: This driver is deprecated and will probably be removed soon,
225 use asus-laptop instead.
226
202config ACPI_IBM 227config ACPI_IBM
203 tristate "IBM ThinkPad Laptop Extras" 228 tristate "IBM ThinkPad Laptop Extras"
204 depends on X86 229 depends on X86
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bce7ca27b429..856c32bccacb 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -37,13 +37,15 @@ endif
37 37
38obj-y += sleep/ 38obj-y += sleep/
39obj-y += bus.o glue.o 39obj-y += bus.o glue.o
40obj-y += scan.o
40obj-$(CONFIG_ACPI_AC) += ac.o 41obj-$(CONFIG_ACPI_AC) += ac.o
41obj-$(CONFIG_ACPI_BATTERY) += battery.o 42obj-$(CONFIG_ACPI_BATTERY) += battery.o
42obj-$(CONFIG_ACPI_BUTTON) += button.o 43obj-$(CONFIG_ACPI_BUTTON) += button.o
43obj-$(CONFIG_ACPI_EC) += ec.o 44obj-$(CONFIG_ACPI_EC) += ec.o
44obj-$(CONFIG_ACPI_FAN) += fan.o 45obj-$(CONFIG_ACPI_FAN) += fan.o
45obj-$(CONFIG_ACPI_DOCK) += dock.o 46obj-$(CONFIG_ACPI_DOCK) += dock.o
46obj-$(CONFIG_ACPI_VIDEO) += video.o 47obj-$(CONFIG_ACPI_BAY) += bay.o
48obj-$(CONFIG_ACPI_VIDEO) += video.o
47obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o 49obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
48obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 50obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
49obj-$(CONFIG_ACPI_POWER) += power.o 51obj-$(CONFIG_ACPI_POWER) += power.o
@@ -56,7 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
56obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o 58obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
57obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o 59obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
58obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 60obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
59obj-y += scan.o motherboard.o
60obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o 61obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
61obj-y += cm_sbs.o 62obj-y += cm_sbs.o
62obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o 63obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 396140bbbe57..31ad70a6e22e 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -26,7 +26,7 @@
26 * Pontus Fuchs - Helper functions, cleanup 26 * Pontus Fuchs - Helper functions, cleanup
27 * Johann Wiesner - Small compile fixes 27 * Johann Wiesner - Small compile fixes
28 * John Belmonte - ACPI code for Toshiba laptop was a good starting point. 28 * John Belmonte - ACPI code for Toshiba laptop was a good starting point.
29 * Éric Burghard - LED display support for W1N 29 * �ic Burghard - LED display support for W1N
30 * 30 *
31 */ 31 */
32 32
@@ -1128,7 +1128,6 @@ static int asus_model_match(char *model)
1128static int asus_hotk_get_info(void) 1128static int asus_hotk_get_info(void)
1129{ 1129{
1130 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1130 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1131 struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
1132 union acpi_object *model = NULL; 1131 union acpi_object *model = NULL;
1133 int bsts_result; 1132 int bsts_result;
1134 char *string = NULL; 1133 char *string = NULL;
@@ -1142,11 +1141,9 @@ static int asus_hotk_get_info(void)
1142 * HID), this bit will be moved. A global variable asus_info contains 1141 * HID), this bit will be moved. A global variable asus_info contains
1143 * the DSDT header. 1142 * the DSDT header.
1144 */ 1143 */
1145 status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); 1144 status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
1146 if (ACPI_FAILURE(status)) 1145 if (ACPI_FAILURE(status))
1147 printk(KERN_WARNING " Couldn't get the DSDT table header\n"); 1146 printk(KERN_WARNING " Couldn't get the DSDT table header\n");
1148 else
1149 asus_info = dsdt.pointer;
1150 1147
1151 /* We have to write 0 on init this far for all ASUS models */ 1148 /* We have to write 0 on init this far for all ASUS models */
1152 if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { 1149 if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -1358,8 +1355,6 @@ static void __exit asus_acpi_exit(void)
1358 acpi_bus_unregister_driver(&asus_hotk_driver); 1355 acpi_bus_unregister_driver(&asus_hotk_driver);
1359 remove_proc_entry(PROC_ASUS, acpi_root_dir); 1356 remove_proc_entry(PROC_ASUS, acpi_root_dir);
1360 1357
1361 kfree(asus_info);
1362
1363 return; 1358 return;
1364} 1359}
1365 1360
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 5f43e0d14899..2f4521a48fe7 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -64,7 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
64 64
65static int acpi_battery_add(struct acpi_device *device); 65static int acpi_battery_add(struct acpi_device *device);
66static int acpi_battery_remove(struct acpi_device *device, int type); 66static int acpi_battery_remove(struct acpi_device *device, int type);
67static int acpi_battery_resume(struct acpi_device *device, int status); 67static int acpi_battery_resume(struct acpi_device *device);
68 68
69static struct acpi_driver acpi_battery_driver = { 69static struct acpi_driver acpi_battery_driver = {
70 .name = ACPI_BATTERY_DRIVER_NAME, 70 .name = ACPI_BATTERY_DRIVER_NAME,
@@ -753,7 +753,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
753} 753}
754 754
755/* this is needed to learn about changes made in suspended state */ 755/* this is needed to learn about changes made in suspended state */
756static int acpi_battery_resume(struct acpi_device *device, int state) 756static int acpi_battery_resume(struct acpi_device *device)
757{ 757{
758 struct acpi_battery *battery; 758 struct acpi_battery *battery;
759 759
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
new file mode 100644
index 000000000000..667fa1dfa1a3
--- /dev/null
+++ b/drivers/acpi/bay.c
@@ -0,0 +1,490 @@
1/*
2 * bay.c - ACPI removable drive bay driver
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/notifier.h>
29#include <acpi/acpi_bus.h>
30#include <acpi/acpi_drivers.h>
31#include <linux/seq_file.h>
32#include <asm/uaccess.h>
33#include <linux/platform_device.h>
34
35#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver"
36
37ACPI_MODULE_NAME("bay")
38MODULE_AUTHOR("Kristen Carlson Accardi");
39MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME);
40MODULE_LICENSE("GPL");
41#define ACPI_BAY_CLASS "bay"
42#define ACPI_BAY_COMPONENT 0x10000000
43#define _COMPONENT ACPI_BAY_COMPONENT
44#define bay_dprintk(h,s) {\
45 char prefix[80] = {'\0'};\
46 struct acpi_buffer buffer = {sizeof(prefix), prefix};\
47 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
48 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
49static void bay_notify(acpi_handle handle, u32 event, void *data);
50static int acpi_bay_add(struct acpi_device *device);
51static int acpi_bay_remove(struct acpi_device *device, int type);
52
53static struct acpi_driver acpi_bay_driver = {
54 .name = ACPI_BAY_DRIVER_NAME,
55 .class = ACPI_BAY_CLASS,
56 .ids = ACPI_BAY_HID,
57 .ops = {
58 .add = acpi_bay_add,
59 .remove = acpi_bay_remove,
60 },
61};
62
63struct bay {
64 acpi_handle handle;
65 char *name;
66 struct list_head list;
67 struct platform_device *pdev;
68};
69
70static LIST_HEAD(drive_bays);
71
72
73/*****************************************************************************
74 * Drive Bay functions *
75 *****************************************************************************/
76/**
77 * is_ejectable - see if a device is ejectable
78 * @handle: acpi handle of the device
79 *
80 * If an acpi object has a _EJ0 method, then it is ejectable
81 */
82static int is_ejectable(acpi_handle handle)
83{
84 acpi_status status;
85 acpi_handle tmp;
86
87 status = acpi_get_handle(handle, "_EJ0", &tmp);
88 if (ACPI_FAILURE(status))
89 return 0;
90 return 1;
91}
92
93/**
94 * bay_present - see if the bay device is present
95 * @bay: the drive bay
96 *
97 * execute the _STA method.
98 */
99static int bay_present(struct bay *bay)
100{
101 unsigned long sta;
102 acpi_status status;
103
104 if (bay) {
105 status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta);
106 if (ACPI_SUCCESS(status) && sta)
107 return 1;
108 }
109 return 0;
110}
111
112/**
113 * eject_device - respond to an eject request
114 * @handle - the device to eject
115 *
116 * Call this devices _EJ0 method.
117 */
118static void eject_device(acpi_handle handle)
119{
120 struct acpi_object_list arg_list;
121 union acpi_object arg;
122
123 bay_dprintk(handle, "Ejecting device");
124
125 arg_list.count = 1;
126 arg_list.pointer = &arg;
127 arg.type = ACPI_TYPE_INTEGER;
128 arg.integer.value = 1;
129
130 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
131 &arg_list, NULL)))
132 pr_debug("Failed to evaluate _EJ0!\n");
133}
134
135/*
136 * show_present - read method for "present" file in sysfs
137 */
138static ssize_t show_present(struct device *dev,
139 struct device_attribute *attr, char *buf)
140{
141 struct bay *bay = dev_get_drvdata(dev);
142 return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay));
143
144}
145DEVICE_ATTR(present, S_IRUGO, show_present, NULL);
146
147/*
148 * write_eject - write method for "eject" file in sysfs
149 */
150static ssize_t write_eject(struct device *dev, struct device_attribute *attr,
151 const char *buf, size_t count)
152{
153 struct bay *bay = dev_get_drvdata(dev);
154
155 if (!count)
156 return -EINVAL;
157
158 eject_device(bay->handle);
159 return count;
160}
161DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject);
162
163/**
164 * is_ata - see if a device is an ata device
165 * @handle: acpi handle of the device
166 *
167 * If an acpi object has one of 4 ATA ACPI methods defined,
168 * then it is an ATA device
169 */
170static int is_ata(acpi_handle handle)
171{
172 acpi_handle tmp;
173
174 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
175 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
176 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
177 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
178 return 1;
179
180 return 0;
181}
182
183/**
184 * parent_is_ata(acpi_handle handle)
185 *
186 */
187static int parent_is_ata(acpi_handle handle)
188{
189 acpi_handle phandle;
190
191 if (acpi_get_parent(handle, &phandle))
192 return 0;
193
194 return is_ata(phandle);
195}
196
197/**
198 * is_ejectable_bay - see if a device is an ejectable drive bay
199 * @handle: acpi handle of the device
200 *
201 * If an acpi object is ejectable and has one of the ACPI ATA
202 * methods defined, then we can safely call it an ejectable
203 * drive bay
204 */
205static int is_ejectable_bay(acpi_handle handle)
206{
207 if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle))
208 return 1;
209 return 0;
210}
211
212/**
213 * eject_removable_drive - try to eject this drive
214 * @dev : the device structure of the drive
215 *
216 * If a device is a removable drive that requires an _EJ0 method
217 * to be executed in order to safely remove from the system, do
218 * it. ATM - always returns success
219 */
220int eject_removable_drive(struct device *dev)
221{
222 acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
223
224 if (handle) {
225 bay_dprintk(handle, "Got device handle");
226 if (is_ejectable_bay(handle))
227 eject_device(handle);
228 } else {
229 printk("No acpi handle for device\n");
230 }
231
232 /* should I return an error code? */
233 return 0;
234}
235EXPORT_SYMBOL_GPL(eject_removable_drive);
236
237static int acpi_bay_add(struct acpi_device *device)
238{
239 bay_dprintk(device->handle, "adding bay device");
240 strcpy(acpi_device_name(device), "Dockable Bay");
241 strcpy(acpi_device_class(device), "bay");
242 return 0;
243}
244
245static int acpi_bay_add_fs(struct bay *bay)
246{
247 int ret;
248 struct device *dev = &bay->pdev->dev;
249
250 ret = device_create_file(dev, &dev_attr_present);
251 if (ret)
252 goto add_fs_err;
253 ret = device_create_file(dev, &dev_attr_eject);
254 if (ret) {
255 device_remove_file(dev, &dev_attr_present);
256 goto add_fs_err;
257 }
258 return 0;
259
260 add_fs_err:
261 bay_dprintk(bay->handle, "Error adding sysfs files\n");
262 return ret;
263}
264
265static void acpi_bay_remove_fs(struct bay *bay)
266{
267 struct device *dev = &bay->pdev->dev;
268
269 /* cleanup sysfs */
270 device_remove_file(dev, &dev_attr_present);
271 device_remove_file(dev, &dev_attr_eject);
272}
273
274static int bay_is_dock_device(acpi_handle handle)
275{
276 acpi_handle parent;
277
278 acpi_get_parent(handle, &parent);
279
280 /* if the device or it's parent is dependent on the
281 * dock, then we are a dock device
282 */
283 return (is_dock_device(handle) || is_dock_device(parent));
284}
285
286static int bay_add(acpi_handle handle, int id)
287{
288 acpi_status status;
289 struct bay *new_bay;
290 struct platform_device *pdev;
291 struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL};
292 acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer);
293
294 bay_dprintk(handle, "Adding notify handler");
295
296 /*
297 * Initialize bay device structure
298 */
299 new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay));
300 INIT_LIST_HEAD(&new_bay->list);
301 new_bay->handle = handle;
302 new_bay->name = (char *)nbuffer.pointer;
303
304 /* initialize platform device stuff */
305 pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
306 if (pdev == NULL) {
307 printk(KERN_ERR PREFIX "Error registering bay device\n");
308 goto bay_add_err;
309 }
310 new_bay->pdev = pdev;
311 platform_set_drvdata(pdev, new_bay);
312
313 if (acpi_bay_add_fs(new_bay)) {
314 platform_device_unregister(new_bay->pdev);
315 goto bay_add_err;
316 }
317
318 /* register for events on this device */
319 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
320 bay_notify, new_bay);
321 if (ACPI_FAILURE(status)) {
322 printk(KERN_ERR PREFIX "Error installing bay notify handler\n");
323 }
324
325 /* if we are on a dock station, we should register for dock
326 * notifications.
327 */
328 if (bay_is_dock_device(handle)) {
329 bay_dprintk(handle, "Is dependent on dock\n");
330 register_hotplug_dock_device(handle, bay_notify, new_bay);
331 }
332 list_add(&new_bay->list, &drive_bays);
333 printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name);
334 return 0;
335
336bay_add_err:
337 kfree(new_bay->name);
338 kfree(new_bay);
339 return -ENODEV;
340}
341
342static int acpi_bay_remove(struct acpi_device *device, int type)
343{
344 /*** FIXME: do something here */
345 return 0;
346}
347
348/**
349 * bay_create_acpi_device - add new devices to acpi
350 * @handle - handle of the device to add
351 *
352 * This function will create a new acpi_device for the given
353 * handle if one does not exist already. This should cause
354 * acpi to scan for drivers for the given devices, and call
355 * matching driver's add routine.
356 *
357 * Returns a pointer to the acpi_device corresponding to the handle.
358 */
359static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
360{
361 struct acpi_device *device = NULL;
362 struct acpi_device *parent_device;
363 acpi_handle parent;
364 int ret;
365
366 bay_dprintk(handle, "Trying to get device");
367 if (acpi_bus_get_device(handle, &device)) {
368 /*
369 * no device created for this object,
370 * so we should create one.
371 */
372 bay_dprintk(handle, "No device for handle");
373 acpi_get_parent(handle, &parent);
374 if (acpi_bus_get_device(parent, &parent_device))
375 parent_device = NULL;
376
377 ret = acpi_bus_add(&device, parent_device, handle,
378 ACPI_BUS_TYPE_DEVICE);
379 if (ret) {
380 pr_debug("error adding bus, %x\n",
381 -ret);
382 return NULL;
383 }
384 }
385 return device;
386}
387
388/**
389 * bay_notify - act upon an acpi bay notification
390 * @handle: the bay handle
391 * @event: the acpi event
392 * @data: our driver data struct
393 *
394 */
395static void bay_notify(acpi_handle handle, u32 event, void *data)
396{
397 struct acpi_device *dev;
398
399 bay_dprintk(handle, "Bay event");
400
401 switch(event) {
402 case ACPI_NOTIFY_BUS_CHECK:
403 printk("Bus Check\n");
404 case ACPI_NOTIFY_DEVICE_CHECK:
405 printk("Device Check\n");
406 dev = bay_create_acpi_device(handle);
407 if (dev)
408 acpi_bus_generate_event(dev, event, 0);
409 else
410 printk("No device for generating event\n");
411 /* wouldn't it be a good idea to just rescan SATA
412 * right here?
413 */
414 break;
415 case ACPI_NOTIFY_EJECT_REQUEST:
416 printk("Eject request\n");
417 dev = bay_create_acpi_device(handle);
418 if (dev)
419 acpi_bus_generate_event(dev, event, 0);
420 else
421 printk("No device for generating eventn");
422
423 /* wouldn't it be a good idea to just call the
424 * eject_device here if we were a SATA device?
425 */
426 break;
427 default:
428 printk("unknown event %d\n", event);
429 }
430}
431
432static acpi_status
433find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
434{
435 int *count = (int *)context;
436
437 /*
438 * there could be more than one ejectable bay.
439 * so, just return AE_OK always so that every object
440 * will be checked.
441 */
442 if (is_ejectable_bay(handle)) {
443 bay_dprintk(handle, "found ejectable bay");
444 if (!bay_add(handle, *count))
445 (*count)++;
446 }
447 return AE_OK;
448}
449
450static int __init bay_init(void)
451{
452 int bays = 0;
453
454 INIT_LIST_HEAD(&drive_bays);
455
456 /* look for dockable drive bays */
457 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
458 ACPI_UINT32_MAX, find_bay, &bays, NULL);
459
460 if (bays)
461 if ((acpi_bus_register_driver(&acpi_bay_driver) < 0))
462 printk(KERN_ERR "Unable to register bay driver\n");
463
464 if (!bays)
465 return -ENODEV;
466
467 return 0;
468}
469
470static void __exit bay_exit(void)
471{
472 struct bay *bay, *tmp;
473
474 list_for_each_entry_safe(bay, tmp, &drive_bays, list) {
475 if (is_dock_device(bay->handle))
476 unregister_hotplug_dock_device(bay->handle);
477 acpi_bay_remove_fs(bay);
478 acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY,
479 bay_notify);
480 platform_device_unregister(bay->pdev);
481 kfree(bay->name);
482 kfree(bay);
483 }
484
485 acpi_bus_unregister_driver(&acpi_bay_driver);
486}
487
488postcore_initcall(bay_init);
489module_exit(bay_exit);
490
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index f9c972b26f4f..f289fd41e77d 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -44,7 +44,7 @@ struct acpi_blacklist_item {
44 char oem_id[7]; 44 char oem_id[7];
45 char oem_table_id[9]; 45 char oem_table_id[9];
46 u32 oem_revision; 46 u32 oem_revision;
47 acpi_table_type table; 47 char *table;
48 enum acpi_blacklist_predicates oem_revision_predicate; 48 enum acpi_blacklist_predicates oem_revision_predicate;
49 char *reason; 49 char *reason;
50 u32 is_critical_error; 50 u32 is_critical_error;
@@ -56,18 +56,18 @@ struct acpi_blacklist_item {
56 */ 56 */
57static struct acpi_blacklist_item acpi_blacklist[] __initdata = { 57static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
58 /* Compaq Presario 1700 */ 58 /* Compaq Presario 1700 */
59 {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT, less_than_or_equal, 59 {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
60 "Multiple problems", 1}, 60 "Multiple problems", 1},
61 /* Sony FX120, FX140, FX150? */ 61 /* Sony FX120, FX140, FX150? */
62 {"SONY ", "U0 ", 0x20010313, ACPI_DSDT, less_than_or_equal, 62 {"SONY ", "U0 ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal,
63 "ACPI driver problem", 1}, 63 "ACPI driver problem", 1},
64 /* Compaq Presario 800, Insyde BIOS */ 64 /* Compaq Presario 800, Insyde BIOS */
65 {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, 65 {"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal,
66 "Does not use _REG to protect EC OpRegions", 1}, 66 "Does not use _REG to protect EC OpRegions", 1},
67 /* IBM 600E - _ADR should return 7, but it returns 1 */ 67 /* IBM 600E - _ADR should return 7, but it returns 1 */
68 {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT, less_than_or_equal, 68 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
69 "Incorrect _ADR", 1}, 69 "Incorrect _ADR", 1},
70 {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT, all_versions, 70 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
71 "Bogus PCI routing", 1}, 71 "Bogus PCI routing", 1},
72 72
73 {""} 73 {""}
@@ -79,7 +79,7 @@ static int __init blacklist_by_year(void)
79{ 79{
80 int year = dmi_get_year(DMI_BIOS_DATE); 80 int year = dmi_get_year(DMI_BIOS_DATE);
81 /* Doesn't exist? Likely an old system */ 81 /* Doesn't exist? Likely an old system */
82 if (year == -1) 82 if (year == -1)
83 return 1; 83 return 1;
84 /* 0? Likely a buggy new BIOS */ 84 /* 0? Likely a buggy new BIOS */
85 if (year == 0) 85 if (year == 0)
@@ -103,22 +103,21 @@ int __init acpi_blacklisted(void)
103{ 103{
104 int i = 0; 104 int i = 0;
105 int blacklisted = 0; 105 int blacklisted = 0;
106 struct acpi_table_header *table_header; 106 struct acpi_table_header table_header;
107 107
108 while (acpi_blacklist[i].oem_id[0] != '\0') { 108 while (acpi_blacklist[i].oem_id[0] != '\0') {
109 if (acpi_get_table_header_early 109 if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
110 (acpi_blacklist[i].table, &table_header)) {
111 i++; 110 i++;
112 continue; 111 continue;
113 } 112 }
114 113
115 if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { 114 if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
116 i++; 115 i++;
117 continue; 116 continue;
118 } 117 }
119 118
120 if (strncmp 119 if (strncmp
121 (acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 120 (acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
122 8)) { 121 8)) {
123 i++; 122 i++;
124 continue; 123 continue;
@@ -127,14 +126,14 @@ int __init acpi_blacklisted(void)
127 if ((acpi_blacklist[i].oem_revision_predicate == all_versions) 126 if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
128 || (acpi_blacklist[i].oem_revision_predicate == 127 || (acpi_blacklist[i].oem_revision_predicate ==
129 less_than_or_equal 128 less_than_or_equal
130 && table_header->oem_revision <= 129 && table_header.oem_revision <=
131 acpi_blacklist[i].oem_revision) 130 acpi_blacklist[i].oem_revision)
132 || (acpi_blacklist[i].oem_revision_predicate == 131 || (acpi_blacklist[i].oem_revision_predicate ==
133 greater_than_or_equal 132 greater_than_or_equal
134 && table_header->oem_revision >= 133 && table_header.oem_revision >=
135 acpi_blacklist[i].oem_revision) 134 acpi_blacklist[i].oem_revision)
136 || (acpi_blacklist[i].oem_revision_predicate == equal 135 || (acpi_blacklist[i].oem_revision_predicate == equal
137 && table_header->oem_revision == 136 && table_header.oem_revision ==
138 acpi_blacklist[i].oem_revision)) { 137 acpi_blacklist[i].oem_revision)) {
139 138
140 printk(KERN_ERR PREFIX 139 printk(KERN_ERR PREFIX
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 766332e45592..c26468da4295 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -44,9 +44,6 @@ ACPI_MODULE_NAME("acpi_bus")
44extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); 44extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
45#endif 45#endif
46 46
47struct fadt_descriptor acpi_fadt;
48EXPORT_SYMBOL(acpi_fadt);
49
50struct acpi_device *acpi_root; 47struct acpi_device *acpi_root;
51struct proc_dir_entry *acpi_root_dir; 48struct proc_dir_entry *acpi_root_dir;
52EXPORT_SYMBOL(acpi_root_dir); 49EXPORT_SYMBOL(acpi_root_dir);
@@ -195,7 +192,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
195 192
196 if (!device->flags.power_manageable) { 193 if (!device->flags.power_manageable) {
197 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", 194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
198 device->kobj.name)); 195 device->dev.kobj.name));
199 return -ENODEV; 196 return -ENODEV;
200 } 197 }
201 /* 198 /*
@@ -582,11 +579,12 @@ static int __init acpi_bus_init_irq(void)
582 return 0; 579 return 0;
583} 580}
584 581
582acpi_native_uint acpi_gbl_permanent_mmap;
583
584
585void __init acpi_early_init(void) 585void __init acpi_early_init(void)
586{ 586{
587 acpi_status status = AE_OK; 587 acpi_status status = AE_OK;
588 struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
589
590 588
591 if (acpi_disabled) 589 if (acpi_disabled)
592 return; 590 return;
@@ -597,6 +595,15 @@ void __init acpi_early_init(void)
597 if (!acpi_strict) 595 if (!acpi_strict)
598 acpi_gbl_enable_interpreter_slack = TRUE; 596 acpi_gbl_enable_interpreter_slack = TRUE;
599 597
598 acpi_gbl_permanent_mmap = 1;
599
600 status = acpi_reallocate_root_table();
601 if (ACPI_FAILURE(status)) {
602 printk(KERN_ERR PREFIX
603 "Unable to reallocate ACPI tables\n");
604 goto error0;
605 }
606
600 status = acpi_initialize_subsystem(); 607 status = acpi_initialize_subsystem();
601 if (ACPI_FAILURE(status)) { 608 if (ACPI_FAILURE(status)) {
602 printk(KERN_ERR PREFIX 609 printk(KERN_ERR PREFIX
@@ -611,32 +618,25 @@ void __init acpi_early_init(void)
611 goto error0; 618 goto error0;
612 } 619 }
613 620
614 /*
615 * Get a separate copy of the FADT for use by other drivers.
616 */
617 status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer);
618 if (ACPI_FAILURE(status)) {
619 printk(KERN_ERR PREFIX "Unable to get the FADT\n");
620 goto error0;
621 }
622#ifdef CONFIG_X86 621#ifdef CONFIG_X86
623 if (!acpi_ioapic) { 622 if (!acpi_ioapic) {
624 extern acpi_interrupt_flags acpi_sci_flags; 623 extern u8 acpi_sci_flags;
625 624
626 /* compatible (0) means level (3) */ 625 /* compatible (0) means level (3) */
627 if (acpi_sci_flags.trigger == 0) 626 if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
628 acpi_sci_flags.trigger = 3; 627 acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
629 628 acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
629 }
630 /* Set PIC-mode SCI trigger type */ 630 /* Set PIC-mode SCI trigger type */
631 acpi_pic_sci_set_trigger(acpi_fadt.sci_int, 631 acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
632 acpi_sci_flags.trigger); 632 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
633 } else { 633 } else {
634 extern int acpi_sci_override_gsi; 634 extern int acpi_sci_override_gsi;
635 /* 635 /*
636 * now that acpi_fadt is initialized, 636 * now that acpi_gbl_FADT is initialized,
637 * update it with result from INT_SRC_OVR parsing 637 * update it with result from INT_SRC_OVR parsing
638 */ 638 */
639 acpi_fadt.sci_int = acpi_sci_override_gsi; 639 acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
640 } 640 }
641#endif 641#endif
642 642
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ac860583c203..c726612fafb6 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -75,7 +75,7 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
75static struct acpi_driver acpi_button_driver = { 75static struct acpi_driver acpi_button_driver = {
76 .name = ACPI_BUTTON_DRIVER_NAME, 76 .name = ACPI_BUTTON_DRIVER_NAME,
77 .class = ACPI_BUTTON_CLASS, 77 .class = ACPI_BUTTON_CLASS,
78 .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", 78 .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
79 .ops = { 79 .ops = {
80 .add = acpi_button_add, 80 .add = acpi_button_add,
81 .remove = acpi_button_remove, 81 .remove = acpi_button_remove,
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 0a1863ec91f3..69a68fd394cf 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -167,7 +167,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
167 if (ACPI_FAILURE(status) || !device) { 167 if (ACPI_FAILURE(status) || !device) {
168 result = container_device_add(&device, handle); 168 result = container_device_add(&device, handle);
169 if (!result) 169 if (!result)
170 kobject_uevent(&device->kobj, 170 kobject_uevent(&device->dev.kobj,
171 KOBJ_ONLINE); 171 KOBJ_ONLINE);
172 else 172 else
173 printk("Failed to add container\n"); 173 printk("Failed to add container\n");
@@ -175,13 +175,13 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
175 } else { 175 } else {
176 if (ACPI_SUCCESS(status)) { 176 if (ACPI_SUCCESS(status)) {
177 /* device exist and this is a remove request */ 177 /* device exist and this is a remove request */
178 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 178 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
179 } 179 }
180 } 180 }
181 break; 181 break;
182 case ACPI_NOTIFY_EJECT_REQUEST: 182 case ACPI_NOTIFY_EJECT_REQUEST:
183 if (!acpi_bus_get_device(handle, &device) && device) { 183 if (!acpi_bus_get_device(handle, &device) && device) {
184 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 184 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
185 } 185 }
186 break; 186 break;
187 default: 187 default:
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 35c6af8a83cd..d48f65a8f658 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,14 +13,11 @@
13 13
14#define _COMPONENT ACPI_SYSTEM_COMPONENT 14#define _COMPONENT ACPI_SYSTEM_COMPONENT
15ACPI_MODULE_NAME("debug") 15ACPI_MODULE_NAME("debug")
16#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" 16
17#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
18#ifdef MODULE_PARAM_PREFIX 17#ifdef MODULE_PARAM_PREFIX
19#undef MODULE_PARAM_PREFIX 18#undef MODULE_PARAM_PREFIX
20#endif 19#endif
21#define MODULE_PARAM_PREFIX 20#define MODULE_PARAM_PREFIX "acpi."
22 module_param(acpi_dbg_layer, uint, 0400);
23module_param(acpi_dbg_level, uint, 0400);
24 21
25struct acpi_dlayer { 22struct acpi_dlayer {
26 const char *name; 23 const char *name;
@@ -86,6 +83,60 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
86 ACPI_DEBUG_INIT(ACPI_LV_EVENTS), 83 ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
87}; 84};
88 85
86/* --------------------------------------------------------------------------
87 FS Interface (/sys)
88 -------------------------------------------------------------------------- */
89static int param_get_debug_layer(char *buffer, struct kernel_param *kp) {
90 int result = 0;
91 int i;
92
93 result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
94
95 for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) {
96 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
97 acpi_debug_layers[i].name,
98 acpi_debug_layers[i].value,
99 (acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' ');
100 }
101 result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
102 ACPI_ALL_DRIVERS,
103 (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
104 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
105 ACPI_ALL_DRIVERS) == 0 ? ' ' : '-');
106 result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer);
107
108 return result;
109}
110
111static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
112 int result = 0;
113 int i;
114
115 result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
116
117 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
118 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
119 acpi_debug_levels[i].name,
120 acpi_debug_levels[i].value,
121 (acpi_dbg_level & acpi_debug_levels[i].
122 value) ? '*' : ' ');
123 }
124 result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n",
125 acpi_dbg_level);
126
127 return result;
128}
129
130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644);
131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644);
132
133/* --------------------------------------------------------------------------
134 FS Interface (/proc)
135 -------------------------------------------------------------------------- */
136#ifdef CONFIG_ACPI_PROCFS
137#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer"
138#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
139
89static int 140static int
90acpi_system_read_debug(char *page, 141acpi_system_read_debug(char *page,
91 char **start, off_t off, int count, int *eof, void *data) 142 char **start, off_t off, int count, int *eof, void *data)
@@ -221,3 +272,4 @@ static int __init acpi_debug_init(void)
221} 272}
222 273
223subsys_initcall(acpi_debug_init); 274subsys_initcall(acpi_debug_init);
275#endif
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index a6d77efb41a0..f049639bac35 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -133,7 +133,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
133 } 133 }
134 } 134 }
135 135
136 /* We could put the returned object (Node) on the object stack for later, 136 /*
137 * We could put the returned object (Node) on the object stack for later,
137 * but for now, we will put it in the "op" object that the parser uses, 138 * but for now, we will put it in the "op" object that the parser uses,
138 * so we can get it again at the end of this scope 139 * so we can get it again at the end of this scope
139 */ 140 */
@@ -514,8 +515,33 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
514 515
515 /* Third arg is the bank_value */ 516 /* Third arg is the bank_value */
516 517
518 /* TBD: This arg is a term_arg, not a constant, and must be evaluated */
519
517 arg = arg->common.next; 520 arg = arg->common.next;
518 info.bank_value = (u32) arg->common.value.integer; 521
522 /* Currently, only the following constants are supported */
523
524 switch (arg->common.aml_opcode) {
525 case AML_ZERO_OP:
526 info.bank_value = 0;
527 break;
528
529 case AML_ONE_OP:
530 info.bank_value = 1;
531 break;
532
533 case AML_BYTE_OP:
534 case AML_WORD_OP:
535 case AML_DWORD_OP:
536 case AML_QWORD_OP:
537 info.bank_value = (u32) arg->common.value.integer;
538 break;
539
540 default:
541 info.bank_value = 0;
542 ACPI_ERROR((AE_INFO,
543 "Non-constant BankValue for BankField is not implemented"));
544 }
519 545
520 /* Fourth arg is the field flags */ 546 /* Fourth arg is the field flags */
521 547
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index 1888c055d10f..af923c388520 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acdispat.h> 45#include <acpi/acdispat.h>
46#include <acpi/acnamesp.h> 46#include <acpi/acnamesp.h>
47#include <acpi/actables.h>
47 48
48#define _COMPONENT ACPI_DISPATCHER 49#define _COMPONENT ACPI_DISPATCHER
49ACPI_MODULE_NAME("dsinit") 50ACPI_MODULE_NAME("dsinit")
@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
90 * We are only interested in NS nodes owned by the table that 91 * We are only interested in NS nodes owned by the table that
91 * was just loaded 92 * was just loaded
92 */ 93 */
93 if (node->owner_id != info->table_desc->owner_id) { 94 if (node->owner_id != info->owner_id) {
94 return (AE_OK); 95 return (AE_OK);
95 } 96 }
96 97
@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
150 ******************************************************************************/ 151 ******************************************************************************/
151 152
152acpi_status 153acpi_status
153acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, 154acpi_ds_initialize_objects(acpi_native_uint table_index,
154 struct acpi_namespace_node * start_node) 155 struct acpi_namespace_node * start_node)
155{ 156{
156 acpi_status status; 157 acpi_status status;
157 struct acpi_init_walk_info info; 158 struct acpi_init_walk_info info;
159 struct acpi_table_header *table;
160 acpi_owner_id owner_id;
158 161
159 ACPI_FUNCTION_TRACE(ds_initialize_objects); 162 ACPI_FUNCTION_TRACE(ds_initialize_objects);
160 163
164 status = acpi_tb_get_owner_id(table_index, &owner_id);
165 if (ACPI_FAILURE(status)) {
166 return_ACPI_STATUS(status);
167 }
168
161 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 169 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
162 "**** Starting initialization of namespace objects ****\n")); 170 "**** Starting initialization of namespace objects ****\n"));
163 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); 171 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
166 info.op_region_count = 0; 174 info.op_region_count = 0;
167 info.object_count = 0; 175 info.object_count = 0;
168 info.device_count = 0; 176 info.device_count = 0;
169 info.table_desc = table_desc; 177 info.table_index = table_index;
178 info.owner_id = owner_id;
170 179
171 /* Walk entire namespace from the supplied root */ 180 /* Walk entire namespace from the supplied root */
172 181
@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
176 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); 185 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
177 } 186 }
178 187
188 status = acpi_get_table_by_index(table_index, &table);
189 if (ACPI_FAILURE(status)) {
190 return_ACPI_STATUS(status);
191 }
192
179 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, 193 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
180 "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", 194 "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
181 table_desc->pointer->signature, 195 table->signature, owner_id, info.object_count,
182 table_desc->owner_id, info.object_count,
183 info.device_count, info.method_count, 196 info.device_count, info.method_count,
184 info.op_region_count)); 197 info.op_region_count));
185 198
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index cf888add3191..1cbe61905824 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
327 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); 327 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
328 328
329 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 329 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
330 "Execute method %p, currentstate=%p\n", 330 "Calling method %p, currentstate=%p\n",
331 this_walk_state->prev_op, this_walk_state)); 331 this_walk_state->prev_op, this_walk_state));
332 332
333 /* 333 /*
@@ -351,49 +351,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
351 return_ACPI_STATUS(status); 351 return_ACPI_STATUS(status);
352 } 352 }
353 353
354 /* 354 /* Begin method parse/execution. Create a new walk state */
355 * 1) Parse the method. All "normal" methods are parsed for each execution.
356 * Internal methods (_OSI, etc.) do not require parsing.
357 */
358 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
359
360 /* Create a new walk state for the parse */
361
362 next_walk_state =
363 acpi_ds_create_walk_state(obj_desc->method.owner_id, op,
364 obj_desc, NULL);
365 if (!next_walk_state) {
366 status = AE_NO_MEMORY;
367 goto cleanup;
368 }
369
370 /* Create and init a parse tree root */
371
372 op = acpi_ps_create_scope_op();
373 if (!op) {
374 status = AE_NO_MEMORY;
375 goto cleanup;
376 }
377
378 status = acpi_ds_init_aml_walk(next_walk_state, op, method_node,
379 obj_desc->method.aml_start,
380 obj_desc->method.aml_length,
381 NULL, 1);
382 if (ACPI_FAILURE(status)) {
383 acpi_ps_delete_parse_tree(op);
384 goto cleanup;
385 }
386
387 /* Begin AML parse (deletes next_walk_state) */
388
389 status = acpi_ps_parse_aml(next_walk_state);
390 acpi_ps_delete_parse_tree(op);
391 if (ACPI_FAILURE(status)) {
392 goto cleanup;
393 }
394 }
395
396 /* 2) Begin method execution. Create a new walk state */
397 355
398 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, 356 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
399 NULL, obj_desc, thread); 357 NULL, obj_desc, thread);
@@ -424,7 +382,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
424 382
425 status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, 383 status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
426 obj_desc->method.aml_start, 384 obj_desc->method.aml_start,
427 obj_desc->method.aml_length, info, 3); 385 obj_desc->method.aml_length, info,
386 ACPI_IMODE_EXECUTE);
428 387
429 ACPI_FREE(info); 388 ACPI_FREE(info);
430 if (ACPI_FAILURE(status)) { 389 if (ACPI_FAILURE(status)) {
@@ -445,8 +404,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
445 this_walk_state->num_operands = 0; 404 this_walk_state->num_operands = 0;
446 405
447 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 406 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
448 "Starting nested execution, newstate=%p\n", 407 "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
449 next_walk_state)); 408 method_node->name.ascii, next_walk_state));
450 409
451 /* Invoke an internal method if necessary */ 410 /* Invoke an internal method if necessary */
452 411
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 459160ff9058..ba4626e06a5e 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 72190abb1d59..a474ca2334d5 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -260,7 +260,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
260 } 260 }
261 261
262 obj_desc->buffer.flags |= AOPOBJ_DATA_VALID; 262 obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
263 op->common.node = (struct acpi_namespace_node *)obj_desc; 263 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
264 return_ACPI_STATUS(AE_OK); 264 return_ACPI_STATUS(AE_OK);
265} 265}
266 266
@@ -270,7 +270,8 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
270 * 270 *
271 * PARAMETERS: walk_state - Current walk state 271 * PARAMETERS: walk_state - Current walk state
272 * Op - Parser object to be translated 272 * Op - Parser object to be translated
273 * package_length - Number of elements in the package 273 * element_count - Number of elements in the package - this is
274 * the num_elements argument to Package()
274 * obj_desc_ptr - Where the ACPI internal object is returned 275 * obj_desc_ptr - Where the ACPI internal object is returned
275 * 276 *
276 * RETURN: Status 277 * RETURN: Status
@@ -278,18 +279,29 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
278 * DESCRIPTION: Translate a parser Op package object to the equivalent 279 * DESCRIPTION: Translate a parser Op package object to the equivalent
279 * namespace object 280 * namespace object
280 * 281 *
282 * NOTE: The number of elements in the package will be always be the num_elements
283 * count, regardless of the number of elements in the package list. If
284 * num_elements is smaller, only that many package list elements are used.
285 * if num_elements is larger, the Package object is padded out with
286 * objects of type Uninitialized (as per ACPI spec.)
287 *
288 * Even though the ASL compilers do not allow num_elements to be smaller
289 * than the Package list length (for the fixed length package opcode), some
290 * BIOS code modifies the AML on the fly to adjust the num_elements, and
291 * this code compensates for that. This also provides compatibility with
292 * other AML interpreters.
293 *
281 ******************************************************************************/ 294 ******************************************************************************/
282 295
283acpi_status 296acpi_status
284acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, 297acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
285 union acpi_parse_object *op, 298 union acpi_parse_object *op,
286 u32 package_length, 299 u32 element_count,
287 union acpi_operand_object **obj_desc_ptr) 300 union acpi_operand_object **obj_desc_ptr)
288{ 301{
289 union acpi_parse_object *arg; 302 union acpi_parse_object *arg;
290 union acpi_parse_object *parent; 303 union acpi_parse_object *parent;
291 union acpi_operand_object *obj_desc = NULL; 304 union acpi_operand_object *obj_desc = NULL;
292 u32 package_list_length;
293 acpi_status status = AE_OK; 305 acpi_status status = AE_OK;
294 acpi_native_uint i; 306 acpi_native_uint i;
295 307
@@ -318,32 +330,13 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
318 obj_desc->package.node = parent->common.node; 330 obj_desc->package.node = parent->common.node;
319 } 331 }
320 332
321 obj_desc->package.count = package_length;
322
323 /* Count the number of items in the package list */
324
325 arg = op->common.value.arg;
326 arg = arg->common.next;
327 for (package_list_length = 0; arg; package_list_length++) {
328 arg = arg->common.next;
329 }
330
331 /*
332 * The package length (number of elements) will be the greater
333 * of the specified length and the length of the initializer list
334 */
335 if (package_list_length > package_length) {
336 obj_desc->package.count = package_list_length;
337 }
338
339 /* 333 /*
340 * Allocate the pointer array (array of pointers to the 334 * Allocate the element array (array of pointers to the individual
341 * individual objects). Add an extra pointer slot so 335 * objects) based on the num_elements parameter. Add an extra pointer slot
342 * that the list is always null terminated. 336 * so that the list is always null terminated.
343 */ 337 */
344 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) 338 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
345 obj_desc->package. 339 element_count +
346 count +
347 1) * sizeof(void *)); 340 1) * sizeof(void *));
348 341
349 if (!obj_desc->package.elements) { 342 if (!obj_desc->package.elements) {
@@ -351,15 +344,20 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
351 return_ACPI_STATUS(AE_NO_MEMORY); 344 return_ACPI_STATUS(AE_NO_MEMORY);
352 } 345 }
353 346
347 obj_desc->package.count = element_count;
348
354 /* 349 /*
355 * Initialize all elements of the package 350 * Initialize the elements of the package, up to the num_elements count.
351 * Package is automatically padded with uninitialized (NULL) elements
352 * if num_elements is greater than the package list length. Likewise,
353 * Package is truncated if num_elements is less than the list length.
356 */ 354 */
357 arg = op->common.value.arg; 355 arg = op->common.value.arg;
358 arg = arg->common.next; 356 arg = arg->common.next;
359 for (i = 0; arg; i++) { 357 for (i = 0; arg && (i < element_count); i++) {
360 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 358 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
361 359
362 /* Object (package or buffer) is already built */ 360 /* This package element is already built, just get it */
363 361
364 obj_desc->package.elements[i] = 362 obj_desc->package.elements[i] =
365 ACPI_CAST_PTR(union acpi_operand_object, 363 ACPI_CAST_PTR(union acpi_operand_object,
@@ -373,8 +371,14 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
373 arg = arg->common.next; 371 arg = arg->common.next;
374 } 372 }
375 373
374 if (!arg) {
375 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
376 "Package List length larger than NumElements count (%X), truncated\n",
377 element_count));
378 }
379
376 obj_desc->package.flags |= AOPOBJ_DATA_VALID; 380 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
377 op->common.node = (struct acpi_namespace_node *)obj_desc; 381 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
378 return_ACPI_STATUS(status); 382 return_ACPI_STATUS(status);
379} 383}
380 384
@@ -488,8 +492,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
488 /* 492 /*
489 * Defer evaluation of Buffer term_arg operand 493 * Defer evaluation of Buffer term_arg operand
490 */ 494 */
491 obj_desc->buffer.node = (struct acpi_namespace_node *) 495 obj_desc->buffer.node =
492 walk_state->operands[0]; 496 ACPI_CAST_PTR(struct acpi_namespace_node,
497 walk_state->operands[0]);
493 obj_desc->buffer.aml_start = op->named.data; 498 obj_desc->buffer.aml_start = op->named.data;
494 obj_desc->buffer.aml_length = op->named.length; 499 obj_desc->buffer.aml_length = op->named.length;
495 break; 500 break;
@@ -499,8 +504,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
499 /* 504 /*
500 * Defer evaluation of Package term_arg operand 505 * Defer evaluation of Package term_arg operand
501 */ 506 */
502 obj_desc->package.node = (struct acpi_namespace_node *) 507 obj_desc->package.node =
503 walk_state->operands[0]; 508 ACPI_CAST_PTR(struct acpi_namespace_node,
509 walk_state->operands[0]);
504 obj_desc->package.aml_start = op->named.data; 510 obj_desc->package.aml_start = op->named.data;
505 obj_desc->package.aml_length = op->named.length; 511 obj_desc->package.aml_length = op->named.length;
506 break; 512 break;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 5b974a8fe614..6c6104a7a247 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -114,7 +114,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node,
114 } 114 }
115 115
116 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 116 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
117 aml_length, NULL, 1); 117 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
118 if (ACPI_FAILURE(status)) { 118 if (ACPI_FAILURE(status)) {
119 acpi_ds_delete_walk_state(walk_state); 119 acpi_ds_delete_walk_state(walk_state);
120 goto cleanup; 120 goto cleanup;
@@ -157,7 +157,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node,
157 /* Execute the opcode and arguments */ 157 /* Execute the opcode and arguments */
158 158
159 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 159 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
160 aml_length, NULL, 3); 160 aml_length, NULL, ACPI_IMODE_EXECUTE);
161 if (ACPI_FAILURE(status)) { 161 if (ACPI_FAILURE(status)) {
162 acpi_ds_delete_walk_state(walk_state); 162 acpi_ds_delete_walk_state(walk_state);
163 goto cleanup; 163 goto cleanup;
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 05230baf5de8..e4073e05a75c 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index d7a616c3104e..69693fa07224 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -219,7 +219,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
219 if (!op) { 219 if (!op) {
220 status = acpi_ds_load2_begin_op(walk_state, out_op); 220 status = acpi_ds_load2_begin_op(walk_state, out_op);
221 if (ACPI_FAILURE(status)) { 221 if (ACPI_FAILURE(status)) {
222 return_ACPI_STATUS(status); 222 goto error_exit;
223 } 223 }
224 224
225 op = *out_op; 225 op = *out_op;
@@ -238,7 +238,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
238 238
239 status = acpi_ds_scope_stack_pop(walk_state); 239 status = acpi_ds_scope_stack_pop(walk_state);
240 if (ACPI_FAILURE(status)) { 240 if (ACPI_FAILURE(status)) {
241 return_ACPI_STATUS(status); 241 goto error_exit;
242 } 242 }
243 } 243 }
244 } 244 }
@@ -287,7 +287,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
287 287
288 status = acpi_ds_result_stack_push(walk_state); 288 status = acpi_ds_result_stack_push(walk_state);
289 if (ACPI_FAILURE(status)) { 289 if (ACPI_FAILURE(status)) {
290 return_ACPI_STATUS(status); 290 goto error_exit;
291 } 291 }
292 292
293 status = acpi_ds_exec_begin_control_op(walk_state, op); 293 status = acpi_ds_exec_begin_control_op(walk_state, op);
@@ -328,6 +328,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
328 /* Nothing to do here during method execution */ 328 /* Nothing to do here during method execution */
329 329
330 return_ACPI_STATUS(status); 330 return_ACPI_STATUS(status);
331
332 error_exit:
333 status = acpi_ds_method_error(status, walk_state);
334 return_ACPI_STATUS(status);
331} 335}
332 336
333/***************************************************************************** 337/*****************************************************************************
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index e3ca7f6539c1..8ab9d1b29a4c 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -196,6 +196,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
196 * one of the opcodes that actually opens a scope 196 * one of the opcodes that actually opens a scope
197 */ 197 */
198 switch (node->type) { 198 switch (node->type) {
199 case ACPI_TYPE_ANY:
199 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ 200 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
200 case ACPI_TYPE_DEVICE: 201 case ACPI_TYPE_DEVICE:
201 case ACPI_TYPE_POWER: 202 case ACPI_TYPE_POWER:
@@ -546,6 +547,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
546 acpi_status status; 547 acpi_status status;
547 acpi_object_type object_type; 548 acpi_object_type object_type;
548 char *buffer_ptr; 549 char *buffer_ptr;
550 u32 flags;
549 551
550 ACPI_FUNCTION_TRACE(ds_load2_begin_op); 552 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
551 553
@@ -669,6 +671,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
669 * one of the opcodes that actually opens a scope 671 * one of the opcodes that actually opens a scope
670 */ 672 */
671 switch (node->type) { 673 switch (node->type) {
674 case ACPI_TYPE_ANY:
672 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ 675 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
673 case ACPI_TYPE_DEVICE: 676 case ACPI_TYPE_DEVICE:
674 case ACPI_TYPE_POWER: 677 case ACPI_TYPE_POWER:
@@ -750,12 +753,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
750 break; 753 break;
751 } 754 }
752 755
753 /* Add new entry into namespace */ 756 flags = ACPI_NS_NO_UPSEARCH;
757 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
758
759 /* Execution mode, node cannot already exist, node is temporary */
760
761 flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY);
762 }
763
764 /* Add new entry or lookup existing entry */
754 765
755 status = 766 status =
756 acpi_ns_lookup(walk_state->scope_info, buffer_ptr, 767 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
757 object_type, ACPI_IMODE_LOAD_PASS2, 768 object_type, ACPI_IMODE_LOAD_PASS2, flags,
758 ACPI_NS_NO_UPSEARCH, walk_state, &(node)); 769 walk_state, &node);
759 break; 770 break;
760 } 771 }
761 772
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index c9228972f5f6..3927c495e4bf 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 7817e5522679..16c8e38b51ef 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 90990a4b6526..688e83a16906 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -615,20 +615,28 @@ static acpi_status
615find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) 615find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
616{ 616{
617 acpi_status status; 617 acpi_status status;
618 acpi_handle tmp; 618 acpi_handle tmp, parent;
619 struct dock_station *ds = context; 619 struct dock_station *ds = context;
620 struct dock_dependent_device *dd; 620 struct dock_dependent_device *dd;
621 621
622 status = acpi_bus_get_ejd(handle, &tmp); 622 status = acpi_bus_get_ejd(handle, &tmp);
623 if (ACPI_FAILURE(status)) 623 if (ACPI_FAILURE(status)) {
624 return AE_OK; 624 /* try the parent device as well */
625 status = acpi_get_parent(handle, &parent);
626 if (ACPI_FAILURE(status))
627 goto fdd_out;
628 /* see if parent is dependent on dock */
629 status = acpi_bus_get_ejd(parent, &tmp);
630 if (ACPI_FAILURE(status))
631 goto fdd_out;
632 }
625 633
626 if (tmp == ds->handle) { 634 if (tmp == ds->handle) {
627 dd = alloc_dock_dependent_device(handle); 635 dd = alloc_dock_dependent_device(handle);
628 if (dd) 636 if (dd)
629 add_dock_dependent_device(ds, dd); 637 add_dock_dependent_device(ds, dd);
630 } 638 }
631 639fdd_out:
632 return AE_OK; 640 return AE_OK;
633} 641}
634 642
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index cbdf031f3c09..743ce27fa0bb 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -872,9 +872,8 @@ static int __init acpi_ec_get_real_ecdt(void)
872 acpi_status status; 872 acpi_status status;
873 struct acpi_table_ecdt *ecdt_ptr; 873 struct acpi_table_ecdt *ecdt_ptr;
874 874
875 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 875 status = acpi_get_table(ACPI_SIG_ECDT, 1,
876 (struct acpi_table_header **) 876 (struct acpi_table_header **)&ecdt_ptr);
877 &ecdt_ptr);
878 if (ACPI_FAILURE(status)) 877 if (ACPI_FAILURE(status))
879 return -ENODEV; 878 return -ENODEV;
880 879
@@ -891,14 +890,14 @@ static int __init acpi_ec_get_real_ecdt(void)
891 if (acpi_ec_mode == EC_INTR) { 890 if (acpi_ec_mode == EC_INTR) {
892 init_waitqueue_head(&ec_ecdt->wait); 891 init_waitqueue_head(&ec_ecdt->wait);
893 } 892 }
894 ec_ecdt->command_addr = ecdt_ptr->ec_control.address; 893 ec_ecdt->command_addr = ecdt_ptr->control.address;
895 ec_ecdt->data_addr = ecdt_ptr->ec_data.address; 894 ec_ecdt->data_addr = ecdt_ptr->data.address;
896 ec_ecdt->gpe = ecdt_ptr->gpe_bit; 895 ec_ecdt->gpe = ecdt_ptr->gpe;
897 /* use the GL just to be safe */ 896 /* use the GL just to be safe */
898 ec_ecdt->global_lock = TRUE; 897 ec_ecdt->global_lock = TRUE;
899 ec_ecdt->uid = ecdt_ptr->uid; 898 ec_ecdt->uid = ecdt_ptr->uid;
900 899
901 status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); 900 status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle);
902 if (ACPI_FAILURE(status)) { 901 if (ACPI_FAILURE(status)) {
903 goto error; 902 goto error;
904 } 903 }
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 919037d6acff..a1f87b5def2a 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void)
70 70
71 ACPI_FUNCTION_TRACE(ev_initialize_events); 71 ACPI_FUNCTION_TRACE(ev_initialize_events);
72 72
73 /* Make sure we have ACPI tables */
74
75 if (!acpi_gbl_DSDT) {
76 ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
77 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
78 }
79
80 /* 73 /*
81 * Initialize the Fixed and General Purpose Events. This is done prior to 74 * Initialize the Fixed and General Purpose Events. This is done prior to
82 * enabling SCIs to prevent interrupts from occurring before the handlers are 75 * enabling SCIs to prevent interrupts from occurring before the handlers are
@@ -211,8 +204,7 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
211 if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { 204 if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
212 status = 205 status =
213 acpi_set_register(acpi_gbl_fixed_event_info[i]. 206 acpi_set_register(acpi_gbl_fixed_event_info[i].
214 enable_register_id, 0, 207 enable_register_id, 0);
215 ACPI_MTX_LOCK);
216 if (ACPI_FAILURE(status)) { 208 if (ACPI_FAILURE(status)) {
217 return (status); 209 return (status);
218 } 210 }
@@ -298,7 +290,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
298 /* Clear the status bit */ 290 /* Clear the status bit */
299 291
300 (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. 292 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
301 status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); 293 status_register_id, 1);
302 294
303 /* 295 /*
304 * Make sure we've got a handler. If not, report an error. 296 * Make sure we've got a handler. If not, report an error.
@@ -306,8 +298,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
306 */ 298 */
307 if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { 299 if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
308 (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. 300 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
309 enable_register_id, 0, 301 enable_register_id, 0);
310 ACPI_MTX_DO_NOT_LOCK);
311 302
312 ACPI_ERROR((AE_INFO, 303 ACPI_ERROR((AE_INFO,
313 "No installed handler for fixed event [%08X]", 304 "No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index c76c0583ca6a..dfac3ecc596e 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -121,7 +121,9 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
121 if (!gpe_register_info) { 121 if (!gpe_register_info) {
122 return_ACPI_STATUS(AE_NOT_EXIST); 122 return_ACPI_STATUS(AE_NOT_EXIST);
123 } 123 }
124 register_bit = gpe_event_info->register_bit; 124 register_bit = (u8)
125 (1 <<
126 (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
125 127
126 /* 1) Disable case. Simply clear all enable bits */ 128 /* 1) Disable case. Simply clear all enable bits */
127 129
@@ -458,8 +460,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
458 460
459 /* Examine one GPE bit */ 461 /* Examine one GPE bit */
460 462
461 if (enabled_status_byte & 463 if (enabled_status_byte & (1 << j)) {
462 acpi_gbl_decode_to8bit[j]) {
463 /* 464 /*
464 * Found an active GPE. Dispatch the event to a handler 465 * Found an active GPE. Dispatch the event to a handler
465 * or method. 466 * or method.
@@ -570,7 +571,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
570 571
571 if (ACPI_FAILURE(status)) { 572 if (ACPI_FAILURE(status)) {
572 ACPI_EXCEPTION((AE_INFO, status, 573 ACPI_EXCEPTION((AE_INFO, status,
573 "While evaluating GPE method [%4.4s]", 574 "while evaluating GPE method [%4.4s]",
574 acpi_ut_get_node_name 575 acpi_ut_get_node_name
575 (local_gpe_event_info.dispatch. 576 (local_gpe_event_info.dispatch.
576 method_node))); 577 method_node)));
@@ -618,6 +619,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
618 619
619 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 620 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
620 621
622 acpi_gpe_count++;
623
621 /* 624 /*
622 * If edge-triggered, clear the GPE status bit now. Note that 625 * If edge-triggered, clear the GPE status bit now. Note that
623 * level-triggered events are cleared after the GPE is serviced. 626 * level-triggered events are cleared after the GPE is serviced.
@@ -633,20 +636,23 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
633 } 636 }
634 } 637 }
635 638
636 /* Save current system state */ 639 if (!acpi_gbl_system_awake_and_running) {
637 640 /*
638 if (acpi_gbl_system_awake_and_running) { 641 * We just woke up because of a wake GPE. Disable any further GPEs
639 ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); 642 * until we are fully up and running (Only wake GPEs should be enabled
640 } else { 643 * at this time, but we just brute-force disable them all.)
641 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); 644 * 1) We must disable this particular wake GPE so it won't fire again
645 * 2) We want to disable all wake GPEs, since we are now awake
646 */
647 (void)acpi_hw_disable_all_gpes();
642 } 648 }
643 649
644 /* 650 /*
645 * Dispatch the GPE to either an installed handler, or the control 651 * Dispatch the GPE to either an installed handler, or the control method
646 * method associated with this GPE (_Lxx or _Exx). 652 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
647 * If a handler exists, we invoke it and do not attempt to run the method. 653 * it and do not attempt to run the method. If there is neither a handler
648 * If there is neither a handler nor a method, we disable the level to 654 * nor a method, we disable this GPE to prevent further such pointless
649 * prevent further events from coming in here. 655 * events from firing.
650 */ 656 */
651 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 657 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
652 case ACPI_GPE_DISPATCH_HANDLER: 658 case ACPI_GPE_DISPATCH_HANDLER:
@@ -677,8 +683,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
677 case ACPI_GPE_DISPATCH_METHOD: 683 case ACPI_GPE_DISPATCH_METHOD:
678 684
679 /* 685 /*
680 * Disable GPE, so it doesn't keep firing before the method has a 686 * Disable the GPE, so it doesn't keep firing before the method has a
681 * chance to run. 687 * chance to run (it runs asynchronously with interrupts enabled).
682 */ 688 */
683 status = acpi_ev_disable_gpe(gpe_event_info); 689 status = acpi_ev_disable_gpe(gpe_event_info);
684 if (ACPI_FAILURE(status)) { 690 if (ACPI_FAILURE(status)) {
@@ -711,7 +717,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
711 gpe_number)); 717 gpe_number));
712 718
713 /* 719 /*
714 * Disable the GPE. The GPE will remain disabled until the ACPI 720 * Disable the GPE. The GPE will remain disabled until the ACPI
715 * Core Subsystem is restarted, or a handler is installed. 721 * Core Subsystem is restarted, or a handler is installed.
716 */ 722 */
717 status = acpi_ev_disable_gpe(gpe_event_info); 723 status = acpi_ev_disable_gpe(gpe_event_info);
@@ -726,50 +732,3 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
726 732
727 return_UINT32(ACPI_INTERRUPT_HANDLED); 733 return_UINT32(ACPI_INTERRUPT_HANDLED);
728} 734}
729
730#ifdef ACPI_GPE_NOTIFY_CHECK
731/*******************************************************************************
732 * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
733 *
734 * FUNCTION: acpi_ev_check_for_wake_only_gpe
735 *
736 * PARAMETERS: gpe_event_info - info for this GPE
737 *
738 * RETURN: Status
739 *
740 * DESCRIPTION: Determine if a a GPE is "wake-only".
741 *
742 * Called from Notify() code in interpreter when a "DeviceWake"
743 * Notify comes in.
744 *
745 ******************************************************************************/
746
747acpi_status
748acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info)
749{
750 acpi_status status;
751
752 ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe);
753
754 if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */
755 ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */
756 /* This must be a wake-only GPE, disable it */
757
758 status = acpi_ev_disable_gpe(gpe_event_info);
759
760 /* Set GPE to wake-only. Do not change wake disabled/enabled status */
761
762 acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
763
764 ACPI_INFO((AE_INFO,
765 "GPE %p was updated from wake/run to wake-only",
766 gpe_event_info));
767
768 /* This was a wake-only GPE */
769
770 return_ACPI_STATUS(AE_WAKE_ONLY_GPE);
771 }
772
773 return_ACPI_STATUS(AE_OK);
774}
775#endif
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 95ddeb48bc0f..ad5bc76edf46 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
529 529
530 /* Install new interrupt handler if not SCI_INT */ 530 /* Install new interrupt handler if not SCI_INT */
531 531
532 if (interrupt_number != acpi_gbl_FADT->sci_int) { 532 if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
533 status = acpi_os_install_interrupt_handler(interrupt_number, 533 status = acpi_os_install_interrupt_handler(interrupt_number,
534 acpi_ev_gpe_xrupt_handler, 534 acpi_ev_gpe_xrupt_handler,
535 gpe_xrupt); 535 gpe_xrupt);
@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
567 567
568 /* We never want to remove the SCI interrupt handler */ 568 /* We never want to remove the SCI interrupt handler */
569 569
570 if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) { 570 if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
571 gpe_xrupt->gpe_block_list_head = NULL; 571 gpe_xrupt->gpe_block_list_head = NULL;
572 return_ACPI_STATUS(AE_OK); 572 return_ACPI_STATUS(AE_OK);
573 } 573 }
@@ -796,30 +796,31 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
796 (u8) (gpe_block->block_base_number + 796 (u8) (gpe_block->block_base_number +
797 (i * ACPI_GPE_REGISTER_WIDTH)); 797 (i * ACPI_GPE_REGISTER_WIDTH));
798 798
799 ACPI_STORE_ADDRESS(this_register->status_address.address, 799 this_register->status_address.address =
800 (gpe_block->block_address.address + i)); 800 gpe_block->block_address.address + i;
801 801
802 ACPI_STORE_ADDRESS(this_register->enable_address.address, 802 this_register->enable_address.address =
803 (gpe_block->block_address.address 803 gpe_block->block_address.address + i +
804 + i + gpe_block->register_count)); 804 gpe_block->register_count;
805 805
806 this_register->status_address.address_space_id = 806 this_register->status_address.space_id =
807 gpe_block->block_address.address_space_id; 807 gpe_block->block_address.space_id;
808 this_register->enable_address.address_space_id = 808 this_register->enable_address.space_id =
809 gpe_block->block_address.address_space_id; 809 gpe_block->block_address.space_id;
810 this_register->status_address.register_bit_width = 810 this_register->status_address.bit_width =
811 ACPI_GPE_REGISTER_WIDTH; 811 ACPI_GPE_REGISTER_WIDTH;
812 this_register->enable_address.register_bit_width = 812 this_register->enable_address.bit_width =
813 ACPI_GPE_REGISTER_WIDTH; 813 ACPI_GPE_REGISTER_WIDTH;
814 this_register->status_address.register_bit_offset = 814 this_register->status_address.bit_offset =
815 ACPI_GPE_REGISTER_WIDTH; 815 ACPI_GPE_REGISTER_WIDTH;
816 this_register->enable_address.register_bit_offset = 816 this_register->enable_address.bit_offset =
817 ACPI_GPE_REGISTER_WIDTH; 817 ACPI_GPE_REGISTER_WIDTH;
818 818
819 /* Init the event_info for each GPE within this register */ 819 /* Init the event_info for each GPE within this register */
820 820
821 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 821 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
822 this_event->register_bit = acpi_gbl_decode_to8bit[j]; 822 this_event->gpe_number =
823 (u8) (this_register->base_gpe_number + j);
823 this_event->register_info = this_register; 824 this_event->register_info = this_register;
824 this_event++; 825 this_event++;
825 } 826 }
@@ -1109,11 +1110,12 @@ acpi_status acpi_ev_gpe_initialize(void)
1109 * If EITHER the register length OR the block address are zero, then that 1110 * If EITHER the register length OR the block address are zero, then that
1110 * particular block is not supported. 1111 * particular block is not supported.
1111 */ 1112 */
1112 if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { 1113 if (acpi_gbl_FADT.gpe0_block_length &&
1114 acpi_gbl_FADT.xgpe0_block.address) {
1113 1115
1114 /* GPE block 0 exists (has both length and address > 0) */ 1116 /* GPE block 0 exists (has both length and address > 0) */
1115 1117
1116 register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); 1118 register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2);
1117 1119
1118 gpe_number_max = 1120 gpe_number_max =
1119 (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; 1121 (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
@@ -1121,9 +1123,9 @@ acpi_status acpi_ev_gpe_initialize(void)
1121 /* Install GPE Block 0 */ 1123 /* Install GPE Block 0 */
1122 1124
1123 status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, 1125 status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
1124 &acpi_gbl_FADT->xgpe0_blk, 1126 &acpi_gbl_FADT.xgpe0_block,
1125 register_count0, 0, 1127 register_count0, 0,
1126 acpi_gbl_FADT->sci_int, 1128 acpi_gbl_FADT.sci_interrupt,
1127 &acpi_gbl_gpe_fadt_blocks[0]); 1129 &acpi_gbl_gpe_fadt_blocks[0]);
1128 1130
1129 if (ACPI_FAILURE(status)) { 1131 if (ACPI_FAILURE(status)) {
@@ -1132,20 +1134,21 @@ acpi_status acpi_ev_gpe_initialize(void)
1132 } 1134 }
1133 } 1135 }
1134 1136
1135 if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { 1137 if (acpi_gbl_FADT.gpe1_block_length &&
1138 acpi_gbl_FADT.xgpe1_block.address) {
1136 1139
1137 /* GPE block 1 exists (has both length and address > 0) */ 1140 /* GPE block 1 exists (has both length and address > 0) */
1138 1141
1139 register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); 1142 register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2);
1140 1143
1141 /* Check for GPE0/GPE1 overlap (if both banks exist) */ 1144 /* Check for GPE0/GPE1 overlap (if both banks exist) */
1142 1145
1143 if ((register_count0) && 1146 if ((register_count0) &&
1144 (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { 1147 (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
1145 ACPI_ERROR((AE_INFO, 1148 ACPI_ERROR((AE_INFO,
1146 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", 1149 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
1147 gpe_number_max, acpi_gbl_FADT->gpe1_base, 1150 gpe_number_max, acpi_gbl_FADT.gpe1_base,
1148 acpi_gbl_FADT->gpe1_base + 1151 acpi_gbl_FADT.gpe1_base +
1149 ((register_count1 * 1152 ((register_count1 *
1150 ACPI_GPE_REGISTER_WIDTH) - 1))); 1153 ACPI_GPE_REGISTER_WIDTH) - 1)));
1151 1154
@@ -1157,10 +1160,11 @@ acpi_status acpi_ev_gpe_initialize(void)
1157 1160
1158 status = 1161 status =
1159 acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, 1162 acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
1160 &acpi_gbl_FADT->xgpe1_blk, 1163 &acpi_gbl_FADT.xgpe1_block,
1161 register_count1, 1164 register_count1,
1162 acpi_gbl_FADT->gpe1_base, 1165 acpi_gbl_FADT.gpe1_base,
1163 acpi_gbl_FADT->sci_int, 1166 acpi_gbl_FADT.
1167 sci_interrupt,
1164 &acpi_gbl_gpe_fadt_blocks 1168 &acpi_gbl_gpe_fadt_blocks
1165 [1]); 1169 [1]);
1166 1170
@@ -1173,7 +1177,7 @@ acpi_status acpi_ev_gpe_initialize(void)
1173 * GPE0 and GPE1 do not have to be contiguous in the GPE number 1177 * GPE0 and GPE1 do not have to be contiguous in the GPE number
1174 * space. However, GPE0 always starts at GPE number zero. 1178 * space. However, GPE0 always starts at GPE number zero.
1175 */ 1179 */
1176 gpe_number_max = acpi_gbl_FADT->gpe1_base + 1180 gpe_number_max = acpi_gbl_FADT.gpe1_base +
1177 ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); 1181 ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
1178 } 1182 }
1179 } 1183 }
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index bf63edc6608d..1b784ffe54c3 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -63,14 +63,18 @@ static const char *acpi_notify_value_names[] = {
63}; 63};
64#endif 64#endif
65 65
66/* Pointer to FACS needed for the Global Lock */
67
68static struct acpi_table_facs *facs = NULL;
69
66/* Local prototypes */ 70/* Local prototypes */
67 71
68static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); 72static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
69 73
70static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context);
71
72static u32 acpi_ev_global_lock_handler(void *context); 74static u32 acpi_ev_global_lock_handler(void *context);
73 75
76static acpi_status acpi_ev_remove_global_lock_handler(void);
77
74/******************************************************************************* 78/*******************************************************************************
75 * 79 *
76 * FUNCTION: acpi_ev_is_notify_object 80 * FUNCTION: acpi_ev_is_notify_object
@@ -282,49 +286,19 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
282 286
283/******************************************************************************* 287/*******************************************************************************
284 * 288 *
285 * FUNCTION: acpi_ev_global_lock_thread
286 *
287 * PARAMETERS: Context - From thread interface, not used
288 *
289 * RETURN: None
290 *
291 * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the
292 * Global Lock. Simply signal all threads that are waiting
293 * for the lock.
294 *
295 ******************************************************************************/
296
297static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context)
298{
299 acpi_status status;
300
301 /* Signal threads that are waiting for the lock */
302
303 if (acpi_gbl_global_lock_thread_count) {
304
305 /* Send sufficient units to the semaphore */
306
307 status =
308 acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore,
309 acpi_gbl_global_lock_thread_count);
310 if (ACPI_FAILURE(status)) {
311 ACPI_ERROR((AE_INFO,
312 "Could not signal Global Lock semaphore"));
313 }
314 }
315}
316
317/*******************************************************************************
318 *
319 * FUNCTION: acpi_ev_global_lock_handler 289 * FUNCTION: acpi_ev_global_lock_handler
320 * 290 *
321 * PARAMETERS: Context - From thread interface, not used 291 * PARAMETERS: Context - From thread interface, not used
322 * 292 *
323 * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED 293 * RETURN: ACPI_INTERRUPT_HANDLED
324 * 294 *
325 * DESCRIPTION: Invoked directly from the SCI handler when a global lock 295 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
326 * release interrupt occurs. Grab the global lock and queue 296 * release interrupt occurs. Attempt to acquire the global lock,
327 * the global lock thread for execution 297 * if successful, signal the thread waiting for the lock.
298 *
299 * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
300 * this is not possible for some reason, a separate thread will have to be
301 * scheduled to do this.
328 * 302 *
329 ******************************************************************************/ 303 ******************************************************************************/
330 304
@@ -333,16 +307,24 @@ static u32 acpi_ev_global_lock_handler(void *context)
333 u8 acquired = FALSE; 307 u8 acquired = FALSE;
334 308
335 /* 309 /*
336 * Attempt to get the lock 310 * Attempt to get the lock.
311 *
337 * If we don't get it now, it will be marked pending and we will 312 * If we don't get it now, it will be marked pending and we will
338 * take another interrupt when it becomes free. 313 * take another interrupt when it becomes free.
339 */ 314 */
340 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); 315 ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
341 if (acquired) { 316 if (acquired) {
342 317
343 /* Got the lock, now wake all threads waiting for it */ 318 /* Got the lock, now wake all threads waiting for it */
319
344 acpi_gbl_global_lock_acquired = TRUE; 320 acpi_gbl_global_lock_acquired = TRUE;
345 acpi_ev_global_lock_thread(context); 321 /* Send a unit to the semaphore */
322
323 if (ACPI_FAILURE(acpi_os_signal_semaphore(
324 acpi_gbl_global_lock_semaphore, 1))) {
325 ACPI_ERROR((AE_INFO,
326 "Could not signal Global Lock semaphore"));
327 }
346 } 328 }
347 329
348 return (ACPI_INTERRUPT_HANDLED); 330 return (ACPI_INTERRUPT_HANDLED);
@@ -366,6 +348,13 @@ acpi_status acpi_ev_init_global_lock_handler(void)
366 348
367 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); 349 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
368 350
351 status =
352 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
353 (struct acpi_table_header **)&facs);
354 if (ACPI_FAILURE(status)) {
355 return_ACPI_STATUS(status);
356 }
357
369 acpi_gbl_global_lock_present = TRUE; 358 acpi_gbl_global_lock_present = TRUE;
370 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, 359 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
371 acpi_ev_global_lock_handler, 360 acpi_ev_global_lock_handler,
@@ -389,6 +378,31 @@ acpi_status acpi_ev_init_global_lock_handler(void)
389 return_ACPI_STATUS(status); 378 return_ACPI_STATUS(status);
390} 379}
391 380
381/*******************************************************************************
382 *
383 * FUNCTION: acpi_ev_remove_global_lock_handler
384 *
385 * PARAMETERS: None
386 *
387 * RETURN: Status
388 *
389 * DESCRIPTION: Remove the handler for the Global Lock
390 *
391 ******************************************************************************/
392
393static acpi_status acpi_ev_remove_global_lock_handler(void)
394{
395 acpi_status status;
396
397 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
398
399 acpi_gbl_global_lock_present = FALSE;
400 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
401 acpi_ev_global_lock_handler);
402
403 return_ACPI_STATUS(status);
404}
405
392/****************************************************************************** 406/******************************************************************************
393 * 407 *
394 * FUNCTION: acpi_ev_acquire_global_lock 408 * FUNCTION: acpi_ev_acquire_global_lock
@@ -399,6 +413,16 @@ acpi_status acpi_ev_init_global_lock_handler(void)
399 * 413 *
400 * DESCRIPTION: Attempt to gain ownership of the Global Lock. 414 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
401 * 415 *
416 * MUTEX: Interpreter must be locked
417 *
418 * Note: The original implementation allowed multiple threads to "acquire" the
419 * Global Lock, and the OS would hold the lock until the last thread had
420 * released it. However, this could potentially starve the BIOS out of the
421 * lock, especially in the case where there is a tight handshake between the
422 * Embedded Controller driver and the BIOS. Therefore, this implementation
423 * allows only one thread to acquire the HW Global Lock at a time, and makes
424 * the global lock appear as a standard mutex on the OS side.
425 *
402 *****************************************************************************/ 426 *****************************************************************************/
403 427
404acpi_status acpi_ev_acquire_global_lock(u16 timeout) 428acpi_status acpi_ev_acquire_global_lock(u16 timeout)
@@ -408,53 +432,51 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
408 432
409 ACPI_FUNCTION_TRACE(ev_acquire_global_lock); 433 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
410 434
411#ifndef ACPI_APPLICATION 435 /*
412 /* Make sure that we actually have a global lock */ 436 * Only one thread can acquire the GL at a time, the global_lock_mutex
413 437 * enforces this. This interface releases the interpreter if we must wait.
414 if (!acpi_gbl_global_lock_present) { 438 */
415 return_ACPI_STATUS(AE_NO_GLOBAL_LOCK); 439 status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
440 if (ACPI_FAILURE(status)) {
441 return_ACPI_STATUS(status);
416 } 442 }
417#endif
418
419 /* One more thread wants the global lock */
420
421 acpi_gbl_global_lock_thread_count++;
422 443
423 /* 444 /*
424 * If we (OS side vs. BIOS side) have the hardware lock already, 445 * Make sure that a global lock actually exists. If not, just treat
425 * we are done 446 * the lock as a standard mutex.
426 */ 447 */
427 if (acpi_gbl_global_lock_acquired) { 448 if (!acpi_gbl_global_lock_present) {
449 acpi_gbl_global_lock_acquired = TRUE;
428 return_ACPI_STATUS(AE_OK); 450 return_ACPI_STATUS(AE_OK);
429 } 451 }
430 452
431 /* We must acquire the actual hardware lock */ 453 /* Attempt to acquire the actual hardware lock */
432 454
433 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); 455 ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
434 if (acquired) { 456 if (acquired) {
435 457
436 /* We got the lock */ 458 /* We got the lock */
437 459
438 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 460 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
439 "Acquired the HW Global Lock\n")); 461 "Acquired hardware Global Lock\n"));
440 462
441 acpi_gbl_global_lock_acquired = TRUE; 463 acpi_gbl_global_lock_acquired = TRUE;
442 return_ACPI_STATUS(AE_OK); 464 return_ACPI_STATUS(AE_OK);
443 } 465 }
444 466
445 /* 467 /*
446 * Did not get the lock. The pending bit was set above, and we must now 468 * Did not get the lock. The pending bit was set above, and we must now
447 * wait until we get the global lock released interrupt. 469 * wait until we get the global lock released interrupt.
448 */ 470 */
449 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); 471 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
450 472
451 /* 473 /*
452 * Acquire the global lock semaphore first. 474 * Wait for handshake with the global lock interrupt handler.
453 * Since this wait will block, we must release the interpreter 475 * This interface releases the interpreter if we must wait.
454 */ 476 */
455 status = 477 status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
456 acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, 478 ACPI_WAIT_FOREVER);
457 timeout); 479
458 return_ACPI_STATUS(status); 480 return_ACPI_STATUS(status);
459} 481}
460 482
@@ -477,38 +499,39 @@ acpi_status acpi_ev_release_global_lock(void)
477 499
478 ACPI_FUNCTION_TRACE(ev_release_global_lock); 500 ACPI_FUNCTION_TRACE(ev_release_global_lock);
479 501
480 if (!acpi_gbl_global_lock_thread_count) { 502 /* Lock must be already acquired */
503
504 if (!acpi_gbl_global_lock_acquired) {
481 ACPI_WARNING((AE_INFO, 505 ACPI_WARNING((AE_INFO,
482 "Cannot release HW Global Lock, it has not been acquired")); 506 "Cannot release the ACPI Global Lock, it has not been acquired"));
483 return_ACPI_STATUS(AE_NOT_ACQUIRED); 507 return_ACPI_STATUS(AE_NOT_ACQUIRED);
484 } 508 }
485 509
486 /* One fewer thread has the global lock */ 510 if (acpi_gbl_global_lock_present) {
487 511
488 acpi_gbl_global_lock_thread_count--; 512 /* Allow any thread to release the lock */
489 if (acpi_gbl_global_lock_thread_count) {
490 513
491 /* There are still some threads holding the lock, cannot release */ 514 ACPI_RELEASE_GLOBAL_LOCK(facs, pending);
492 515
493 return_ACPI_STATUS(AE_OK); 516 /*
517 * If the pending bit was set, we must write GBL_RLS to the control
518 * register
519 */
520 if (pending) {
521 status =
522 acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
523 1);
524 }
525
526 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
527 "Released hardware Global Lock\n"));
494 } 528 }
495 529
496 /*
497 * No more threads holding lock, we can do the actual hardware
498 * release
499 */
500 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending);
501 acpi_gbl_global_lock_acquired = FALSE; 530 acpi_gbl_global_lock_acquired = FALSE;
502 531
503 /* 532 /* Release the local GL mutex */
504 * If the pending bit was set, we must write GBL_RLS to the control
505 * register
506 */
507 if (pending) {
508 status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
509 1, ACPI_MTX_LOCK);
510 }
511 533
534 acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
512 return_ACPI_STATUS(status); 535 return_ACPI_STATUS(status);
513} 536}
514 537
@@ -558,6 +581,12 @@ void acpi_ev_terminate(void)
558 if (ACPI_FAILURE(status)) { 581 if (ACPI_FAILURE(status)) {
559 ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); 582 ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
560 } 583 }
584
585 status = acpi_ev_remove_global_lock_handler();
586 if (ACPI_FAILURE(status)) {
587 ACPI_ERROR((AE_INFO,
588 "Could not remove Global Lock handler"));
589 }
561 } 590 }
562 591
563 /* Deallocate all handler objects installed within GPE info structs */ 592 /* Deallocate all handler objects installed within GPE info structs */
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 21caae04fe85..e99f0c435a47 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -291,7 +291,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
291 u32 bit_width, acpi_integer * value) 291 u32 bit_width, acpi_integer * value)
292{ 292{
293 acpi_status status; 293 acpi_status status;
294 acpi_status status2;
295 acpi_adr_space_handler handler; 294 acpi_adr_space_handler handler;
296 acpi_adr_space_setup region_setup; 295 acpi_adr_space_setup region_setup;
297 union acpi_operand_object *handler_desc; 296 union acpi_operand_object *handler_desc;
@@ -345,7 +344,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
345 * setup will potentially execute control methods 344 * setup will potentially execute control methods
346 * (e.g., _REG method for this region) 345 * (e.g., _REG method for this region)
347 */ 346 */
348 acpi_ex_exit_interpreter(); 347 acpi_ex_relinquish_interpreter();
349 348
350 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 349 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
351 handler_desc->address_space.context, 350 handler_desc->address_space.context,
@@ -353,10 +352,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
353 352
354 /* Re-enter the interpreter */ 353 /* Re-enter the interpreter */
355 354
356 status2 = acpi_ex_enter_interpreter(); 355 acpi_ex_reacquire_interpreter();
357 if (ACPI_FAILURE(status2)) {
358 return_ACPI_STATUS(status2);
359 }
360 356
361 /* Check for failure of the Region Setup */ 357 /* Check for failure of the Region Setup */
362 358
@@ -409,7 +405,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
409 * exit the interpreter because the handler *might* block -- we don't 405 * exit the interpreter because the handler *might* block -- we don't
410 * know what it will do, so we can't hold the lock on the intepreter. 406 * know what it will do, so we can't hold the lock on the intepreter.
411 */ 407 */
412 acpi_ex_exit_interpreter(); 408 acpi_ex_relinquish_interpreter();
413 } 409 }
414 410
415 /* Call the handler */ 411 /* Call the handler */
@@ -430,10 +426,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
430 * We just returned from a non-default handler, we must re-enter the 426 * We just returned from a non-default handler, we must re-enter the
431 * interpreter 427 * interpreter
432 */ 428 */
433 status2 = acpi_ex_enter_interpreter(); 429 acpi_ex_reacquire_interpreter();
434 if (ACPI_FAILURE(status2)) {
435 return_ACPI_STATUS(status2);
436 }
437 } 430 }
438 431
439 return_ACPI_STATUS(status); 432 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 203d1359190a..a4fa7e6822a3 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,11 @@
48#define _COMPONENT ACPI_EVENTS 48#define _COMPONENT ACPI_EVENTS
49ACPI_MODULE_NAME("evrgnini") 49ACPI_MODULE_NAME("evrgnini")
50 50
51/* Local prototypes */
52static u8 acpi_ev_match_pci_root_bridge(char *id);
53
54static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
55
51/******************************************************************************* 56/*******************************************************************************
52 * 57 *
53 * FUNCTION: acpi_ev_system_memory_region_setup 58 * FUNCTION: acpi_ev_system_memory_region_setup
@@ -62,6 +67,7 @@ ACPI_MODULE_NAME("evrgnini")
62 * DESCRIPTION: Setup a system_memory operation region 67 * DESCRIPTION: Setup a system_memory operation region
63 * 68 *
64 ******************************************************************************/ 69 ******************************************************************************/
70
65acpi_status 71acpi_status
66acpi_ev_system_memory_region_setup(acpi_handle handle, 72acpi_ev_system_memory_region_setup(acpi_handle handle,
67 u32 function, 73 u32 function,
@@ -168,9 +174,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
168 union acpi_operand_object *handler_obj; 174 union acpi_operand_object *handler_obj;
169 struct acpi_namespace_node *parent_node; 175 struct acpi_namespace_node *parent_node;
170 struct acpi_namespace_node *pci_root_node; 176 struct acpi_namespace_node *pci_root_node;
177 struct acpi_namespace_node *pci_device_node;
171 union acpi_operand_object *region_obj = 178 union acpi_operand_object *region_obj =
172 (union acpi_operand_object *)handle; 179 (union acpi_operand_object *)handle;
173 struct acpi_device_id object_hID;
174 180
175 ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); 181 ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
176 182
@@ -215,45 +221,30 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
215 221
216 pci_root_node = parent_node; 222 pci_root_node = parent_node;
217 while (pci_root_node != acpi_gbl_root_node) { 223 while (pci_root_node != acpi_gbl_root_node) {
218 status =
219 acpi_ut_execute_HID(pci_root_node, &object_hID);
220 if (ACPI_SUCCESS(status)) {
221 /*
222 * Got a valid _HID string, check if this is a PCI root.
223 * New for ACPI 3.0: check for a PCI Express root also.
224 */
225 if (!
226 (ACPI_STRNCMP
227 (object_hID.value, PCI_ROOT_HID_STRING,
228 sizeof(PCI_ROOT_HID_STRING)))
229 ||
230 !(ACPI_STRNCMP
231 (object_hID.value,
232 PCI_EXPRESS_ROOT_HID_STRING,
233 sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
234
235 /* Install a handler for this PCI root bridge */
236 224
237 status = 225 /* Get the _HID/_CID in order to detect a root_bridge */
238 acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); 226
239 if (ACPI_FAILURE(status)) { 227 if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
240 if (status == AE_SAME_HANDLER) { 228
241 /* 229 /* Install a handler for this PCI root bridge */
242 * It is OK if the handler is already installed on the root 230
243 * bridge. Still need to return a context object for the 231 status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
244 * new PCI_Config operation region, however. 232 if (ACPI_FAILURE(status)) {
245 */ 233 if (status == AE_SAME_HANDLER) {
246 status = AE_OK; 234 /*
247 } else { 235 * It is OK if the handler is already installed on the root
248 ACPI_EXCEPTION((AE_INFO, 236 * bridge. Still need to return a context object for the
249 status, 237 * new PCI_Config operation region, however.
250 "Could not install PciConfig handler for Root Bridge %4.4s", 238 */
251 acpi_ut_get_node_name 239 status = AE_OK;
252 (pci_root_node))); 240 } else {
253 } 241 ACPI_EXCEPTION((AE_INFO, status,
242 "Could not install PciConfig handler for Root Bridge %4.4s",
243 acpi_ut_get_node_name
244 (pci_root_node)));
254 } 245 }
255 break;
256 } 246 }
247 break;
257 } 248 }
258 249
259 pci_root_node = acpi_ns_get_parent_node(pci_root_node); 250 pci_root_node = acpi_ns_get_parent_node(pci_root_node);
@@ -282,14 +273,25 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
282 /* 273 /*
283 * For PCI_Config space access, we need the segment, bus, 274 * For PCI_Config space access, we need the segment, bus,
284 * device and function numbers. Acquire them here. 275 * device and function numbers. Acquire them here.
276 *
277 * Find the parent device object. (This allows the operation region to be
278 * within a subscope under the device, such as a control method.)
285 */ 279 */
280 pci_device_node = region_obj->region.node;
281 while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
282 pci_device_node = acpi_ns_get_parent_node(pci_device_node);
283 }
284
285 if (!pci_device_node) {
286 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
287 }
286 288
287 /* 289 /*
288 * Get the PCI device and function numbers from the _ADR object 290 * Get the PCI device and function numbers from the _ADR object
289 * contained in the parent's scope. 291 * contained in the parent's scope.
290 */ 292 */
291 status = 293 status =
292 acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node, 294 acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
293 &pci_value); 295 &pci_value);
294 296
295 /* 297 /*
@@ -329,6 +331,91 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
329 331
330/******************************************************************************* 332/*******************************************************************************
331 * 333 *
334 * FUNCTION: acpi_ev_match_pci_root_bridge
335 *
336 * PARAMETERS: Id - The HID/CID in string format
337 *
338 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
339 *
340 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
341 *
342 ******************************************************************************/
343
344static u8 acpi_ev_match_pci_root_bridge(char *id)
345{
346
347 /*
348 * Check if this is a PCI root.
349 * ACPI 3.0+: check for a PCI Express root also.
350 */
351 if (!(ACPI_STRNCMP(id,
352 PCI_ROOT_HID_STRING,
353 sizeof(PCI_ROOT_HID_STRING))) ||
354 !(ACPI_STRNCMP(id,
355 PCI_EXPRESS_ROOT_HID_STRING,
356 sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
357 return (TRUE);
358 }
359
360 return (FALSE);
361}
362
363/*******************************************************************************
364 *
365 * FUNCTION: acpi_ev_is_pci_root_bridge
366 *
367 * PARAMETERS: Node - Device node being examined
368 *
369 * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
370 *
371 * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
372 * examining the _HID and _CID for the device.
373 *
374 ******************************************************************************/
375
376static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
377{
378 acpi_status status;
379 struct acpi_device_id hid;
380 struct acpi_compatible_id_list *cid;
381 acpi_native_uint i;
382
383 /*
384 * Get the _HID and check for a PCI Root Bridge
385 */
386 status = acpi_ut_execute_HID(node, &hid);
387 if (ACPI_FAILURE(status)) {
388 return (FALSE);
389 }
390
391 if (acpi_ev_match_pci_root_bridge(hid.value)) {
392 return (TRUE);
393 }
394
395 /*
396 * The _HID did not match.
397 * Get the _CID and check for a PCI Root Bridge
398 */
399 status = acpi_ut_execute_CID(node, &cid);
400 if (ACPI_FAILURE(status)) {
401 return (FALSE);
402 }
403
404 /* Check all _CIDs in the returned list */
405
406 for (i = 0; i < cid->count; i++) {
407 if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) {
408 ACPI_FREE(cid);
409 return (TRUE);
410 }
411 }
412
413 ACPI_FREE(cid);
414 return (FALSE);
415}
416
417/*******************************************************************************
418 *
332 * FUNCTION: acpi_ev_pci_bar_region_setup 419 * FUNCTION: acpi_ev_pci_bar_region_setup
333 * 420 *
334 * PARAMETERS: Handle - Region we are interested in 421 * PARAMETERS: Handle - Region we are interested in
@@ -432,6 +519,9 @@ acpi_ev_default_region_setup(acpi_handle handle,
432 * a PCI address in the scope of the definition. This address is 519 * a PCI address in the scope of the definition. This address is
433 * required to perform an access to PCI config space. 520 * required to perform an access to PCI config space.
434 * 521 *
522 * MUTEX: Interpreter should be unlocked, because we may run the _REG
523 * method for this region.
524 *
435 ******************************************************************************/ 525 ******************************************************************************/
436 526
437acpi_status 527acpi_status
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 8106215ad554..7e5d15ce2395 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -142,9 +142,10 @@ u32 acpi_ev_install_sci_handler(void)
142 142
143 ACPI_FUNCTION_TRACE(ev_install_sci_handler); 143 ACPI_FUNCTION_TRACE(ev_install_sci_handler);
144 144
145 status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, 145 status =
146 acpi_ev_sci_xrupt_handler, 146 acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
147 acpi_gbl_gpe_xrupt_list_head); 147 acpi_ev_sci_xrupt_handler,
148 acpi_gbl_gpe_xrupt_list_head);
148 return_ACPI_STATUS(status); 149 return_ACPI_STATUS(status);
149} 150}
150 151
@@ -175,8 +176,9 @@ acpi_status acpi_ev_remove_sci_handler(void)
175 176
176 /* Just let the OS remove the handler and disable the level */ 177 /* Just let the OS remove the handler and disable the level */
177 178
178 status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int, 179 status =
179 acpi_ev_sci_xrupt_handler); 180 acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
181 acpi_ev_sci_xrupt_handler);
180 182
181 return_ACPI_STATUS(status); 183 return_ACPI_STATUS(status);
182} 184}
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 923fd2b46955..685a103a3587 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -768,11 +768,9 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
768 return (AE_BAD_PARAMETER); 768 return (AE_BAD_PARAMETER);
769 } 769 }
770 770
771 status = acpi_ex_enter_interpreter(); 771 /* Must lock interpreter to prevent race conditions */
772 if (ACPI_FAILURE(status)) {
773 return (status);
774 }
775 772
773 acpi_ex_enter_interpreter();
776 status = acpi_ev_acquire_global_lock(timeout); 774 status = acpi_ev_acquire_global_lock(timeout);
777 acpi_ex_exit_interpreter(); 775 acpi_ex_exit_interpreter();
778 776
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 7ebc2efac936..17065e98807c 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acevents.h> 45#include <acpi/acevents.h>
46#include <acpi/acnamesp.h> 46#include <acpi/acnamesp.h>
47#include <acpi/actables.h>
47 48
48#define _COMPONENT ACPI_EVENTS 49#define _COMPONENT ACPI_EVENTS
49ACPI_MODULE_NAME("evxfevnt") 50ACPI_MODULE_NAME("evxfevnt")
@@ -65,13 +66,14 @@ acpi_status acpi_enable(void)
65 66
66 ACPI_FUNCTION_TRACE(acpi_enable); 67 ACPI_FUNCTION_TRACE(acpi_enable);
67 68
68 /* Make sure we have the FADT */ 69 /* ACPI tables must be present */
69 70
70 if (!acpi_gbl_FADT) { 71 if (!acpi_tb_tables_loaded()) {
71 ACPI_WARNING((AE_INFO, "No FADT information present!"));
72 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 72 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
73 } 73 }
74 74
75 /* Check current mode */
76
75 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 77 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
76 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 78 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
77 "System is already in ACPI mode\n")); 79 "System is already in ACPI mode\n"));
@@ -111,11 +113,6 @@ acpi_status acpi_disable(void)
111 113
112 ACPI_FUNCTION_TRACE(acpi_disable); 114 ACPI_FUNCTION_TRACE(acpi_disable);
113 115
114 if (!acpi_gbl_FADT) {
115 ACPI_WARNING((AE_INFO, "No FADT information present!"));
116 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
117 }
118
119 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 116 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
120 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 117 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
121 "System is already in legacy (non-ACPI) mode\n")); 118 "System is already in legacy (non-ACPI) mode\n"));
@@ -169,7 +166,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
169 */ 166 */
170 status = 167 status =
171 acpi_set_register(acpi_gbl_fixed_event_info[event]. 168 acpi_set_register(acpi_gbl_fixed_event_info[event].
172 enable_register_id, 1, ACPI_MTX_LOCK); 169 enable_register_id, 1);
173 if (ACPI_FAILURE(status)) { 170 if (ACPI_FAILURE(status)) {
174 return_ACPI_STATUS(status); 171 return_ACPI_STATUS(status);
175 } 172 }
@@ -178,7 +175,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
178 175
179 status = 176 status =
180 acpi_get_register(acpi_gbl_fixed_event_info[event]. 177 acpi_get_register(acpi_gbl_fixed_event_info[event].
181 enable_register_id, &value, ACPI_MTX_LOCK); 178 enable_register_id, &value);
182 if (ACPI_FAILURE(status)) { 179 if (ACPI_FAILURE(status)) {
183 return_ACPI_STATUS(status); 180 return_ACPI_STATUS(status);
184 } 181 }
@@ -368,14 +365,14 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
368 */ 365 */
369 status = 366 status =
370 acpi_set_register(acpi_gbl_fixed_event_info[event]. 367 acpi_set_register(acpi_gbl_fixed_event_info[event].
371 enable_register_id, 0, ACPI_MTX_LOCK); 368 enable_register_id, 0);
372 if (ACPI_FAILURE(status)) { 369 if (ACPI_FAILURE(status)) {
373 return_ACPI_STATUS(status); 370 return_ACPI_STATUS(status);
374 } 371 }
375 372
376 status = 373 status =
377 acpi_get_register(acpi_gbl_fixed_event_info[event]. 374 acpi_get_register(acpi_gbl_fixed_event_info[event].
378 enable_register_id, &value, ACPI_MTX_LOCK); 375 enable_register_id, &value);
379 if (ACPI_FAILURE(status)) { 376 if (ACPI_FAILURE(status)) {
380 return_ACPI_STATUS(status); 377 return_ACPI_STATUS(status);
381 } 378 }
@@ -421,7 +418,7 @@ acpi_status acpi_clear_event(u32 event)
421 */ 418 */
422 status = 419 status =
423 acpi_set_register(acpi_gbl_fixed_event_info[event]. 420 acpi_set_register(acpi_gbl_fixed_event_info[event].
424 status_register_id, 1, ACPI_MTX_LOCK); 421 status_register_id, 1);
425 422
426 return_ACPI_STATUS(status); 423 return_ACPI_STATUS(status);
427} 424}
@@ -510,7 +507,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
510 507
511 status = 508 status =
512 acpi_get_register(acpi_gbl_fixed_event_info[event]. 509 acpi_get_register(acpi_gbl_fixed_event_info[event].
513 status_register_id, event_status, ACPI_MTX_LOCK); 510 status_register_id, event_status);
514 511
515 return_ACPI_STATUS(status); 512 return_ACPI_STATUS(status);
516} 513}
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index 83b12a9afa32..7bf09c5fb242 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index c8341fa5fe01..25802f302ffe 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig")
54 54
55/* Local prototypes */ 55/* Local prototypes */
56static acpi_status 56static acpi_status
57acpi_ex_add_table(struct acpi_table_header *table, 57acpi_ex_add_table(acpi_native_uint table_index,
58 struct acpi_namespace_node *parent_node, 58 struct acpi_namespace_node *parent_node,
59 union acpi_operand_object **ddb_handle); 59 union acpi_operand_object **ddb_handle);
60 60
@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table,
74 ******************************************************************************/ 74 ******************************************************************************/
75 75
76static acpi_status 76static acpi_status
77acpi_ex_add_table(struct acpi_table_header *table, 77acpi_ex_add_table(acpi_native_uint table_index,
78 struct acpi_namespace_node *parent_node, 78 struct acpi_namespace_node *parent_node,
79 union acpi_operand_object **ddb_handle) 79 union acpi_operand_object **ddb_handle)
80{ 80{
81 acpi_status status; 81 acpi_status status;
82 struct acpi_table_desc table_info;
83 union acpi_operand_object *obj_desc; 82 union acpi_operand_object *obj_desc;
84 83
85 ACPI_FUNCTION_TRACE(ex_add_table); 84 ACPI_FUNCTION_TRACE(ex_add_table);
@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table,
98 97
99 /* Install the new table into the local data structures */ 98 /* Install the new table into the local data structures */
100 99
101 ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); 100 obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
102
103 table_info.type = ACPI_TABLE_ID_SSDT;
104 table_info.pointer = table;
105 table_info.length = (acpi_size) table->length;
106 table_info.allocation = ACPI_MEM_ALLOCATED;
107
108 status = acpi_tb_install_table(&table_info);
109 obj_desc->reference.object = table_info.installed_desc;
110
111 if (ACPI_FAILURE(status)) {
112 if (status == AE_ALREADY_EXISTS) {
113
114 /* Table already exists, just return the handle */
115
116 return_ACPI_STATUS(AE_OK);
117 }
118 goto cleanup;
119 }
120 101
121 /* Add the table to the namespace */ 102 /* Add the table to the namespace */
122 103
123 status = acpi_ns_load_table(table_info.installed_desc, parent_node); 104 status = acpi_ns_load_table(table_index, parent_node);
124 if (ACPI_FAILURE(status)) { 105 if (ACPI_FAILURE(status)) {
125 106 acpi_ut_remove_reference(obj_desc);
126 /* Uninstall table on error */ 107 *ddb_handle = NULL;
127
128 (void)acpi_tb_uninstall_table(table_info.installed_desc);
129 goto cleanup;
130 } 108 }
131 109
132 return_ACPI_STATUS(AE_OK);
133
134 cleanup:
135 acpi_ut_remove_reference(obj_desc);
136 *ddb_handle = NULL;
137 return_ACPI_STATUS(status); 110 return_ACPI_STATUS(status);
138} 111}
139 112
@@ -146,7 +119,7 @@ acpi_ex_add_table(struct acpi_table_header *table,
146 * 119 *
147 * RETURN: Status 120 * RETURN: Status
148 * 121 *
149 * DESCRIPTION: Load an ACPI table 122 * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
150 * 123 *
151 ******************************************************************************/ 124 ******************************************************************************/
152 125
@@ -156,33 +129,20 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
156{ 129{
157 acpi_status status; 130 acpi_status status;
158 union acpi_operand_object **operand = &walk_state->operands[0]; 131 union acpi_operand_object **operand = &walk_state->operands[0];
159 struct acpi_table_header *table; 132 acpi_native_uint table_index;
160 struct acpi_namespace_node *parent_node; 133 struct acpi_namespace_node *parent_node;
161 struct acpi_namespace_node *start_node; 134 struct acpi_namespace_node *start_node;
162 struct acpi_namespace_node *parameter_node = NULL; 135 struct acpi_namespace_node *parameter_node = NULL;
163 union acpi_operand_object *ddb_handle; 136 union acpi_operand_object *ddb_handle;
137 struct acpi_table_header *table;
164 138
165 ACPI_FUNCTION_TRACE(ex_load_table_op); 139 ACPI_FUNCTION_TRACE(ex_load_table_op);
166 140
167#if 0 141 /* Find the ACPI table in the RSDT/XSDT */
168 /*
169 * Make sure that the signature does not match one of the tables that
170 * is already loaded.
171 */
172 status = acpi_tb_match_signature(operand[0]->string.pointer, NULL);
173 if (status == AE_OK) {
174
175 /* Signature matched -- don't allow override */
176
177 return_ACPI_STATUS(AE_ALREADY_EXISTS);
178 }
179#endif
180
181 /* Find the ACPI table */
182 142
183 status = acpi_tb_find_table(operand[0]->string.pointer, 143 status = acpi_tb_find_table(operand[0]->string.pointer,
184 operand[1]->string.pointer, 144 operand[1]->string.pointer,
185 operand[2]->string.pointer, &table); 145 operand[2]->string.pointer, &table_index);
186 if (ACPI_FAILURE(status)) { 146 if (ACPI_FAILURE(status)) {
187 if (status != AE_NOT_FOUND) { 147 if (status != AE_NOT_FOUND) {
188 return_ACPI_STATUS(status); 148 return_ACPI_STATUS(status);
@@ -245,7 +205,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
245 205
246 /* Load the table into the namespace */ 206 /* Load the table into the namespace */
247 207
248 status = acpi_ex_add_table(table, parent_node, &ddb_handle); 208 status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
249 if (ACPI_FAILURE(status)) { 209 if (ACPI_FAILURE(status)) {
250 return_ACPI_STATUS(status); 210 return_ACPI_STATUS(status);
251 } 211 }
@@ -266,9 +226,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
266 } 226 }
267 } 227 }
268 228
269 ACPI_INFO((AE_INFO, 229 status = acpi_get_table_by_index(table_index, &table);
270 "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", 230 if (ACPI_SUCCESS(status)) {
271 table->signature, table->oem_id, table->oem_table_id)); 231 ACPI_INFO((AE_INFO,
232 "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
233 table->signature, table->oem_id,
234 table->oem_table_id));
235 }
272 236
273 *return_desc = ddb_handle; 237 *return_desc = ddb_handle;
274 return_ACPI_STATUS(status); 238 return_ACPI_STATUS(status);
@@ -278,7 +242,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
278 * 242 *
279 * FUNCTION: acpi_ex_load_op 243 * FUNCTION: acpi_ex_load_op
280 * 244 *
281 * PARAMETERS: obj_desc - Region or Field where the table will be 245 * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be
282 * obtained 246 * obtained
283 * Target - Where a handle to the table will be stored 247 * Target - Where a handle to the table will be stored
284 * walk_state - Current state 248 * walk_state - Current state
@@ -287,6 +251,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
287 * 251 *
288 * DESCRIPTION: Load an ACPI table from a field or operation region 252 * DESCRIPTION: Load an ACPI table from a field or operation region
289 * 253 *
254 * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer
255 * objects before this code is reached.
256 *
257 * If source is an operation region, it must refer to system_memory, as
258 * per the ACPI specification.
259 *
290 ******************************************************************************/ 260 ******************************************************************************/
291 261
292acpi_status 262acpi_status
@@ -294,22 +264,26 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
294 union acpi_operand_object *target, 264 union acpi_operand_object *target,
295 struct acpi_walk_state *walk_state) 265 struct acpi_walk_state *walk_state)
296{ 266{
297 acpi_status status;
298 union acpi_operand_object *ddb_handle; 267 union acpi_operand_object *ddb_handle;
299 union acpi_operand_object *buffer_desc = NULL; 268 struct acpi_table_desc table_desc;
300 struct acpi_table_header *table_ptr = NULL; 269 acpi_native_uint table_index;
301 acpi_physical_address address; 270 acpi_status status;
302 struct acpi_table_header table_header;
303 acpi_integer temp;
304 u32 i;
305 271
306 ACPI_FUNCTION_TRACE(ex_load_op); 272 ACPI_FUNCTION_TRACE(ex_load_op);
307 273
308 /* Object can be either an op_region or a Field */ 274 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
275
276 /* Source Object can be either an op_region or a Buffer/Field */
309 277
310 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 278 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
311 case ACPI_TYPE_REGION: 279 case ACPI_TYPE_REGION:
312 280
281 /* Region must be system_memory (from ACPI spec) */
282
283 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
284 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
285 }
286
313 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", 287 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
314 obj_desc, 288 obj_desc,
315 acpi_ut_get_object_type_name(obj_desc))); 289 acpi_ut_get_object_type_name(obj_desc)));
@@ -325,113 +299,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
325 } 299 }
326 } 300 }
327 301
328 /* Get the base physical address of the region */ 302 table_desc.address = obj_desc->region.address;
329 303 table_desc.length = obj_desc->region.length;
330 address = obj_desc->region.address; 304 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
331
332 /* Get part of the table header to get the table length */
333
334 table_header.length = 0;
335 for (i = 0; i < 8; i++) {
336 status =
337 acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
338 (acpi_physical_address)
339 (i + address), 8,
340 &temp);
341 if (ACPI_FAILURE(status)) {
342 return_ACPI_STATUS(status);
343 }
344
345 /* Get the one valid byte of the returned 64-bit value */
346
347 ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp;
348 }
349
350 /* Sanity check the table length */
351
352 if (table_header.length < sizeof(struct acpi_table_header)) {
353 return_ACPI_STATUS(AE_BAD_HEADER);
354 }
355
356 /* Allocate a buffer for the entire table */
357
358 table_ptr = ACPI_ALLOCATE(table_header.length);
359 if (!table_ptr) {
360 return_ACPI_STATUS(AE_NO_MEMORY);
361 }
362
363 /* Get the entire table from the op region */
364
365 for (i = 0; i < table_header.length; i++) {
366 status =
367 acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
368 (acpi_physical_address)
369 (i + address), 8,
370 &temp);
371 if (ACPI_FAILURE(status)) {
372 goto cleanup;
373 }
374
375 /* Get the one valid byte of the returned 64-bit value */
376
377 ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp;
378 }
379 break; 305 break;
380 306
381 case ACPI_TYPE_LOCAL_REGION_FIELD: 307 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
382 case ACPI_TYPE_LOCAL_BANK_FIELD:
383 case ACPI_TYPE_LOCAL_INDEX_FIELD:
384 308
385 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n", 309 /* Simply extract the buffer from the buffer object */
386 obj_desc,
387 acpi_ut_get_object_type_name(obj_desc)));
388 310
389 /* 311 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
390 * The length of the field must be at least as large as the table. 312 "Load from Buffer or Field %p %s\n", obj_desc,
391 * Read the entire field and thus the entire table. Buffer is 313 acpi_ut_get_object_type_name(obj_desc)));
392 * allocated during the read.
393 */
394 status =
395 acpi_ex_read_data_from_field(walk_state, obj_desc,
396 &buffer_desc);
397 if (ACPI_FAILURE(status)) {
398 return_ACPI_STATUS(status);
399 }
400
401 table_ptr = ACPI_CAST_PTR(struct acpi_table_header,
402 buffer_desc->buffer.pointer);
403
404 /* All done with the buffer_desc, delete it */
405
406 buffer_desc->buffer.pointer = NULL;
407 acpi_ut_remove_reference(buffer_desc);
408 314
409 /* Sanity check the table length */ 315 table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header,
316 obj_desc->buffer.pointer);
317 table_desc.length = table_desc.pointer->length;
318 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
410 319
411 if (table_ptr->length < sizeof(struct acpi_table_header)) { 320 obj_desc->buffer.pointer = NULL;
412 status = AE_BAD_HEADER;
413 goto cleanup;
414 }
415 break; 321 break;
416 322
417 default: 323 default:
418 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 324 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
419 } 325 }
420 326
421 /* The table must be either an SSDT or a PSDT */ 327 /*
422 328 * Install the new table into the local data structures
423 if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && 329 */
424 (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { 330 status = acpi_tb_add_table(&table_desc, &table_index);
425 ACPI_ERROR((AE_INFO, 331 if (ACPI_FAILURE(status)) {
426 "Table has invalid signature [%4.4s], must be SSDT or PSDT",
427 table_ptr->signature));
428 status = AE_BAD_SIGNATURE;
429 goto cleanup; 332 goto cleanup;
430 } 333 }
431 334
432 /* Install the new table into the local data structures */ 335 status =
433 336 acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
434 status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
435 if (ACPI_FAILURE(status)) { 337 if (ACPI_FAILURE(status)) {
436 338
437 /* On error, table_ptr was deallocated above */ 339 /* On error, table_ptr was deallocated above */
@@ -450,13 +352,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
450 return_ACPI_STATUS(status); 352 return_ACPI_STATUS(status);
451 } 353 }
452 354
453 ACPI_INFO((AE_INFO,
454 "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]",
455 table_ptr->oem_id, table_ptr->oem_table_id));
456
457 cleanup: 355 cleanup:
458 if (ACPI_FAILURE(status)) { 356 if (ACPI_FAILURE(status)) {
459 ACPI_FREE(table_ptr); 357 acpi_tb_delete_table(&table_desc);
460 } 358 }
461 return_ACPI_STATUS(status); 359 return_ACPI_STATUS(status);
462} 360}
@@ -477,7 +375,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
477{ 375{
478 acpi_status status = AE_OK; 376 acpi_status status = AE_OK;
479 union acpi_operand_object *table_desc = ddb_handle; 377 union acpi_operand_object *table_desc = ddb_handle;
480 struct acpi_table_desc *table_info; 378 acpi_native_uint table_index;
481 379
482 ACPI_FUNCTION_TRACE(ex_unload_table); 380 ACPI_FUNCTION_TRACE(ex_unload_table);
483 381
@@ -493,19 +391,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
493 return_ACPI_STATUS(AE_BAD_PARAMETER); 391 return_ACPI_STATUS(AE_BAD_PARAMETER);
494 } 392 }
495 393
496 /* Get the actual table descriptor from the ddb_handle */ 394 /* Get the table index from the ddb_handle */
497 395
498 table_info = (struct acpi_table_desc *)table_desc->reference.object; 396 table_index = (acpi_native_uint) table_desc->reference.object;
499 397
500 /* 398 /*
501 * Delete the entire namespace under this table Node 399 * Delete the entire namespace under this table Node
502 * (Offset contains the table_id) 400 * (Offset contains the table_id)
503 */ 401 */
504 acpi_ns_delete_namespace_by_owner(table_info->owner_id); 402 acpi_tb_delete_namespace_by_owner(table_index);
505 403 acpi_tb_release_owner_id(table_index);
506 /* Delete the table itself */
507 404
508 (void)acpi_tb_uninstall_table(table_info->installed_desc); 405 acpi_tb_set_table_loaded_flag(table_index, FALSE);
509 406
510 /* Delete the table descriptor (ddb_handle) */ 407 /* Delete the table descriptor (ddb_handle) */
511 408
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 544e81a6a438..d470e8b1f4ea 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 34eec82c1b1e..7c38528a7e83 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
359 union acpi_operand_object **operand = &walk_state->operands[0]; 359 union acpi_operand_object **operand = &walk_state->operands[0];
360 union acpi_operand_object *obj_desc; 360 union acpi_operand_object *obj_desc;
361 struct acpi_namespace_node *node; 361 struct acpi_namespace_node *node;
362 struct acpi_table_header *table;
363 union acpi_operand_object *region_obj2; 362 union acpi_operand_object *region_obj2;
363 acpi_native_uint table_index;
364 struct acpi_table_header *table;
364 365
365 ACPI_FUNCTION_TRACE(ex_create_table_region); 366 ACPI_FUNCTION_TRACE(ex_create_table_region);
366 367
@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
380 381
381 status = acpi_tb_find_table(operand[1]->string.pointer, 382 status = acpi_tb_find_table(operand[1]->string.pointer,
382 operand[2]->string.pointer, 383 operand[2]->string.pointer,
383 operand[3]->string.pointer, &table); 384 operand[3]->string.pointer, &table_index);
384 if (ACPI_FAILURE(status)) { 385 if (ACPI_FAILURE(status)) {
385 return_ACPI_STATUS(status); 386 return_ACPI_STATUS(status);
386 } 387 }
@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
395 region_obj2 = obj_desc->common.next_object; 396 region_obj2 = obj_desc->common.next_object;
396 region_obj2->extra.region_context = NULL; 397 region_obj2->extra.region_context = NULL;
397 398
399 status = acpi_get_table_by_index(table_index, &table);
400 if (ACPI_FAILURE(status)) {
401 return_ACPI_STATUS(status);
402 }
403
398 /* Init the region from the operands */ 404 /* Init the region from the operands */
399 405
400 obj_desc->region.space_id = REGION_DATA_TABLE; 406 obj_desc->region.space_id = REGION_DATA_TABLE;
@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start,
553 559
554 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); 560 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
555 if (!obj_desc) { 561 if (!obj_desc) {
556 return_ACPI_STATUS(AE_NO_MEMORY); 562 status = AE_NO_MEMORY;
563 goto exit;
557 } 564 }
558 565
559 /* Save the method's AML pointer and length */ 566 /* Save the method's AML pointer and length */
@@ -576,10 +583,7 @@ acpi_ex_create_method(u8 * aml_start,
576 * Get the sync_level. If method is serialized, a mutex will be 583 * Get the sync_level. If method is serialized, a mutex will be
577 * created for this method when it is parsed. 584 * created for this method when it is parsed.
578 */ 585 */
579 if (acpi_gbl_all_methods_serialized) { 586 if (method_flags & AML_METHOD_SERIALIZED) {
580 obj_desc->method.sync_level = 0;
581 obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
582 } else if (method_flags & AML_METHOD_SERIALIZED) {
583 /* 587 /*
584 * ACPI 1.0: sync_level = 0 588 * ACPI 1.0: sync_level = 0
585 * ACPI 2.0: sync_level = sync_level in method declaration 589 * ACPI 2.0: sync_level = sync_level in method declaration
@@ -597,6 +601,7 @@ acpi_ex_create_method(u8 * aml_start,
597 601
598 acpi_ut_remove_reference(obj_desc); 602 acpi_ut_remove_reference(obj_desc);
599 603
604 exit:
600 /* Remove a reference to the operand */ 605 /* Remove a reference to the operand */
601 606
602 acpi_ut_remove_reference(operand[1]); 607 acpi_ut_remove_reference(operand[1]);
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 2450943add33..68d283fd60e7 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -59,8 +59,6 @@ static void acpi_ex_out_string(char *title, char *value);
59 59
60static void acpi_ex_out_pointer(char *title, void *value); 60static void acpi_ex_out_pointer(char *title, void *value);
61 61
62static void acpi_ex_out_address(char *title, acpi_physical_address value);
63
64static void 62static void
65acpi_ex_dump_object(union acpi_operand_object *obj_desc, 63acpi_ex_dump_object(union acpi_operand_object *obj_desc,
66 struct acpi_exdump_info *info); 64 struct acpi_exdump_info *info);
@@ -92,10 +90,11 @@ static struct acpi_exdump_info acpi_ex_dump_string[4] = {
92 {ACPI_EXD_STRING, 0, NULL} 90 {ACPI_EXD_STRING, 0, NULL}
93}; 91};
94 92
95static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { 93static struct acpi_exdump_info acpi_ex_dump_buffer[5] = {
96 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, 94 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL},
97 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, 95 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"},
98 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, 96 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"},
97 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"},
99 {ACPI_EXD_BUFFER, 0, NULL} 98 {ACPI_EXD_BUFFER, 0, NULL}
100}; 99};
101 100
@@ -165,8 +164,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = {
165 164
166static struct acpi_exdump_info acpi_ex_dump_processor[7] = { 165static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
167 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, 166 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL},
168 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, 167 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
169 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, 168 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
170 {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, 169 {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
171 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), 170 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify),
172 "System Notify"}, 171 "System Notify"},
@@ -379,18 +378,12 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
379 break; 378 break;
380 379
381 case ACPI_EXD_POINTER: 380 case ACPI_EXD_POINTER:
381 case ACPI_EXD_ADDRESS:
382 382
383 acpi_ex_out_pointer(name, 383 acpi_ex_out_pointer(name,
384 *ACPI_CAST_PTR(void *, target)); 384 *ACPI_CAST_PTR(void *, target));
385 break; 385 break;
386 386
387 case ACPI_EXD_ADDRESS:
388
389 acpi_ex_out_address(name,
390 *ACPI_CAST_PTR
391 (acpi_physical_address, target));
392 break;
393
394 case ACPI_EXD_STRING: 387 case ACPI_EXD_STRING:
395 388
396 acpi_ut_print_string(obj_desc->string.pointer, 389 acpi_ut_print_string(obj_desc->string.pointer,
@@ -834,16 +827,6 @@ static void acpi_ex_out_pointer(char *title, void *value)
834 acpi_os_printf("%20s : %p\n", title, value); 827 acpi_os_printf("%20s : %p\n", title, value);
835} 828}
836 829
837static void acpi_ex_out_address(char *title, acpi_physical_address value)
838{
839
840#if ACPI_MACHINE_WIDTH == 16
841 acpi_os_printf("%20s : %p\n", title, value);
842#else
843 acpi_os_printf("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
844#endif
845}
846
847/******************************************************************************* 830/*******************************************************************************
848 * 831 *
849 * FUNCTION: acpi_ex_dump_namespace_node 832 * FUNCTION: acpi_ex_dump_namespace_node
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index 9ea9c3a67ca9..2d88a3d8d1ad 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 40f0bee6faa5..65a48b6170ee 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
257 } 257 }
258 258
259 ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, 259 ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
260 " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", 260 " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
261 acpi_ut_get_region_name(rgn_desc->region. 261 acpi_ut_get_region_name(rgn_desc->region.
262 space_id), 262 space_id),
263 rgn_desc->region.space_id, 263 rgn_desc->region.space_id,
264 obj_desc->common_field.access_byte_width, 264 obj_desc->common_field.access_byte_width,
265 obj_desc->common_field.base_byte_offset, 265 obj_desc->common_field.base_byte_offset,
266 field_datum_byte_offset, 266 field_datum_byte_offset, (void *)address));
267 ACPI_FORMAT_UINT64(address)));
268 267
269 /* Invoke the appropriate address_space/op_region handler */ 268 /* Invoke the appropriate address_space/op_region handler */
270 269
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index bd98aab017cf..f13d1cec2d6d 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index bf90f04f2c60..5101bad5baf8 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
44 44
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/acinterp.h> 46#include <acpi/acinterp.h>
47#include <acpi/acevents.h>
47 48
48#define _COMPONENT ACPI_EXECUTER 49#define _COMPONENT ACPI_EXECUTER
49ACPI_MODULE_NAME("exmutex") 50ACPI_MODULE_NAME("exmutex")
@@ -150,7 +151,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
150 return_ACPI_STATUS(AE_BAD_PARAMETER); 151 return_ACPI_STATUS(AE_BAD_PARAMETER);
151 } 152 }
152 153
153 /* Sanity check -- we must have a valid thread ID */ 154 /* Sanity check: we must have a valid thread ID */
154 155
155 if (!walk_state->thread) { 156 if (!walk_state->thread) {
156 ACPI_ERROR((AE_INFO, 157 ACPI_ERROR((AE_INFO,
@@ -174,24 +175,28 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
174 /* Support for multiple acquires by the owning thread */ 175 /* Support for multiple acquires by the owning thread */
175 176
176 if (obj_desc->mutex.owner_thread) { 177 if (obj_desc->mutex.owner_thread) {
177 178 if (obj_desc->mutex.owner_thread->thread_id ==
178 /* Special case for Global Lock, allow all threads */ 179 walk_state->thread->thread_id) {
179
180 if ((obj_desc->mutex.owner_thread->thread_id ==
181 walk_state->thread->thread_id) ||
182 (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK)) {
183 /* 180 /*
184 * The mutex is already owned by this thread, 181 * The mutex is already owned by this thread, just increment the
185 * just increment the acquisition depth 182 * acquisition depth
186 */ 183 */
187 obj_desc->mutex.acquisition_depth++; 184 obj_desc->mutex.acquisition_depth++;
188 return_ACPI_STATUS(AE_OK); 185 return_ACPI_STATUS(AE_OK);
189 } 186 }
190 } 187 }
191 188
192 /* Acquire the mutex, wait if necessary */ 189 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
190
191 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
192 status =
193 acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
194 } else {
195 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
196 (u16) time_desc->integer.
197 value);
198 }
193 199
194 status = acpi_ex_system_acquire_mutex(time_desc, obj_desc);
195 if (ACPI_FAILURE(status)) { 200 if (ACPI_FAILURE(status)) {
196 201
197 /* Includes failure from a timeout on time_desc */ 202 /* Includes failure from a timeout on time_desc */
@@ -211,7 +216,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
211 /* Link the mutex to the current thread for force-unlock at method exit */ 216 /* Link the mutex to the current thread for force-unlock at method exit */
212 217
213 acpi_ex_link_mutex(obj_desc, walk_state->thread); 218 acpi_ex_link_mutex(obj_desc, walk_state->thread);
214
215 return_ACPI_STATUS(AE_OK); 219 return_ACPI_STATUS(AE_OK);
216} 220}
217 221
@@ -232,7 +236,7 @@ acpi_status
232acpi_ex_release_mutex(union acpi_operand_object *obj_desc, 236acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
233 struct acpi_walk_state *walk_state) 237 struct acpi_walk_state *walk_state)
234{ 238{
235 acpi_status status; 239 acpi_status status = AE_OK;
236 240
237 ACPI_FUNCTION_TRACE(ex_release_mutex); 241 ACPI_FUNCTION_TRACE(ex_release_mutex);
238 242
@@ -249,7 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
249 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); 253 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
250 } 254 }
251 255
252 /* Sanity check -- we must have a valid thread ID */ 256 /* Sanity check: we must have a valid thread ID */
253 257
254 if (!walk_state->thread) { 258 if (!walk_state->thread) {
255 ACPI_ERROR((AE_INFO, 259 ACPI_ERROR((AE_INFO,
@@ -264,7 +268,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
264 */ 268 */
265 if ((obj_desc->mutex.owner_thread->thread_id != 269 if ((obj_desc->mutex.owner_thread->thread_id !=
266 walk_state->thread->thread_id) 270 walk_state->thread->thread_id)
267 && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { 271 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
268 ACPI_ERROR((AE_INFO, 272 ACPI_ERROR((AE_INFO,
269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 273 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
270 (unsigned long)walk_state->thread->thread_id, 274 (unsigned long)walk_state->thread->thread_id,
@@ -274,8 +278,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
274 } 278 }
275 279
276 /* 280 /*
277 * The sync level of the mutex must be less than or 281 * The sync level of the mutex must be less than or equal to the current
278 * equal to the current sync level 282 * sync level
279 */ 283 */
280 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { 284 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
281 ACPI_ERROR((AE_INFO, 285 ACPI_ERROR((AE_INFO,
@@ -298,11 +302,15 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
298 302
299 acpi_ex_unlink_mutex(obj_desc); 303 acpi_ex_unlink_mutex(obj_desc);
300 304
301 /* Release the mutex */ 305 /* Release the mutex, special case for Global Lock */
302 306
303 status = acpi_ex_system_release_mutex(obj_desc); 307 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
308 status = acpi_ev_release_global_lock();
309 } else {
310 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
311 }
304 312
305 /* Update the mutex and walk state, restore sync_level before acquire */ 313 /* Update the mutex and restore sync_level */
306 314
307 obj_desc->mutex.owner_thread = NULL; 315 obj_desc->mutex.owner_thread = NULL;
308 walk_state->thread->current_sync_level = 316 walk_state->thread->current_sync_level =
@@ -321,39 +329,49 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
321 * 329 *
322 * DESCRIPTION: Release all mutexes held by this thread 330 * DESCRIPTION: Release all mutexes held by this thread
323 * 331 *
332 * NOTE: This function is called as the thread is exiting the interpreter.
333 * Mutexes are not released when an individual control method is exited, but
334 * only when the parent thread actually exits the interpreter. This allows one
335 * method to acquire a mutex, and a different method to release it, as long as
336 * this is performed underneath a single parent control method.
337 *
324 ******************************************************************************/ 338 ******************************************************************************/
325 339
326void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) 340void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
327{ 341{
328 union acpi_operand_object *next = thread->acquired_mutex_list; 342 union acpi_operand_object *next = thread->acquired_mutex_list;
329 union acpi_operand_object *this; 343 union acpi_operand_object *obj_desc;
330 acpi_status status;
331 344
332 ACPI_FUNCTION_ENTRY(); 345 ACPI_FUNCTION_ENTRY();
333 346
334 /* Traverse the list of owned mutexes, releasing each one */ 347 /* Traverse the list of owned mutexes, releasing each one */
335 348
336 while (next) { 349 while (next) {
337 this = next; 350 obj_desc = next;
338 next = this->mutex.next; 351 next = obj_desc->mutex.next;
352
353 obj_desc->mutex.prev = NULL;
354 obj_desc->mutex.next = NULL;
355 obj_desc->mutex.acquisition_depth = 0;
356
357 /* Release the mutex, special case for Global Lock */
339 358
340 this->mutex.acquisition_depth = 1; 359 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
341 this->mutex.prev = NULL;
342 this->mutex.next = NULL;
343 360
344 /* Release the mutex */ 361 /* Ignore errors */
345 362
346 status = acpi_ex_system_release_mutex(this); 363 (void)acpi_ev_release_global_lock();
347 if (ACPI_FAILURE(status)) { 364 } else {
348 continue; 365 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
349 } 366 }
350 367
351 /* Mark mutex unowned */ 368 /* Mark mutex unowned */
352 369
353 this->mutex.owner_thread = NULL; 370 obj_desc->mutex.owner_thread = NULL;
354 371
355 /* Update Thread sync_level (Last mutex is the important one) */ 372 /* Update Thread sync_level (Last mutex is the important one) */
356 373
357 thread->current_sync_level = this->mutex.original_sync_level; 374 thread->current_sync_level =
375 obj_desc->mutex.original_sync_level;
358 } 376 }
359} 377}
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index d3d70364626c..1ee4fb1175c6 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 6374d8be88e0..252f10acbbcc 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -104,9 +104,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
104 status = AE_NO_MEMORY; 104 status = AE_NO_MEMORY;
105 goto cleanup; 105 goto cleanup;
106 } 106 }
107#if ACPI_MACHINE_WIDTH != 16
108 return_desc->integer.value = acpi_os_get_timer(); 107 return_desc->integer.value = acpi_os_get_timer();
109#endif
110 break; 108 break;
111 109
112 default: /* Unknown opcode */ 110 default: /* Unknown opcode */
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 7d2cbc113160..17e652e65379 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index e2d945dfd509..7fe67cf82cee 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index f0c0ba6eb408..bd80a9cb3d65 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index 44d064f427b9..a6696621ff1b 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 3cc97ba48b36..2e9ce94798c7 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function,
155 155
156 /* Create a new mapping starting at the address given */ 156 /* Create a new mapping starting at the address given */
157 157
158 status = acpi_os_map_memory(address, window_size, 158 mem_info->mapped_logical_address =
159 (void **)&mem_info-> 159 acpi_os_map_memory((acpi_native_uint) address, window_size);
160 mapped_logical_address); 160 if (!mem_info->mapped_logical_address) {
161 if (ACPI_FAILURE(status)) {
162 ACPI_ERROR((AE_INFO, 161 ACPI_ERROR((AE_INFO,
163 "Could not map memory at %8.8X%8.8X, size %X", 162 "Could not map memory at %8.8X%8.8X, size %X",
164 ACPI_FORMAT_UINT64(address), 163 ACPI_FORMAT_UINT64(address),
165 (u32) window_size)); 164 (u32) window_size));
166 mem_info->mapped_length = 0; 165 mem_info->mapped_length = 0;
167 return_ACPI_STATUS(status); 166 return_ACPI_STATUS(AE_NO_MEMORY);
168 } 167 }
169 168
170 /* Save the physical address and mapping size */ 169 /* Save the physical address and mapping size */
@@ -210,11 +209,10 @@ acpi_ex_system_memory_space_handler(u32 function,
210 *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); 209 *value = (acpi_integer) ACPI_GET32(logical_addr_ptr);
211 break; 210 break;
212 211
213#if ACPI_MACHINE_WIDTH != 16
214 case 64: 212 case 64:
215 *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); 213 *value = (acpi_integer) ACPI_GET64(logical_addr_ptr);
216 break; 214 break;
217#endif 215
218 default: 216 default:
219 /* bit_width was already validated */ 217 /* bit_width was already validated */
220 break; 218 break;
@@ -236,11 +234,9 @@ acpi_ex_system_memory_space_handler(u32 function,
236 ACPI_SET32(logical_addr_ptr) = (u32) * value; 234 ACPI_SET32(logical_addr_ptr) = (u32) * value;
237 break; 235 break;
238 236
239#if ACPI_MACHINE_WIDTH != 16
240 case 64: 237 case 64:
241 ACPI_SET64(logical_addr_ptr) = (u64) * value; 238 ACPI_SET64(logical_addr_ptr) = (u64) * value;
242 break; 239 break;
243#endif
244 240
245 default: 241 default:
246 /* bit_width was already validated */ 242 /* bit_width was already validated */
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 3089b05a1368..2b3a01cc4929 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 6499de878017..6c64e55dab0e 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -141,7 +141,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
141 acpi_status status = AE_OK; 141 acpi_status status = AE_OK;
142 union acpi_operand_object *stack_desc; 142 union acpi_operand_object *stack_desc;
143 void *temp_node; 143 void *temp_node;
144 union acpi_operand_object *obj_desc; 144 union acpi_operand_object *obj_desc = NULL;
145 u16 opcode; 145 u16 opcode;
146 146
147 ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); 147 ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
@@ -299,8 +299,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
299 status = acpi_ds_get_package_arguments(stack_desc); 299 status = acpi_ds_get_package_arguments(stack_desc);
300 break; 300 break;
301 301
302 /* These cases may never happen here, but just in case.. */
303
304 case ACPI_TYPE_BUFFER_FIELD: 302 case ACPI_TYPE_BUFFER_FIELD:
305 case ACPI_TYPE_LOCAL_REGION_FIELD: 303 case ACPI_TYPE_LOCAL_REGION_FIELD:
306 case ACPI_TYPE_LOCAL_BANK_FIELD: 304 case ACPI_TYPE_LOCAL_BANK_FIELD:
@@ -314,6 +312,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
314 status = 312 status =
315 acpi_ex_read_data_from_field(walk_state, stack_desc, 313 acpi_ex_read_data_from_field(walk_state, stack_desc,
316 &obj_desc); 314 &obj_desc);
315
316 /* Remove a reference to the original operand, then override */
317
318 acpi_ut_remove_reference(*stack_ptr);
317 *stack_ptr = (void *)obj_desc; 319 *stack_ptr = (void *)obj_desc;
318 break; 320 break;
319 321
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 4c93d0972333..ba761862a599 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -611,22 +611,20 @@ acpi_ex_resolve_operands(u16 opcode,
611 } 611 }
612 goto next_operand; 612 goto next_operand;
613 613
614 case ARGI_REGION_OR_FIELD: 614 case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
615 615
616 /* Need an operand of type REGION or a FIELD in a region */ 616 /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
617 617
618 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 618 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
619 case ACPI_TYPE_BUFFER:
619 case ACPI_TYPE_REGION: 620 case ACPI_TYPE_REGION:
620 case ACPI_TYPE_LOCAL_REGION_FIELD:
621 case ACPI_TYPE_LOCAL_BANK_FIELD:
622 case ACPI_TYPE_LOCAL_INDEX_FIELD:
623 621
624 /* Valid operand */ 622 /* Valid operand */
625 break; 623 break;
626 624
627 default: 625 default:
628 ACPI_ERROR((AE_INFO, 626 ACPI_ERROR((AE_INFO,
629 "Needed [Region/RegionField], found [%s] %p", 627 "Needed [Region/Buffer], found [%s] %p",
630 acpi_ut_get_object_type_name 628 acpi_ut_get_object_type_name
631 (obj_desc), obj_desc)); 629 (obj_desc), obj_desc));
632 630
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index 0456405ba019..f4b69a637820 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 591aaf0e18b3..1d622c625c64 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -7,7 +7,7 @@
7 *****************************************************************************/ 7 *****************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2006, R. Byron Moore 10 * Copyright (C) 2000 - 2007, R. Byron Moore
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 99ebe5adfcda..8233d40178ee 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 28aef3e69ecc..9460baff3032 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@ ACPI_MODULE_NAME("exsystem")
66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
67{ 67{
68 acpi_status status; 68 acpi_status status;
69 acpi_status status2;
70 69
71 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 70 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
72 71
@@ -79,7 +78,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
79 78
80 /* We must wait, so unlock the interpreter */ 79 /* We must wait, so unlock the interpreter */
81 80
82 acpi_ex_exit_interpreter(); 81 acpi_ex_relinquish_interpreter();
83 82
84 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 83 status = acpi_os_wait_semaphore(semaphore, 1, timeout);
85 84
@@ -89,13 +88,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
89 88
90 /* Reacquire the interpreter */ 89 /* Reacquire the interpreter */
91 90
92 status2 = acpi_ex_enter_interpreter(); 91 acpi_ex_reacquire_interpreter();
93 if (ACPI_FAILURE(status2)) {
94
95 /* Report fatal error, could not acquire interpreter */
96
97 return_ACPI_STATUS(status2);
98 }
99 } 92 }
100 93
101 return_ACPI_STATUS(status); 94 return_ACPI_STATUS(status);
@@ -119,7 +112,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
119acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 112acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
120{ 113{
121 acpi_status status; 114 acpi_status status;
122 acpi_status status2;
123 115
124 ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 116 ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
125 117
@@ -132,7 +124,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
132 124
133 /* We must wait, so unlock the interpreter */ 125 /* We must wait, so unlock the interpreter */
134 126
135 acpi_ex_exit_interpreter(); 127 acpi_ex_relinquish_interpreter();
136 128
137 status = acpi_os_acquire_mutex(mutex, timeout); 129 status = acpi_os_acquire_mutex(mutex, timeout);
138 130
@@ -142,13 +134,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
142 134
143 /* Reacquire the interpreter */ 135 /* Reacquire the interpreter */
144 136
145 status2 = acpi_ex_enter_interpreter(); 137 acpi_ex_reacquire_interpreter();
146 if (ACPI_FAILURE(status2)) {
147
148 /* Report fatal error, could not acquire interpreter */
149
150 return_ACPI_STATUS(status2);
151 }
152 } 138 }
153 139
154 return_ACPI_STATUS(status); 140 return_ACPI_STATUS(status);
@@ -209,96 +195,18 @@ acpi_status acpi_ex_system_do_stall(u32 how_long)
209 195
210acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) 196acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
211{ 197{
212 acpi_status status;
213
214 ACPI_FUNCTION_ENTRY(); 198 ACPI_FUNCTION_ENTRY();
215 199
216 /* Since this thread will sleep, we must release the interpreter */ 200 /* Since this thread will sleep, we must release the interpreter */
217 201
218 acpi_ex_exit_interpreter(); 202 acpi_ex_relinquish_interpreter();
219 203
220 acpi_os_sleep(how_long); 204 acpi_os_sleep(how_long);
221 205
222 /* And now we must get the interpreter again */ 206 /* And now we must get the interpreter again */
223 207
224 status = acpi_ex_enter_interpreter(); 208 acpi_ex_reacquire_interpreter();
225 return (status); 209 return (AE_OK);
226}
227
228/*******************************************************************************
229 *
230 * FUNCTION: acpi_ex_system_acquire_mutex
231 *
232 * PARAMETERS: time_desc - Maximum time to wait for the mutex
233 * obj_desc - The object descriptor for this op
234 *
235 * RETURN: Status
236 *
237 * DESCRIPTION: Provides an access point to perform synchronization operations
238 * within the AML. This function will cause a lock to be generated
239 * for the Mutex pointed to by obj_desc.
240 *
241 ******************************************************************************/
242
243acpi_status
244acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc,
245 union acpi_operand_object * obj_desc)
246{
247 acpi_status status = AE_OK;
248
249 ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc);
250
251 if (!obj_desc) {
252 return_ACPI_STATUS(AE_BAD_PARAMETER);
253 }
254
255 /* Support for the _GL_ Mutex object -- go get the global lock */
256
257 if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) {
258 status =
259 acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
260 return_ACPI_STATUS(status);
261 }
262
263 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
264 (u16) time_desc->integer.value);
265 return_ACPI_STATUS(status);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION: acpi_ex_system_release_mutex
271 *
272 * PARAMETERS: obj_desc - The object descriptor for this op
273 *
274 * RETURN: Status
275 *
276 * DESCRIPTION: Provides an access point to perform synchronization operations
277 * within the AML. This operation is a request to release a
278 * previously acquired Mutex. If the Mutex variable is set then
279 * it will be decremented.
280 *
281 ******************************************************************************/
282
283acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
284{
285 acpi_status status = AE_OK;
286
287 ACPI_FUNCTION_TRACE(ex_system_release_mutex);
288
289 if (!obj_desc) {
290 return_ACPI_STATUS(AE_BAD_PARAMETER);
291 }
292
293 /* Support for the _GL_ Mutex object -- release the global lock */
294
295 if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) {
296 status = acpi_ev_release_global_lock();
297 return_ACPI_STATUS(status);
298 }
299
300 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
301 return_ACPI_STATUS(AE_OK);
302} 210}
303 211
304/******************************************************************************* 212/*******************************************************************************
@@ -314,7 +222,7 @@ acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
314 * 222 *
315 ******************************************************************************/ 223 ******************************************************************************/
316 224
317acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) 225acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
318{ 226{
319 acpi_status status = AE_OK; 227 acpi_status status = AE_OK;
320 228
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 982c8b65876f..6b0aeccbb69b 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -76,14 +76,15 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
76 * 76 *
77 * PARAMETERS: None 77 * PARAMETERS: None
78 * 78 *
79 * RETURN: Status 79 * RETURN: None
80 * 80 *
81 * DESCRIPTION: Enter the interpreter execution region. Failure to enter 81 * DESCRIPTION: Enter the interpreter execution region. Failure to enter
82 * the interpreter region is a fatal system error 82 * the interpreter region is a fatal system error. Used in
83 * conjunction with exit_interpreter.
83 * 84 *
84 ******************************************************************************/ 85 ******************************************************************************/
85 86
86acpi_status acpi_ex_enter_interpreter(void) 87void acpi_ex_enter_interpreter(void)
87{ 88{
88 acpi_status status; 89 acpi_status status;
89 90
@@ -91,31 +92,55 @@ acpi_status acpi_ex_enter_interpreter(void)
91 92
92 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 93 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
93 if (ACPI_FAILURE(status)) { 94 if (ACPI_FAILURE(status)) {
94 ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); 95 ACPI_ERROR((AE_INFO,
96 "Could not acquire AML Interpreter mutex"));
95 } 97 }
96 98
97 return_ACPI_STATUS(status); 99 return_VOID;
98} 100}
99 101
100/******************************************************************************* 102/*******************************************************************************
101 * 103 *
102 * FUNCTION: acpi_ex_exit_interpreter 104 * FUNCTION: acpi_ex_reacquire_interpreter
103 * 105 *
104 * PARAMETERS: None 106 * PARAMETERS: None
105 * 107 *
106 * RETURN: None 108 * RETURN: None
107 * 109 *
108 * DESCRIPTION: Exit the interpreter execution region 110 * DESCRIPTION: Reacquire the interpreter execution region from within the
111 * interpreter code. Failure to enter the interpreter region is a
112 * fatal system error. Used in conjuction with
113 * relinquish_interpreter
114 *
115 ******************************************************************************/
116
117void acpi_ex_reacquire_interpreter(void)
118{
119 ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
120
121 /*
122 * If the global serialized flag is set, do not release the interpreter,
123 * since it was not actually released by acpi_ex_relinquish_interpreter.
124 * This forces the interpreter to be single threaded.
125 */
126 if (!acpi_gbl_all_methods_serialized) {
127 acpi_ex_enter_interpreter();
128 }
129
130 return_VOID;
131}
132
133/*******************************************************************************
134 *
135 * FUNCTION: acpi_ex_exit_interpreter
136 *
137 * PARAMETERS: None
138 *
139 * RETURN: None
109 * 140 *
110 * Cases where the interpreter is unlocked: 141 * DESCRIPTION: Exit the interpreter execution region. This is the top level
111 * 1) Completion of the execution of a control method 142 * routine used to exit the interpreter when all processing has
112 * 2) Method blocked on a Sleep() AML opcode 143 * been completed.
113 * 3) Method blocked on an Acquire() AML opcode
114 * 4) Method blocked on a Wait() AML opcode
115 * 5) Method blocked to acquire the global lock
116 * 6) Method blocked to execute a serialized control method that is
117 * already executing
118 * 7) About to invoke a user-installed opregion handler
119 * 144 *
120 ******************************************************************************/ 145 ******************************************************************************/
121 146
@@ -127,7 +152,46 @@ void acpi_ex_exit_interpreter(void)
127 152
128 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 153 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
129 if (ACPI_FAILURE(status)) { 154 if (ACPI_FAILURE(status)) {
130 ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); 155 ACPI_ERROR((AE_INFO,
156 "Could not release AML Interpreter mutex"));
157 }
158
159 return_VOID;
160}
161
162/*******************************************************************************
163 *
164 * FUNCTION: acpi_ex_relinquish_interpreter
165 *
166 * PARAMETERS: None
167 *
168 * RETURN: None
169 *
170 * DESCRIPTION: Exit the interpreter execution region, from within the
171 * interpreter - before attempting an operation that will possibly
172 * block the running thread.
173 *
174 * Cases where the interpreter is unlocked internally
175 * 1) Method to be blocked on a Sleep() AML opcode
176 * 2) Method to be blocked on an Acquire() AML opcode
177 * 3) Method to be blocked on a Wait() AML opcode
178 * 4) Method to be blocked to acquire the global lock
179 * 5) Method to be blocked waiting to execute a serialized control method
180 * that is currently executing
181 * 6) About to invoke a user-installed opregion handler
182 *
183 ******************************************************************************/
184
185void acpi_ex_relinquish_interpreter(void)
186{
187 ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
188
189 /*
190 * If the global serialized flag is set, do not release the interpreter.
191 * This forces the interpreter to be single threaded.
192 */
193 if (!acpi_gbl_all_methods_serialized) {
194 acpi_ex_exit_interpreter();
131 } 195 }
132 196
133 return_VOID; 197 return_VOID;
@@ -141,8 +205,8 @@ void acpi_ex_exit_interpreter(void)
141 * 205 *
142 * RETURN: none 206 * RETURN: none
143 * 207 *
144 * DESCRIPTION: Truncate a number to 32-bits if the currently executing method 208 * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
145 * belongs to a 32-bit ACPI table. 209 * 32-bit, as determined by the revision of the DSDT.
146 * 210 *
147 ******************************************************************************/ 211 ******************************************************************************/
148 212
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index f305a826ca2d..af22fdf73413 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
48 48
49static int acpi_fan_add(struct acpi_device *device); 49static int acpi_fan_add(struct acpi_device *device);
50static int acpi_fan_remove(struct acpi_device *device, int type); 50static int acpi_fan_remove(struct acpi_device *device, int type);
51static int acpi_fan_suspend(struct acpi_device *device, int state); 51static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
52static int acpi_fan_resume(struct acpi_device *device, int state); 52static int acpi_fan_resume(struct acpi_device *device);
53 53
54static struct acpi_driver acpi_fan_driver = { 54static struct acpi_driver acpi_fan_driver = {
55 .name = ACPI_FAN_DRIVER_NAME, 55 .name = ACPI_FAN_DRIVER_NAME,
@@ -237,7 +237,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
237 return 0; 237 return 0;
238} 238}
239 239
240static int acpi_fan_suspend(struct acpi_device *device, int state) 240static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
241{ 241{
242 if (!device) 242 if (!device)
243 return -EINVAL; 243 return -EINVAL;
@@ -247,7 +247,7 @@ static int acpi_fan_suspend(struct acpi_device *device, int state)
247 return AE_OK; 247 return AE_OK;
248} 248}
249 249
250static int acpi_fan_resume(struct acpi_device *device, int state) 250static int acpi_fan_resume(struct acpi_device *device)
251{ 251{
252 int result = 0; 252 int result = 0;
253 int power_state = 0; 253 int power_state = 0;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 8a0324b43e53..7b6c9ff9bebe 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -86,129 +86,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
86 return ret; 86 return ret;
87} 87}
88 88
89/* Get PCI root bridge's handle from its segment and bus number */
90struct acpi_find_pci_root {
91 unsigned int seg;
92 unsigned int bus;
93 acpi_handle handle;
94};
95
96static acpi_status
97do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
98{
99 unsigned long *busnr = data;
100 struct acpi_resource_address64 address;
101
102 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
103 resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
104 resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
105 return AE_OK;
106
107 acpi_resource_to_address64(resource, &address);
108 if ((address.address_length > 0) &&
109 (address.resource_type == ACPI_BUS_NUMBER_RANGE))
110 *busnr = address.minimum;
111
112 return AE_OK;
113}
114
115static int get_root_bridge_busnr(acpi_handle handle)
116{
117 acpi_status status;
118 unsigned long bus, bbn;
119 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
120
121 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
122
123 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
124 &bbn);
125 if (status == AE_NOT_FOUND) {
126 /* Assume bus = 0 */
127 printk(KERN_INFO PREFIX
128 "Assume root bridge [%s] bus is 0\n",
129 (char *)buffer.pointer);
130 status = AE_OK;
131 bbn = 0;
132 }
133 if (ACPI_FAILURE(status)) {
134 bbn = -ENODEV;
135 goto exit;
136 }
137 if (bbn > 0)
138 goto exit;
139
140 /* _BBN in some systems return 0 for all root bridges */
141 bus = -1;
142 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
143 do_root_bridge_busnr_callback, &bus);
144 /* If _CRS failed, we just use _BBN */
145 if (ACPI_FAILURE(status) || (bus == -1))
146 goto exit;
147 /* We select _CRS */
148 if (bbn != bus) {
149 printk(KERN_INFO PREFIX
150 "_BBN and _CRS returns different value for %s. Select _CRS\n",
151 (char *)buffer.pointer);
152 bbn = bus;
153 }
154 exit:
155 kfree(buffer.pointer);
156 return (int)bbn;
157}
158
159static acpi_status
160find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
161{
162 struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
163 unsigned long seg, bus;
164 acpi_status status;
165 int tmp;
166 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
167
168 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
169
170 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
171 if (status == AE_NOT_FOUND) {
172 /* Assume seg = 0 */
173 status = AE_OK;
174 seg = 0;
175 }
176 if (ACPI_FAILURE(status)) {
177 status = AE_CTRL_DEPTH;
178 goto exit;
179 }
180
181 tmp = get_root_bridge_busnr(handle);
182 if (tmp < 0) {
183 printk(KERN_ERR PREFIX
184 "Find root bridge failed for %s\n",
185 (char *)buffer.pointer);
186 status = AE_CTRL_DEPTH;
187 goto exit;
188 }
189 bus = tmp;
190
191 if (seg == find->seg && bus == find->bus)
192 {
193 find->handle = handle;
194 status = AE_CTRL_TERMINATE;
195 }
196 else
197 status = AE_OK;
198 exit:
199 kfree(buffer.pointer);
200 return status;
201}
202
203acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
204{
205 struct acpi_find_pci_root find = { seg, bus, NULL };
206
207 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
208 return find.handle;
209}
210EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
211
212/* Get device's handler per its address under its parent */ 89/* Get device's handler per its address under its parent */
213struct acpi_find_child { 90struct acpi_find_child {
214 acpi_handle handle; 91 acpi_handle handle;
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index de50fab2a910..6031ca13dd2f 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -49,41 +49,6 @@ ACPI_MODULE_NAME("hwacpi")
49 49
50/****************************************************************************** 50/******************************************************************************
51 * 51 *
52 * FUNCTION: acpi_hw_initialize
53 *
54 * PARAMETERS: None
55 *
56 * RETURN: Status
57 *
58 * DESCRIPTION: Initialize and validate the various ACPI registers defined in
59 * the FADT.
60 *
61 ******************************************************************************/
62acpi_status acpi_hw_initialize(void)
63{
64 acpi_status status;
65
66 ACPI_FUNCTION_TRACE(hw_initialize);
67
68 /* We must have the ACPI tables by the time we get here */
69
70 if (!acpi_gbl_FADT) {
71 ACPI_ERROR((AE_INFO, "No FADT is present"));
72 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
73 }
74
75 /* Sanity check the FADT for valid values */
76
77 status = acpi_ut_validate_fadt();
78 if (ACPI_FAILURE(status)) {
79 return_ACPI_STATUS(status);
80 }
81
82 return_ACPI_STATUS(AE_OK);
83}
84
85/******************************************************************************
86 *
87 * FUNCTION: acpi_hw_set_mode 52 * FUNCTION: acpi_hw_set_mode
88 * 53 *
89 * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY 54 * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
@@ -93,7 +58,6 @@ acpi_status acpi_hw_initialize(void)
93 * DESCRIPTION: Transitions the system into the requested mode. 58 * DESCRIPTION: Transitions the system into the requested mode.
94 * 59 *
95 ******************************************************************************/ 60 ******************************************************************************/
96
97acpi_status acpi_hw_set_mode(u32 mode) 61acpi_status acpi_hw_set_mode(u32 mode)
98{ 62{
99 63
@@ -106,7 +70,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
106 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, 70 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
107 * system does not support mode transition. 71 * system does not support mode transition.
108 */ 72 */
109 if (!acpi_gbl_FADT->smi_cmd) { 73 if (!acpi_gbl_FADT.smi_command) {
110 ACPI_ERROR((AE_INFO, 74 ACPI_ERROR((AE_INFO,
111 "No SMI_CMD in FADT, mode transition failed")); 75 "No SMI_CMD in FADT, mode transition failed"));
112 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 76 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
@@ -119,7 +83,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
119 * we make sure both the numbers are zero to determine these 83 * we make sure both the numbers are zero to determine these
120 * transitions are not supported. 84 * transitions are not supported.
121 */ 85 */
122 if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { 86 if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
123 ACPI_ERROR((AE_INFO, 87 ACPI_ERROR((AE_INFO,
124 "No ACPI mode transition supported in this system (enable/disable both zero)")); 88 "No ACPI mode transition supported in this system (enable/disable both zero)"));
125 return_ACPI_STATUS(AE_OK); 89 return_ACPI_STATUS(AE_OK);
@@ -130,9 +94,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
130 94
131 /* BIOS should have disabled ALL fixed and GP events */ 95 /* BIOS should have disabled ALL fixed and GP events */
132 96
133 status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, 97 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
134 (u32) acpi_gbl_FADT->acpi_enable, 98 (u32) acpi_gbl_FADT.acpi_enable, 8);
135 8);
136 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 99 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
137 "Attempting to enable ACPI mode\n")); 100 "Attempting to enable ACPI mode\n"));
138 break; 101 break;
@@ -143,8 +106,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
143 * BIOS should clear all fixed status bits and restore fixed event 106 * BIOS should clear all fixed status bits and restore fixed event
144 * enable bits to default 107 * enable bits to default
145 */ 108 */
146 status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, 109 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
147 (u32) acpi_gbl_FADT->acpi_disable, 110 (u32) acpi_gbl_FADT.acpi_disable,
148 8); 111 8);
149 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 112 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
150 "Attempting to enable Legacy (non-ACPI) mode\n")); 113 "Attempting to enable Legacy (non-ACPI) mode\n"));
@@ -204,12 +167,11 @@ u32 acpi_hw_get_mode(void)
204 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, 167 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
205 * system does not support mode transition. 168 * system does not support mode transition.
206 */ 169 */
207 if (!acpi_gbl_FADT->smi_cmd) { 170 if (!acpi_gbl_FADT.smi_command) {
208 return_UINT32(ACPI_SYS_MODE_ACPI); 171 return_UINT32(ACPI_SYS_MODE_ACPI);
209 } 172 }
210 173
211 status = 174 status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
212 acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
213 if (ACPI_FAILURE(status)) { 175 if (ACPI_FAILURE(status)) {
214 return_UINT32(ACPI_SYS_MODE_LEGACY); 176 return_UINT32(ACPI_SYS_MODE_LEGACY);
215 } 177 }
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 608a3a60ee11..117a05cadaaa 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -105,14 +105,20 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info)
105acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) 105acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
106{ 106{
107 acpi_status status; 107 acpi_status status;
108 u8 register_bit;
108 109
109 ACPI_FUNCTION_ENTRY(); 110 ACPI_FUNCTION_ENTRY();
110 111
112 register_bit = (u8)
113 (1 <<
114 (gpe_event_info->gpe_number -
115 gpe_event_info->register_info->base_gpe_number));
116
111 /* 117 /*
112 * Write a one to the appropriate bit in the status register to 118 * Write a one to the appropriate bit in the status register to
113 * clear this GPE. 119 * clear this GPE.
114 */ 120 */
115 status = acpi_hw_low_level_write(8, gpe_event_info->register_bit, 121 status = acpi_hw_low_level_write(8, register_bit,
116 &gpe_event_info->register_info-> 122 &gpe_event_info->register_info->
117 status_address); 123 status_address);
118 124
@@ -155,7 +161,10 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
155 161
156 /* Get the register bitmask for this GPE */ 162 /* Get the register bitmask for this GPE */
157 163
158 register_bit = gpe_event_info->register_bit; 164 register_bit = (u8)
165 (1 <<
166 (gpe_event_info->gpe_number -
167 gpe_event_info->register_info->base_gpe_number));
159 168
160 /* GPE currently enabled? (enabled for runtime?) */ 169 /* GPE currently enabled? (enabled for runtime?) */
161 170
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index fa58c1edce1e..1d371fa663f2 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -7,7 +7,7 @@
7 ******************************************************************************/ 7 ******************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2006, R. Byron Moore 10 * Copyright (C) 2000 - 2007, R. Byron Moore
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
@@ -54,17 +54,15 @@ ACPI_MODULE_NAME("hwregs")
54 * 54 *
55 * FUNCTION: acpi_hw_clear_acpi_status 55 * FUNCTION: acpi_hw_clear_acpi_status
56 * 56 *
57 * PARAMETERS: Flags - Lock the hardware or not 57 * PARAMETERS: None
58 * 58 *
59 * RETURN: none 59 * RETURN: None
60 * 60 *
61 * DESCRIPTION: Clears all fixed and general purpose status bits 61 * DESCRIPTION: Clears all fixed and general purpose status bits
62 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 62 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
63 * 63 *
64 * NOTE: TBD: Flags parameter is obsolete, to be removed
65 *
66 ******************************************************************************/ 64 ******************************************************************************/
67acpi_status acpi_hw_clear_acpi_status(u32 flags) 65acpi_status acpi_hw_clear_acpi_status(void)
68{ 66{
69 acpi_status status; 67 acpi_status status;
70 acpi_cpu_flags lock_flags = 0; 68 acpi_cpu_flags lock_flags = 0;
@@ -73,7 +71,7 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
73 71
74 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", 72 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
75 ACPI_BITMASK_ALL_FIXED_STATUS, 73 ACPI_BITMASK_ALL_FIXED_STATUS,
76 (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); 74 (u16) acpi_gbl_FADT.xpm1a_event_block.address));
77 75
78 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 76 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
79 77
@@ -86,10 +84,10 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
86 84
87 /* Clear the fixed events */ 85 /* Clear the fixed events */
88 86
89 if (acpi_gbl_FADT->xpm1b_evt_blk.address) { 87 if (acpi_gbl_FADT.xpm1b_event_block.address) {
90 status = 88 status =
91 acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, 89 acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
92 &acpi_gbl_FADT->xpm1b_evt_blk); 90 &acpi_gbl_FADT.xpm1b_event_block);
93 if (ACPI_FAILURE(status)) { 91 if (ACPI_FAILURE(status)) {
94 goto unlock_and_exit; 92 goto unlock_and_exit;
95 } 93 }
@@ -253,18 +251,15 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
253 * 251 *
254 * PARAMETERS: register_id - ID of ACPI bit_register to access 252 * PARAMETERS: register_id - ID of ACPI bit_register to access
255 * return_value - Value that was read from the register 253 * return_value - Value that was read from the register
256 * Flags - Lock the hardware or not
257 * 254 *
258 * RETURN: Status and the value read from specified Register. Value 255 * RETURN: Status and the value read from specified Register. Value
259 * returned is normalized to bit0 (is shifted all the way right) 256 * returned is normalized to bit0 (is shifted all the way right)
260 * 257 *
261 * DESCRIPTION: ACPI bit_register read function. 258 * DESCRIPTION: ACPI bit_register read function.
262 * 259 *
263 * NOTE: TBD: Flags parameter is obsolete, to be removed
264 *
265 ******************************************************************************/ 260 ******************************************************************************/
266 261
267acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) 262acpi_status acpi_get_register(u32 register_id, u32 * return_value)
268{ 263{
269 u32 register_value = 0; 264 u32 register_value = 0;
270 struct acpi_bit_register_info *bit_reg_info; 265 struct acpi_bit_register_info *bit_reg_info;
@@ -312,16 +307,13 @@ ACPI_EXPORT_SYMBOL(acpi_get_register)
312 * PARAMETERS: register_id - ID of ACPI bit_register to access 307 * PARAMETERS: register_id - ID of ACPI bit_register to access
313 * Value - (only used on write) value to write to the 308 * Value - (only used on write) value to write to the
314 * Register, NOT pre-normalized to the bit pos 309 * Register, NOT pre-normalized to the bit pos
315 * Flags - Lock the hardware or not
316 * 310 *
317 * RETURN: Status 311 * RETURN: Status
318 * 312 *
319 * DESCRIPTION: ACPI Bit Register write function. 313 * DESCRIPTION: ACPI Bit Register write function.
320 * 314 *
321 * NOTE: TBD: Flags parameter is obsolete, to be removed
322 *
323 ******************************************************************************/ 315 ******************************************************************************/
324acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) 316acpi_status acpi_set_register(u32 register_id, u32 value)
325{ 317{
326 u32 register_value = 0; 318 u32 register_value = 0;
327 struct acpi_bit_register_info *bit_reg_info; 319 struct acpi_bit_register_info *bit_reg_info;
@@ -422,8 +414,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
422 ACPI_DEBUG_PRINT((ACPI_DB_IO, 414 ACPI_DEBUG_PRINT((ACPI_DB_IO,
423 "PM2 control: Read %X from %8.8X%8.8X\n", 415 "PM2 control: Read %X from %8.8X%8.8X\n",
424 register_value, 416 register_value,
425 ACPI_FORMAT_UINT64(acpi_gbl_FADT-> 417 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
426 xpm2_cnt_blk.address))); 418 xpm2_control_block.
419 address)));
427 420
428 ACPI_REGISTER_INSERT_VALUE(register_value, 421 ACPI_REGISTER_INSERT_VALUE(register_value,
429 bit_reg_info->bit_position, 422 bit_reg_info->bit_position,
@@ -433,8 +426,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
433 ACPI_DEBUG_PRINT((ACPI_DB_IO, 426 ACPI_DEBUG_PRINT((ACPI_DB_IO,
434 "About to write %4.4X to %8.8X%8.8X\n", 427 "About to write %4.4X to %8.8X%8.8X\n",
435 register_value, 428 register_value,
436 ACPI_FORMAT_UINT64(acpi_gbl_FADT-> 429 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
437 xpm2_cnt_blk.address))); 430 xpm2_control_block.
431 address)));
438 432
439 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 433 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
440 ACPI_REGISTER_PM2_CONTROL, 434 ACPI_REGISTER_PM2_CONTROL,
@@ -495,7 +489,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
495 489
496 status = 490 status =
497 acpi_hw_low_level_read(16, &value1, 491 acpi_hw_low_level_read(16, &value1,
498 &acpi_gbl_FADT->xpm1a_evt_blk); 492 &acpi_gbl_FADT.xpm1a_event_block);
499 if (ACPI_FAILURE(status)) { 493 if (ACPI_FAILURE(status)) {
500 goto unlock_and_exit; 494 goto unlock_and_exit;
501 } 495 }
@@ -504,7 +498,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
504 498
505 status = 499 status =
506 acpi_hw_low_level_read(16, &value2, 500 acpi_hw_low_level_read(16, &value2,
507 &acpi_gbl_FADT->xpm1b_evt_blk); 501 &acpi_gbl_FADT.xpm1b_event_block);
508 value1 |= value2; 502 value1 |= value2;
509 break; 503 break;
510 504
@@ -527,14 +521,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
527 521
528 status = 522 status =
529 acpi_hw_low_level_read(16, &value1, 523 acpi_hw_low_level_read(16, &value1,
530 &acpi_gbl_FADT->xpm1a_cnt_blk); 524 &acpi_gbl_FADT.xpm1a_control_block);
531 if (ACPI_FAILURE(status)) { 525 if (ACPI_FAILURE(status)) {
532 goto unlock_and_exit; 526 goto unlock_and_exit;
533 } 527 }
534 528
535 status = 529 status =
536 acpi_hw_low_level_read(16, &value2, 530 acpi_hw_low_level_read(16, &value2,
537 &acpi_gbl_FADT->xpm1b_cnt_blk); 531 &acpi_gbl_FADT.xpm1b_control_block);
538 value1 |= value2; 532 value1 |= value2;
539 break; 533 break;
540 534
@@ -542,19 +536,20 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
542 536
543 status = 537 status =
544 acpi_hw_low_level_read(8, &value1, 538 acpi_hw_low_level_read(8, &value1,
545 &acpi_gbl_FADT->xpm2_cnt_blk); 539 &acpi_gbl_FADT.xpm2_control_block);
546 break; 540 break;
547 541
548 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 542 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
549 543
550 status = 544 status =
551 acpi_hw_low_level_read(32, &value1, 545 acpi_hw_low_level_read(32, &value1,
552 &acpi_gbl_FADT->xpm_tmr_blk); 546 &acpi_gbl_FADT.xpm_timer_block);
553 break; 547 break;
554 548
555 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 549 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
556 550
557 status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8); 551 status =
552 acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
558 break; 553 break;
559 554
560 default: 555 default:
@@ -635,7 +630,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
635 630
636 status = 631 status =
637 acpi_hw_low_level_write(16, value, 632 acpi_hw_low_level_write(16, value,
638 &acpi_gbl_FADT->xpm1a_evt_blk); 633 &acpi_gbl_FADT.xpm1a_event_block);
639 if (ACPI_FAILURE(status)) { 634 if (ACPI_FAILURE(status)) {
640 goto unlock_and_exit; 635 goto unlock_and_exit;
641 } 636 }
@@ -644,7 +639,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
644 639
645 status = 640 status =
646 acpi_hw_low_level_write(16, value, 641 acpi_hw_low_level_write(16, value,
647 &acpi_gbl_FADT->xpm1b_evt_blk); 642 &acpi_gbl_FADT.xpm1b_event_block);
648 break; 643 break;
649 644
650 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 645 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
@@ -682,49 +677,50 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
682 677
683 status = 678 status =
684 acpi_hw_low_level_write(16, value, 679 acpi_hw_low_level_write(16, value,
685 &acpi_gbl_FADT->xpm1a_cnt_blk); 680 &acpi_gbl_FADT.xpm1a_control_block);
686 if (ACPI_FAILURE(status)) { 681 if (ACPI_FAILURE(status)) {
687 goto unlock_and_exit; 682 goto unlock_and_exit;
688 } 683 }
689 684
690 status = 685 status =
691 acpi_hw_low_level_write(16, value, 686 acpi_hw_low_level_write(16, value,
692 &acpi_gbl_FADT->xpm1b_cnt_blk); 687 &acpi_gbl_FADT.xpm1b_control_block);
693 break; 688 break;
694 689
695 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 690 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
696 691
697 status = 692 status =
698 acpi_hw_low_level_write(16, value, 693 acpi_hw_low_level_write(16, value,
699 &acpi_gbl_FADT->xpm1a_cnt_blk); 694 &acpi_gbl_FADT.xpm1a_control_block);
700 break; 695 break;
701 696
702 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 697 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
703 698
704 status = 699 status =
705 acpi_hw_low_level_write(16, value, 700 acpi_hw_low_level_write(16, value,
706 &acpi_gbl_FADT->xpm1b_cnt_blk); 701 &acpi_gbl_FADT.xpm1b_control_block);
707 break; 702 break;
708 703
709 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 704 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
710 705
711 status = 706 status =
712 acpi_hw_low_level_write(8, value, 707 acpi_hw_low_level_write(8, value,
713 &acpi_gbl_FADT->xpm2_cnt_blk); 708 &acpi_gbl_FADT.xpm2_control_block);
714 break; 709 break;
715 710
716 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 711 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
717 712
718 status = 713 status =
719 acpi_hw_low_level_write(32, value, 714 acpi_hw_low_level_write(32, value,
720 &acpi_gbl_FADT->xpm_tmr_blk); 715 &acpi_gbl_FADT.xpm_timer_block);
721 break; 716 break;
722 717
723 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 718 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
724 719
725 /* SMI_CMD is currently always in IO space */ 720 /* SMI_CMD is currently always in IO space */
726 721
727 status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8); 722 status =
723 acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
728 break; 724 break;
729 725
730 default: 726 default:
@@ -783,7 +779,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
783 * Two address spaces supported: Memory or IO. 779 * Two address spaces supported: Memory or IO.
784 * PCI_Config is not supported here because the GAS struct is insufficient 780 * PCI_Config is not supported here because the GAS struct is insufficient
785 */ 781 */
786 switch (reg->address_space_id) { 782 switch (reg->space_id) {
787 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 783 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
788 784
789 status = acpi_os_read_memory((acpi_physical_address) address, 785 status = acpi_os_read_memory((acpi_physical_address) address,
@@ -792,22 +788,20 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
792 788
793 case ACPI_ADR_SPACE_SYSTEM_IO: 789 case ACPI_ADR_SPACE_SYSTEM_IO:
794 790
795 status = acpi_os_read_port((acpi_io_address) address, 791 status =
796 value, width); 792 acpi_os_read_port((acpi_io_address) address, value, width);
797 break; 793 break;
798 794
799 default: 795 default:
800 ACPI_ERROR((AE_INFO, 796 ACPI_ERROR((AE_INFO,
801 "Unsupported address space: %X", 797 "Unsupported address space: %X", reg->space_id));
802 reg->address_space_id));
803 return (AE_BAD_PARAMETER); 798 return (AE_BAD_PARAMETER);
804 } 799 }
805 800
806 ACPI_DEBUG_PRINT((ACPI_DB_IO, 801 ACPI_DEBUG_PRINT((ACPI_DB_IO,
807 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 802 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
808 *value, width, 803 *value, width, ACPI_FORMAT_UINT64(address),
809 ACPI_FORMAT_UINT64(address), 804 acpi_ut_get_region_name(reg->space_id)));
810 acpi_ut_get_region_name(reg->address_space_id)));
811 805
812 return (status); 806 return (status);
813} 807}
@@ -854,7 +848,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
854 * Two address spaces supported: Memory or IO. 848 * Two address spaces supported: Memory or IO.
855 * PCI_Config is not supported here because the GAS struct is insufficient 849 * PCI_Config is not supported here because the GAS struct is insufficient
856 */ 850 */
857 switch (reg->address_space_id) { 851 switch (reg->space_id) {
858 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 852 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
859 853
860 status = acpi_os_write_memory((acpi_physical_address) address, 854 status = acpi_os_write_memory((acpi_physical_address) address,
@@ -863,22 +857,20 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
863 857
864 case ACPI_ADR_SPACE_SYSTEM_IO: 858 case ACPI_ADR_SPACE_SYSTEM_IO:
865 859
866 status = acpi_os_write_port((acpi_io_address) address, 860 status = acpi_os_write_port((acpi_io_address) address, value,
867 value, width); 861 width);
868 break; 862 break;
869 863
870 default: 864 default:
871 ACPI_ERROR((AE_INFO, 865 ACPI_ERROR((AE_INFO,
872 "Unsupported address space: %X", 866 "Unsupported address space: %X", reg->space_id));
873 reg->address_space_id));
874 return (AE_BAD_PARAMETER); 867 return (AE_BAD_PARAMETER);
875 } 868 }
876 869
877 ACPI_DEBUG_PRINT((ACPI_DB_IO, 870 ACPI_DEBUG_PRINT((ACPI_DB_IO,
878 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 871 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
879 value, width, 872 value, width, ACPI_FORMAT_UINT64(address),
880 ACPI_FORMAT_UINT64(address), 873 acpi_ut_get_region_name(reg->space_id)));
881 acpi_ut_get_region_name(reg->address_space_id)));
882 874
883 return (status); 875 return (status);
884} 876}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 8bb43cae60c2..57901ca3ade9 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@
43 */ 43 */
44 44
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/actables.h>
46 47
47#define _COMPONENT ACPI_HARDWARE 48#define _COMPONENT ACPI_HARDWARE
48ACPI_MODULE_NAME("hwsleep") 49ACPI_MODULE_NAME("hwsleep")
@@ -62,17 +63,32 @@ ACPI_MODULE_NAME("hwsleep")
62acpi_status 63acpi_status
63acpi_set_firmware_waking_vector(acpi_physical_address physical_address) 64acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
64{ 65{
66 struct acpi_table_facs *facs;
67 acpi_status status;
65 68
66 ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); 69 ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
67 70
71 /* Get the FACS */
72
73 status =
74 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
75 (struct acpi_table_header **)&facs);
76 if (ACPI_FAILURE(status)) {
77 return_ACPI_STATUS(status);
78 }
79
68 /* Set the vector */ 80 /* Set the vector */
69 81
70 if (acpi_gbl_common_fACS.vector_width == 32) { 82 if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
71 *(ACPI_CAST_PTR 83 /*
72 (u32, acpi_gbl_common_fACS.firmware_waking_vector)) 84 * ACPI 1.0 FACS or short table or optional X_ field is zero
73 = (u32) physical_address; 85 */
86 facs->firmware_waking_vector = (u32) physical_address;
74 } else { 87 } else {
75 *acpi_gbl_common_fACS.firmware_waking_vector = physical_address; 88 /*
89 * ACPI 2.0 FACS with valid X_ field
90 */
91 facs->xfirmware_waking_vector = physical_address;
76 } 92 }
77 93
78 return_ACPI_STATUS(AE_OK); 94 return_ACPI_STATUS(AE_OK);
@@ -97,6 +113,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
97acpi_status 113acpi_status
98acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) 114acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
99{ 115{
116 struct acpi_table_facs *facs;
117 acpi_status status;
100 118
101 ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); 119 ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector);
102 120
@@ -104,16 +122,29 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
104 return_ACPI_STATUS(AE_BAD_PARAMETER); 122 return_ACPI_STATUS(AE_BAD_PARAMETER);
105 } 123 }
106 124
125 /* Get the FACS */
126
127 status =
128 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
129 (struct acpi_table_header **)&facs);
130 if (ACPI_FAILURE(status)) {
131 return_ACPI_STATUS(status);
132 }
133
107 /* Get the vector */ 134 /* Get the vector */
108 135
109 if (acpi_gbl_common_fACS.vector_width == 32) { 136 if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
110 *physical_address = (acpi_physical_address) 137 /*
111 * 138 * ACPI 1.0 FACS or short table or optional X_ field is zero
112 (ACPI_CAST_PTR 139 */
113 (u32, acpi_gbl_common_fACS.firmware_waking_vector)); 140 *physical_address =
141 (acpi_physical_address) facs->firmware_waking_vector;
114 } else { 142 } else {
143 /*
144 * ACPI 2.0 FACS with valid X_ field
145 */
115 *physical_address = 146 *physical_address =
116 *acpi_gbl_common_fACS.firmware_waking_vector; 147 (acpi_physical_address) facs->xfirmware_waking_vector;
117 } 148 }
118 149
119 return_ACPI_STATUS(AE_OK); 150 return_ACPI_STATUS(AE_OK);
@@ -246,15 +277,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
246 277
247 /* Clear wake status */ 278 /* Clear wake status */
248 279
249 status = 280 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
250 acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
251 if (ACPI_FAILURE(status)) { 281 if (ACPI_FAILURE(status)) {
252 return_ACPI_STATUS(status); 282 return_ACPI_STATUS(status);
253 } 283 }
254 284
255 /* Clear all fixed and general purpose status bits */ 285 /* Clear all fixed and general purpose status bits */
256 286
257 status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); 287 status = acpi_hw_clear_acpi_status();
258 if (ACPI_FAILURE(status)) { 288 if (ACPI_FAILURE(status)) {
259 return_ACPI_STATUS(status); 289 return_ACPI_STATUS(status);
260 } 290 }
@@ -367,8 +397,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
367 /* Wait until we enter sleep state */ 397 /* Wait until we enter sleep state */
368 398
369 do { 399 do {
370 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, 400 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
371 ACPI_MTX_DO_NOT_LOCK);
372 if (ACPI_FAILURE(status)) { 401 if (ACPI_FAILURE(status)) {
373 return_ACPI_STATUS(status); 402 return_ACPI_STATUS(status);
374 } 403 }
@@ -401,13 +430,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
401 430
402 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); 431 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
403 432
404 status = 433 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
405 acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
406 if (ACPI_FAILURE(status)) { 434 if (ACPI_FAILURE(status)) {
407 return_ACPI_STATUS(status); 435 return_ACPI_STATUS(status);
408 } 436 }
409 437
410 status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); 438 status = acpi_hw_clear_acpi_status();
411 if (ACPI_FAILURE(status)) { 439 if (ACPI_FAILURE(status)) {
412 return_ACPI_STATUS(status); 440 return_ACPI_STATUS(status);
413 } 441 }
@@ -429,13 +457,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
429 457
430 ACPI_FLUSH_CPU_CACHE(); 458 ACPI_FLUSH_CPU_CACHE();
431 459
432 status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, 460 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
433 (u32) acpi_gbl_FADT->S4bios_req, 8); 461 (u32) acpi_gbl_FADT.S4bios_request, 8);
434 462
435 do { 463 do {
436 acpi_os_stall(1000); 464 acpi_os_stall(1000);
437 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value, 465 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
438 ACPI_MTX_DO_NOT_LOCK);
439 if (ACPI_FAILURE(status)) { 466 if (ACPI_FAILURE(status)) {
440 return_ACPI_STATUS(status); 467 return_ACPI_STATUS(status);
441 } 468 }
@@ -568,13 +595,11 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
568 595
569 (void) 596 (void)
570 acpi_set_register(acpi_gbl_fixed_event_info 597 acpi_set_register(acpi_gbl_fixed_event_info
571 [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, 598 [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
572 ACPI_MTX_DO_NOT_LOCK);
573 599
574 (void) 600 (void)
575 acpi_set_register(acpi_gbl_fixed_event_info 601 acpi_set_register(acpi_gbl_fixed_event_info
576 [ACPI_EVENT_POWER_BUTTON].status_register_id, 1, 602 [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
577 ACPI_MTX_DO_NOT_LOCK);
578 603
579 arg.integer.value = ACPI_SST_WORKING; 604 arg.integer.value = ACPI_SST_WORKING;
580 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); 605 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index c4ec47c939fd..c32eab696acd 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution)
66 return_ACPI_STATUS(AE_BAD_PARAMETER); 66 return_ACPI_STATUS(AE_BAD_PARAMETER);
67 } 67 }
68 68
69 if (acpi_gbl_FADT->tmr_val_ext == 0) { 69 if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
70 *resolution = 24; 70 *resolution = 24;
71 } else { 71 } else {
72 *resolution = 32; 72 *resolution = 32;
@@ -98,7 +98,8 @@ acpi_status acpi_get_timer(u32 * ticks)
98 return_ACPI_STATUS(AE_BAD_PARAMETER); 98 return_ACPI_STATUS(AE_BAD_PARAMETER);
99 } 99 }
100 100
101 status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); 101 status =
102 acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block);
102 103
103 return_ACPI_STATUS(status); 104 return_ACPI_STATUS(status);
104} 105}
@@ -153,7 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
153 if (start_ticks < end_ticks) { 154 if (start_ticks < end_ticks) {
154 delta_ticks = end_ticks - start_ticks; 155 delta_ticks = end_ticks - start_ticks;
155 } else if (start_ticks > end_ticks) { 156 } else if (start_ticks > end_ticks) {
156 if (acpi_gbl_FADT->tmr_val_ext == 0) { 157 if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
157 158
158 /* 24-bit Timer */ 159 /* 24-bit Timer */
159 160
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
deleted file mode 100644
index 2e17ec75af03..000000000000
--- a/drivers/acpi/motherboard.c
+++ /dev/null
@@ -1,191 +0,0 @@
1/*
2 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or (at
6 * your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 */
19
20/* Purpose: Prevent PCMCIA cards from using motherboard resources. */
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/ioport.h>
27#include <asm/io.h>
28
29#include <acpi/acpi_bus.h>
30#include <acpi/acpi_drivers.h>
31
32#define _COMPONENT ACPI_SYSTEM_COMPONENT
33ACPI_MODULE_NAME("acpi_motherboard")
34
35/* Dell use PNP0C01 instead of PNP0C02 */
36#define ACPI_MB_HID1 "PNP0C01"
37#define ACPI_MB_HID2 "PNP0C02"
38/**
39 * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
40 * Doesn't care about the failure of 'request_region', since other may reserve
41 * the io ports as well
42 */
43#define IS_RESERVED_ADDR(base, len) \
44 (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
45 && ((base) + (len) > PCIBIOS_MIN_IO))
46/*
47 * Clearing the flag (IORESOURCE_BUSY) allows drivers to use
48 * the io ports if they really know they can use it, while
49 * still preventing hotplug PCI devices from using it.
50 */
51
52/*
53 * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
54 * and PNP0C02, redundant with acpi_reserve_io_ranges().
55 * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
56 */
57static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
58{
59 struct resource *requested_res = NULL;
60
61
62 if (res->type == ACPI_RESOURCE_TYPE_IO) {
63 struct acpi_resource_io *io_res = &res->data.io;
64
65 if (io_res->minimum != io_res->maximum)
66 return AE_OK;
67 if (IS_RESERVED_ADDR
68 (io_res->minimum, io_res->address_length)) {
69 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
70 "Motherboard resources 0x%08x - 0x%08x\n",
71 io_res->minimum,
72 io_res->minimum +
73 io_res->address_length));
74 requested_res =
75 request_region(io_res->minimum,
76 io_res->address_length, "motherboard");
77 }
78 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) {
79 struct acpi_resource_fixed_io *fixed_io_res =
80 &res->data.fixed_io;
81
82 if (IS_RESERVED_ADDR
83 (fixed_io_res->address, fixed_io_res->address_length)) {
84 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
85 "Motherboard resources 0x%08x - 0x%08x\n",
86 fixed_io_res->address,
87 fixed_io_res->address +
88 fixed_io_res->address_length));
89 requested_res =
90 request_region(fixed_io_res->address,
91 fixed_io_res->address_length,
92 "motherboard");
93 }
94 } else {
95 /* Memory mapped IO? */
96 }
97
98 if (requested_res)
99 requested_res->flags &= ~IORESOURCE_BUSY;
100 return AE_OK;
101}
102
103static int acpi_motherboard_add(struct acpi_device *device)
104{
105 if (!device)
106 return -EINVAL;
107 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
108 acpi_reserve_io_ranges, NULL);
109
110 return 0;
111}
112
113static struct acpi_driver acpi_motherboard_driver1 = {
114 .name = "motherboard",
115 .class = "",
116 .ids = ACPI_MB_HID1,
117 .ops = {
118 .add = acpi_motherboard_add,
119 },
120};
121
122static struct acpi_driver acpi_motherboard_driver2 = {
123 .name = "motherboard",
124 .class = "",
125 .ids = ACPI_MB_HID2,
126 .ops = {
127 .add = acpi_motherboard_add,
128 },
129};
130
131static void __init acpi_request_region (struct acpi_generic_address *addr,
132 unsigned int length, char *desc)
133{
134 if (!addr->address || !length)
135 return;
136
137 if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO)
138 request_region(addr->address, length, desc);
139 else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
140 request_mem_region(addr->address, length, desc);
141}
142
143static void __init acpi_reserve_resources(void)
144{
145 acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk,
146 acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK");
147
148 acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk,
149 acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK");
150
151 acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk,
152 acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK");
153
154 acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk,
155 acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK");
156
157 if (acpi_gbl_FADT->pm_tm_len == 4)
158 acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR");
159
160 acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk,
161 acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK");
162
163 /* Length of GPE blocks must be a non-negative multiple of 2 */
164
165 if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1))
166 acpi_request_region(&acpi_gbl_FADT->xgpe0_blk,
167 acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK");
168
169 if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1))
170 acpi_request_region(&acpi_gbl_FADT->xgpe1_blk,
171 acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK");
172}
173
174static int __init acpi_motherboard_init(void)
175{
176 acpi_bus_register_driver(&acpi_motherboard_driver1);
177 acpi_bus_register_driver(&acpi_motherboard_driver2);
178 /*
179 * Guarantee motherboard IO reservation first
180 * This module must run after scan.c
181 */
182 if (!acpi_disabled)
183 acpi_reserve_resources();
184 return 0;
185}
186
187/**
188 * Reserve motherboard resources after PCI claim BARs,
189 * but before PCI assign resources for uninitialized PCI devices
190 */
191fs_initcall(acpi_motherboard_init);
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index c1c6c236df9a..57faf598bad8 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -195,31 +195,27 @@ acpi_status acpi_ns_root_initialize(void)
195 obj_desc->mutex.sync_level = 195 obj_desc->mutex.sync_level =
196 (u8) (ACPI_TO_INTEGER(val) - 1); 196 (u8) (ACPI_TO_INTEGER(val) - 1);
197 197
198 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { 198 /* Create a mutex */
199 199
200 /* Create a counting semaphore for the global lock */ 200 status =
201 acpi_os_create_mutex(&obj_desc->mutex.
202 os_mutex);
203 if (ACPI_FAILURE(status)) {
204 acpi_ut_remove_reference(obj_desc);
205 goto unlock_and_exit;
206 }
201 207
202 status = 208 /* Special case for ACPI Global Lock */
203 acpi_os_create_semaphore
204 (ACPI_NO_UNIT_LIMIT, 1,
205 &acpi_gbl_global_lock_semaphore);
206 if (ACPI_FAILURE(status)) {
207 acpi_ut_remove_reference
208 (obj_desc);
209 goto unlock_and_exit;
210 }
211 209
212 /* Mark this mutex as very special */ 210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
211 acpi_gbl_global_lock_mutex =
212 obj_desc->mutex.os_mutex;
213 213
214 obj_desc->mutex.os_mutex = 214 /* Create additional counting semaphore for global lock */
215 ACPI_GLOBAL_LOCK;
216 } else {
217 /* Create a mutex */
218 215
219 status = 216 status =
220 acpi_os_create_mutex(&obj_desc-> 217 acpi_os_create_semaphore(1, 0,
221 mutex. 218 &acpi_gbl_global_lock_semaphore);
222 os_mutex);
223 if (ACPI_FAILURE(status)) { 219 if (ACPI_FAILURE(status)) {
224 acpi_ut_remove_reference 220 acpi_ut_remove_reference
225 (obj_desc); 221 (obj_desc);
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 55b407aae266..1d693d8ad2d8 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -61,6 +61,9 @@ ACPI_MODULE_NAME("nsalloc")
61struct acpi_namespace_node *acpi_ns_create_node(u32 name) 61struct acpi_namespace_node *acpi_ns_create_node(u32 name)
62{ 62{
63 struct acpi_namespace_node *node; 63 struct acpi_namespace_node *node;
64#ifdef ACPI_DBG_TRACK_ALLOCATIONS
65 u32 temp;
66#endif
64 67
65 ACPI_FUNCTION_TRACE(ns_create_node); 68 ACPI_FUNCTION_TRACE(ns_create_node);
66 69
@@ -71,6 +74,15 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
71 74
72 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); 75 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
73 76
77#ifdef ACPI_DBG_TRACK_ALLOCATIONS
78 temp =
79 acpi_gbl_ns_node_list->total_allocated -
80 acpi_gbl_ns_node_list->total_freed;
81 if (temp > acpi_gbl_ns_node_list->max_occupied) {
82 acpi_gbl_ns_node_list->max_occupied = temp;
83 }
84#endif
85
74 node->name.integer = name; 86 node->name.integer = name;
75 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); 87 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
76 return_PTR(node); 88 return_PTR(node);
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index d72df66aa965..1fc4f86676e1 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -205,7 +205,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
205 205
206 if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { 206 if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
207 this_node->name.integer = 207 this_node->name.integer =
208 acpi_ut_repair_name(this_node->name.integer); 208 acpi_ut_repair_name(this_node->name.ascii);
209 209
210 ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", 210 ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
211 this_node->name.integer)); 211 this_node->name.integer));
@@ -226,6 +226,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
226 obj_desc = acpi_ns_get_attached_object(this_node); 226 obj_desc = acpi_ns_get_attached_object(this_node);
227 acpi_dbg_level = dbg_level; 227 acpi_dbg_level = dbg_level;
228 228
229 /* Temp nodes are those nodes created by a control method */
230
231 if (this_node->flags & ANOBJ_TEMPORARY) {
232 acpi_os_printf("(T) ");
233 }
234
229 switch (info->display_type & ACPI_DISPLAY_MASK) { 235 switch (info->display_type & ACPI_DISPLAY_MASK) {
230 case ACPI_DISPLAY_SUMMARY: 236 case ACPI_DISPLAY_SUMMARY:
231 237
@@ -623,7 +629,8 @@ acpi_ns_dump_objects(acpi_object_type type,
623 info.display_type = display_type; 629 info.display_type = display_type;
624 630
625 (void)acpi_ns_walk_namespace(type, start_handle, max_depth, 631 (void)acpi_ns_walk_namespace(type, start_handle, max_depth,
626 ACPI_NS_WALK_NO_UNLOCK, 632 ACPI_NS_WALK_NO_UNLOCK |
633 ACPI_NS_WALK_TEMP_NODES,
627 acpi_ns_dump_one_object, (void *)&info, 634 acpi_ns_dump_one_object, (void *)&info,
628 NULL); 635 NULL);
629} 636}
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index c6bf5d30fca3..5097e167939e 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 4b0a4a8c9843..aa6370c67ec1 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -154,11 +154,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
154 * Execute the method via the interpreter. The interpreter is locked 154 * Execute the method via the interpreter. The interpreter is locked
155 * here before calling into the AML parser 155 * here before calling into the AML parser
156 */ 156 */
157 status = acpi_ex_enter_interpreter(); 157 acpi_ex_enter_interpreter();
158 if (ACPI_FAILURE(status)) {
159 return_ACPI_STATUS(status);
160 }
161
162 status = acpi_ps_execute_method(info); 158 status = acpi_ps_execute_method(info);
163 acpi_ex_exit_interpreter(); 159 acpi_ex_exit_interpreter();
164 } else { 160 } else {
@@ -182,10 +178,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
182 * resolution, we must lock it because we could access an opregion. 178 * resolution, we must lock it because we could access an opregion.
183 * The opregion access code assumes that the interpreter is locked. 179 * The opregion access code assumes that the interpreter is locked.
184 */ 180 */
185 status = acpi_ex_enter_interpreter(); 181 acpi_ex_enter_interpreter();
186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
188 }
189 182
190 /* Function has a strange interface */ 183 /* Function has a strange interface */
191 184
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index aec8488c0019..326af8fc0ce7 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -213,7 +213,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
213 u32 level, void *context, void **return_value) 213 u32 level, void *context, void **return_value)
214{ 214{
215 acpi_object_type type; 215 acpi_object_type type;
216 acpi_status status; 216 acpi_status status = AE_OK;
217 struct acpi_init_walk_info *info = 217 struct acpi_init_walk_info *info =
218 (struct acpi_init_walk_info *)context; 218 (struct acpi_init_walk_info *)context;
219 struct acpi_namespace_node *node = 219 struct acpi_namespace_node *node =
@@ -267,10 +267,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
267 /* 267 /*
268 * Must lock the interpreter before executing AML code 268 * Must lock the interpreter before executing AML code
269 */ 269 */
270 status = acpi_ex_enter_interpreter(); 270 acpi_ex_enter_interpreter();
271 if (ACPI_FAILURE(status)) {
272 return (status);
273 }
274 271
275 /* 272 /*
276 * Each of these types can contain executable AML code within the 273 * Each of these types can contain executable AML code within the
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index fe75d888e183..d4f9654fd20f 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -44,13 +44,12 @@
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acnamesp.h> 45#include <acpi/acnamesp.h>
46#include <acpi/acdispat.h> 46#include <acpi/acdispat.h>
47#include <acpi/actables.h>
47 48
48#define _COMPONENT ACPI_NAMESPACE 49#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nsload") 50ACPI_MODULE_NAME("nsload")
50 51
51/* Local prototypes */ 52/* Local prototypes */
52static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type);
53
54#ifdef ACPI_FUTURE_IMPLEMENTATION 53#ifdef ACPI_FUTURE_IMPLEMENTATION
55acpi_status acpi_ns_unload_namespace(acpi_handle handle); 54acpi_status acpi_ns_unload_namespace(acpi_handle handle);
56 55
@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
62 * 61 *
63 * FUNCTION: acpi_ns_load_table 62 * FUNCTION: acpi_ns_load_table
64 * 63 *
65 * PARAMETERS: table_desc - Descriptor for table to be loaded 64 * PARAMETERS: table_index - Index for table to be loaded
66 * Node - Owning NS node 65 * Node - Owning NS node
67 * 66 *
68 * RETURN: Status 67 * RETURN: Status
@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
72 ******************************************************************************/ 71 ******************************************************************************/
73 72
74acpi_status 73acpi_status
75acpi_ns_load_table(struct acpi_table_desc *table_desc, 74acpi_ns_load_table(acpi_native_uint table_index,
76 struct acpi_namespace_node *node) 75 struct acpi_namespace_node *node)
77{ 76{
78 acpi_status status; 77 acpi_status status;
79 78
80 ACPI_FUNCTION_TRACE(ns_load_table); 79 ACPI_FUNCTION_TRACE(ns_load_table);
81 80
82 /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
83
84 if (!
85 (acpi_gbl_table_data[table_desc->type].
86 flags & ACPI_TABLE_EXECUTABLE)) {
87
88 /* Just ignore this table */
89
90 return_ACPI_STATUS(AE_OK);
91 }
92
93 /* Check validity of the AML start and length */
94
95 if (!table_desc->aml_start) {
96 ACPI_ERROR((AE_INFO, "Null AML pointer"));
97 return_ACPI_STATUS(AE_BAD_PARAMETER);
98 }
99
100 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n",
101 table_desc->aml_start));
102
103 /* Ignore table if there is no AML contained within */
104
105 if (!table_desc->aml_length) {
106 ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]",
107 table_desc->pointer->signature));
108 return_ACPI_STATUS(AE_OK);
109 }
110
111 /* 81 /*
112 * Parse the table and load the namespace with all named 82 * Parse the table and load the namespace with all named
113 * objects found within. Control methods are NOT parsed 83 * objects found within. Control methods are NOT parsed
@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
117 * to another control method, we can't continue parsing 87 * to another control method, we can't continue parsing
118 * because we don't know how many arguments to parse next! 88 * because we don't know how many arguments to parse next!
119 */ 89 */
90 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
91 if (ACPI_FAILURE(status)) {
92 return_ACPI_STATUS(status);
93 }
94
95 /* If table already loaded into namespace, just return */
96
97 if (acpi_tb_is_table_loaded(table_index)) {
98 status = AE_ALREADY_EXISTS;
99 goto unlock;
100 }
101
120 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 102 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
121 "**** Loading table into namespace ****\n")); 103 "**** Loading table into namespace ****\n"));
122 104
123 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 105 status = acpi_tb_allocate_owner_id(table_index);
124 if (ACPI_FAILURE(status)) { 106 if (ACPI_FAILURE(status)) {
125 return_ACPI_STATUS(status); 107 goto unlock;
108 }
109
110 status = acpi_ns_parse_table(table_index, node->child);
111 if (ACPI_SUCCESS(status)) {
112 acpi_tb_set_table_loaded_flag(table_index, TRUE);
113 } else {
114 acpi_tb_release_owner_id(table_index);
126 } 115 }
127 116
128 status = acpi_ns_parse_table(table_desc, node->child); 117 unlock:
129 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 118 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
130 119
131 if (ACPI_FAILURE(status)) { 120 if (ACPI_FAILURE(status)) {
@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
141 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 130 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
142 "**** Begin Table Method Parsing and Object Initialization ****\n")); 131 "**** Begin Table Method Parsing and Object Initialization ****\n"));
143 132
144 status = acpi_ds_initialize_objects(table_desc, node); 133 status = acpi_ds_initialize_objects(table_index, node);
145 134
146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 135 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
147 "**** Completed Table Method Parsing and Object Initialization ****\n")); 136 "**** Completed Table Method Parsing and Object Initialization ****\n"));
@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
149 return_ACPI_STATUS(status); 138 return_ACPI_STATUS(status);
150} 139}
151 140
152/******************************************************************************* 141#ifdef ACPI_OBSOLETE_FUNCTIONS
153 *
154 * FUNCTION: acpi_ns_load_table_by_type
155 *
156 * PARAMETERS: table_type - Id of the table type to load
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables
161 * of the given type are loaded. The mechanism allows this
162 * routine to be called repeatedly.
163 *
164 ******************************************************************************/
165
166static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type)
167{
168 u32 i;
169 acpi_status status;
170 struct acpi_table_desc *table_desc;
171
172 ACPI_FUNCTION_TRACE(ns_load_table_by_type);
173
174 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
175 if (ACPI_FAILURE(status)) {
176 return_ACPI_STATUS(status);
177 }
178
179 /*
180 * Table types supported are:
181 * DSDT (one), SSDT/PSDT (multiple)
182 */
183 switch (table_type) {
184 case ACPI_TABLE_ID_DSDT:
185
186 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n"));
187
188 table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next;
189
190 /* If table already loaded into namespace, just return */
191
192 if (table_desc->loaded_into_namespace) {
193 goto unlock_and_exit;
194 }
195
196 /* Now load the single DSDT */
197
198 status = acpi_ns_load_table(table_desc, acpi_gbl_root_node);
199 if (ACPI_SUCCESS(status)) {
200 table_desc->loaded_into_namespace = TRUE;
201 }
202 break;
203
204 case ACPI_TABLE_ID_SSDT:
205 case ACPI_TABLE_ID_PSDT:
206
207 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
208 "Namespace load: %d SSDT or PSDTs\n",
209 acpi_gbl_table_lists[table_type].count));
210
211 /*
212 * Traverse list of SSDT or PSDT tables
213 */
214 table_desc = acpi_gbl_table_lists[table_type].next;
215 for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) {
216 /*
217 * Only attempt to load table into namespace if it is not
218 * already loaded!
219 */
220 if (!table_desc->loaded_into_namespace) {
221 status =
222 acpi_ns_load_table(table_desc,
223 acpi_gbl_root_node);
224 if (ACPI_FAILURE(status)) {
225 break;
226 }
227
228 table_desc->loaded_into_namespace = TRUE;
229 }
230
231 table_desc = table_desc->next;
232 }
233 break;
234
235 default:
236 status = AE_SUPPORT;
237 break;
238 }
239
240 unlock_and_exit:
241 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
242 return_ACPI_STATUS(status);
243}
244
245/******************************************************************************* 142/*******************************************************************************
246 * 143 *
247 * FUNCTION: acpi_load_namespace 144 * FUNCTION: acpi_load_namespace
@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void)
288 185
289 return_ACPI_STATUS(status); 186 return_ACPI_STATUS(status);
290} 187}
188#endif
291 189
292#ifdef ACPI_FUTURE_IMPLEMENTATION 190#ifdef ACPI_FUTURE_IMPLEMENTATION
293/******************************************************************************* 191/*******************************************************************************
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index 97b8332c9746..cbd94af08cc5 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index aabe8794b908..d9d7377bc6e6 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index 155505a4ef69..e696aa847990 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
45#include <acpi/acnamesp.h> 45#include <acpi/acnamesp.h>
46#include <acpi/acparser.h> 46#include <acpi/acparser.h>
47#include <acpi/acdispat.h> 47#include <acpi/acdispat.h>
48#include <acpi/actables.h>
48 49
49#define _COMPONENT ACPI_NAMESPACE 50#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsparse") 51ACPI_MODULE_NAME("nsparse")
@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse")
62 * 63 *
63 ******************************************************************************/ 64 ******************************************************************************/
64acpi_status 65acpi_status
65acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) 66acpi_ns_one_complete_parse(acpi_native_uint pass_number,
67 acpi_native_uint table_index)
66{ 68{
67 union acpi_parse_object *parse_root; 69 union acpi_parse_object *parse_root;
68 acpi_status status; 70 acpi_status status;
71 acpi_native_uint aml_length;
72 u8 *aml_start;
69 struct acpi_walk_state *walk_state; 73 struct acpi_walk_state *walk_state;
74 struct acpi_table_header *table;
75 acpi_owner_id owner_id;
70 76
71 ACPI_FUNCTION_TRACE(ns_one_complete_parse); 77 ACPI_FUNCTION_TRACE(ns_one_complete_parse);
72 78
79 status = acpi_tb_get_owner_id(table_index, &owner_id);
80 if (ACPI_FAILURE(status)) {
81 return_ACPI_STATUS(status);
82 }
83
73 /* Create and init a Root Node */ 84 /* Create and init a Root Node */
74 85
75 parse_root = acpi_ps_create_scope_op(); 86 parse_root = acpi_ps_create_scope_op();
@@ -79,26 +90,41 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
79 90
80 /* Create and initialize a new walk state */ 91 /* Create and initialize a new walk state */
81 92
82 walk_state = acpi_ds_create_walk_state(table_desc->owner_id, 93 walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
83 NULL, NULL, NULL);
84 if (!walk_state) { 94 if (!walk_state) {
85 acpi_ps_free_op(parse_root); 95 acpi_ps_free_op(parse_root);
86 return_ACPI_STATUS(AE_NO_MEMORY); 96 return_ACPI_STATUS(AE_NO_MEMORY);
87 } 97 }
88 98
89 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, 99 status = acpi_get_table_by_index(table_index, &table);
90 table_desc->aml_start, 100 if (ACPI_FAILURE(status)) {
91 table_desc->aml_length, NULL, 101 acpi_ds_delete_walk_state(walk_state);
92 pass_number); 102 acpi_ps_free_op(parse_root);
103 return_ACPI_STATUS(status);
104 }
105
106 /* Table must consist of at least a complete header */
107
108 if (table->length < sizeof(struct acpi_table_header)) {
109 status = AE_BAD_HEADER;
110 } else {
111 aml_start = (u8 *) table + sizeof(struct acpi_table_header);
112 aml_length = table->length - sizeof(struct acpi_table_header);
113 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
114 aml_start, aml_length, NULL,
115 (u8) pass_number);
116 }
117
93 if (ACPI_FAILURE(status)) { 118 if (ACPI_FAILURE(status)) {
94 acpi_ds_delete_walk_state(walk_state); 119 acpi_ds_delete_walk_state(walk_state);
120 acpi_ps_delete_parse_tree(parse_root);
95 return_ACPI_STATUS(status); 121 return_ACPI_STATUS(status);
96 } 122 }
97 123
98 /* Parse the AML */ 124 /* Parse the AML */
99 125
100 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", 126 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n",
101 pass_number)); 127 (unsigned)pass_number));
102 status = acpi_ps_parse_aml(walk_state); 128 status = acpi_ps_parse_aml(walk_state);
103 129
104 acpi_ps_delete_parse_tree(parse_root); 130 acpi_ps_delete_parse_tree(parse_root);
@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
119 ******************************************************************************/ 145 ******************************************************************************/
120 146
121acpi_status 147acpi_status
122acpi_ns_parse_table(struct acpi_table_desc *table_desc, 148acpi_ns_parse_table(acpi_native_uint table_index,
123 struct acpi_namespace_node *start_node) 149 struct acpi_namespace_node *start_node)
124{ 150{
125 acpi_status status; 151 acpi_status status;
@@ -134,10 +160,10 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
134 * each Parser Op subtree is deleted when it is finished. This saves 160 * each Parser Op subtree is deleted when it is finished. This saves
135 * a great deal of memory, and allows a small cache of parse objects 161 * a great deal of memory, and allows a small cache of parse objects
136 * to service the entire parse. The second pass of the parse then 162 * to service the entire parse. The second pass of the parse then
137 * performs another complete parse of the AML.. 163 * performs another complete parse of the AML.
138 */ 164 */
139 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); 165 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
140 status = acpi_ns_one_complete_parse(1, table_desc); 166 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index);
141 if (ACPI_FAILURE(status)) { 167 if (ACPI_FAILURE(status)) {
142 return_ACPI_STATUS(status); 168 return_ACPI_STATUS(status);
143 } 169 }
@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
152 * parse objects are all cached. 178 * parse objects are all cached.
153 */ 179 */
154 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); 180 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
155 status = acpi_ns_one_complete_parse(2, table_desc); 181 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index);
156 if (ACPI_FAILURE(status)) { 182 if (ACPI_FAILURE(status)) {
157 return_ACPI_STATUS(status); 183 return_ACPI_STATUS(status);
158 } 184 }
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 500e2bbcfaf7..e863be665ce8 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -321,7 +321,8 @@ acpi_ns_search_and_enter(u32 target_name,
321 * even though there are a few bad names. 321 * even though there are a few bad names.
322 */ 322 */
323 if (!acpi_ut_valid_acpi_name(target_name)) { 323 if (!acpi_ut_valid_acpi_name(target_name)) {
324 target_name = acpi_ut_repair_name(target_name); 324 target_name =
325 acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
325 326
326 /* Report warning only if in strict mode or debug mode */ 327 /* Report warning only if in strict mode or debug mode */
327 328
@@ -401,6 +402,10 @@ acpi_ns_search_and_enter(u32 target_name,
401 } 402 }
402#endif 403#endif
403 404
405 if (flags & ACPI_NS_TEMPORARY) {
406 new_node->flags |= ANOBJ_TEMPORARY;
407 }
408
404 /* Install the new object into the parent's list of children */ 409 /* Install the new object into the parent's list of children */
405 410
406 acpi_ns_install_node(walk_state, node, new_node, type); 411 acpi_ns_install_node(walk_state, node, new_node, type);
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index aa4e799d9a8c..90fd059615ff 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -770,13 +770,6 @@ void acpi_ns_terminate(void)
770 } 770 }
771 771
772 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); 772 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
773
774 /*
775 * 2) Now we can delete the ACPI tables
776 */
777 acpi_tb_delete_all_tables();
778 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
779
780 return_VOID; 773 return_VOID;
781} 774}
782 775
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index c8f6bef16ed0..94eb8f332d94 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -126,7 +126,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
126 * PARAMETERS: Type - acpi_object_type to search for 126 * PARAMETERS: Type - acpi_object_type to search for
127 * start_node - Handle in namespace where search begins 127 * start_node - Handle in namespace where search begins
128 * max_depth - Depth to which search is to reach 128 * max_depth - Depth to which search is to reach
129 * unlock_before_callback- Whether to unlock the NS before invoking 129 * Flags - Whether to unlock the NS before invoking
130 * the callback routine 130 * the callback routine
131 * user_function - Called when an object of "Type" is found 131 * user_function - Called when an object of "Type" is found
132 * Context - Passed to user function 132 * Context - Passed to user function
@@ -153,7 +153,7 @@ acpi_status
153acpi_ns_walk_namespace(acpi_object_type type, 153acpi_ns_walk_namespace(acpi_object_type type,
154 acpi_handle start_node, 154 acpi_handle start_node,
155 u32 max_depth, 155 u32 max_depth,
156 u8 unlock_before_callback, 156 u32 flags,
157 acpi_walk_callback user_function, 157 acpi_walk_callback user_function,
158 void *context, void **return_value) 158 void *context, void **return_value)
159{ 159{
@@ -193,20 +193,34 @@ acpi_ns_walk_namespace(acpi_object_type type,
193 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, 193 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
194 child_node); 194 child_node);
195 if (child_node) { 195 if (child_node) {
196 /* 196
197 * Found node, Get the type if we are not 197 /* Found next child, get the type if we are not searching for ANY */
198 * searching for ANY 198
199 */
200 if (type != ACPI_TYPE_ANY) { 199 if (type != ACPI_TYPE_ANY) {
201 child_type = child_node->type; 200 child_type = child_node->type;
202 } 201 }
203 202
204 if (child_type == type) { 203 /*
204 * Ignore all temporary namespace nodes (created during control
205 * method execution) unless told otherwise. These temporary nodes
206 * can cause a race condition because they can be deleted during the
207 * execution of the user function (if the namespace is unlocked before
208 * invocation of the user function.) Only the debugger namespace dump
209 * will examine the temporary nodes.
210 */
211 if ((child_node->flags & ANOBJ_TEMPORARY) &&
212 !(flags & ACPI_NS_WALK_TEMP_NODES)) {
213 status = AE_CTRL_DEPTH;
214 }
215
216 /* Type must match requested type */
217
218 else if (child_type == type) {
205 /* 219 /*
206 * Found a matching node, invoke the user 220 * Found a matching node, invoke the user callback function.
207 * callback function 221 * Unlock the namespace if flag is set.
208 */ 222 */
209 if (unlock_before_callback) { 223 if (flags & ACPI_NS_WALK_UNLOCK) {
210 mutex_status = 224 mutex_status =
211 acpi_ut_release_mutex 225 acpi_ut_release_mutex
212 (ACPI_MTX_NAMESPACE); 226 (ACPI_MTX_NAMESPACE);
@@ -216,10 +230,11 @@ acpi_ns_walk_namespace(acpi_object_type type,
216 } 230 }
217 } 231 }
218 232
219 status = user_function(child_node, level, 233 status =
220 context, return_value); 234 user_function(child_node, level, context,
235 return_value);
221 236
222 if (unlock_before_callback) { 237 if (flags & ACPI_NS_WALK_UNLOCK) {
223 mutex_status = 238 mutex_status =
224 acpi_ut_acquire_mutex 239 acpi_ut_acquire_mutex
225 (ACPI_MTX_NAMESPACE); 240 (ACPI_MTX_NAMESPACE);
@@ -251,20 +266,17 @@ acpi_ns_walk_namespace(acpi_object_type type,
251 } 266 }
252 267
253 /* 268 /*
254 * Depth first search: 269 * Depth first search: Attempt to go down another level in the
255 * Attempt to go down another level in the namespace 270 * namespace if we are allowed to. Don't go any further if we have
256 * if we are allowed to. Don't go any further if we 271 * reached the caller specified maximum depth or if the user
257 * have reached the caller specified maximum depth 272 * function has specified that the maximum depth has been reached.
258 * or if the user function has specified that the
259 * maximum depth has been reached.
260 */ 273 */
261 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { 274 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
262 if (acpi_ns_get_next_node 275 if (acpi_ns_get_next_node
263 (ACPI_TYPE_ANY, child_node, NULL)) { 276 (ACPI_TYPE_ANY, child_node, NULL)) {
264 /* 277
265 * There is at least one child of this 278 /* There is at least one child of this node, visit it */
266 * node, visit the onde 279
267 */
268 level++; 280 level++;
269 parent_node = child_node; 281 parent_node = child_node;
270 child_node = NULL; 282 child_node = NULL;
@@ -272,9 +284,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
272 } 284 }
273 } else { 285 } else {
274 /* 286 /*
275 * No more children of this node (acpi_ns_get_next_node 287 * No more children of this node (acpi_ns_get_next_node failed), go
276 * failed), go back upwards in the namespace tree to 288 * back upwards in the namespace tree to the node's parent.
277 * the node's parent.
278 */ 289 */
279 level--; 290 level--;
280 child_node = parent_node; 291 child_node = parent_node;
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index dca6799ac678..7ac6ace50059 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -170,7 +170,6 @@ acpi_evaluate_object(acpi_handle handle,
170 struct acpi_buffer *return_buffer) 170 struct acpi_buffer *return_buffer)
171{ 171{
172 acpi_status status; 172 acpi_status status;
173 acpi_status status2;
174 struct acpi_evaluate_info *info; 173 struct acpi_evaluate_info *info;
175 acpi_size buffer_space_needed; 174 acpi_size buffer_space_needed;
176 u32 i; 175 u32 i;
@@ -329,14 +328,12 @@ acpi_evaluate_object(acpi_handle handle,
329 * Delete the internal return object. NOTE: Interpreter must be 328 * Delete the internal return object. NOTE: Interpreter must be
330 * locked to avoid race condition. 329 * locked to avoid race condition.
331 */ 330 */
332 status2 = acpi_ex_enter_interpreter(); 331 acpi_ex_enter_interpreter();
333 if (ACPI_SUCCESS(status2)) {
334 332
335 /* Remove one reference on the return object (should delete it) */ 333 /* Remove one reference on the return object (should delete it) */
336 334
337 acpi_ut_remove_reference(info->return_object); 335 acpi_ut_remove_reference(info->return_object);
338 acpi_ex_exit_interpreter(); 336 acpi_ex_exit_interpreter();
339 }
340 } 337 }
341 338
342 cleanup: 339 cleanup:
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 978213a6c19f..b489781b22a8 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -84,38 +84,41 @@ acpi_get_handle(acpi_handle parent,
84 /* Convert a parent handle to a prefix node */ 84 /* Convert a parent handle to a prefix node */
85 85
86 if (parent) { 86 if (parent) {
87 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
88 if (ACPI_FAILURE(status)) {
89 return (status);
90 }
91
92 prefix_node = acpi_ns_map_handle_to_node(parent); 87 prefix_node = acpi_ns_map_handle_to_node(parent);
93 if (!prefix_node) { 88 if (!prefix_node) {
94 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
95 return (AE_BAD_PARAMETER); 89 return (AE_BAD_PARAMETER);
96 } 90 }
91 }
92
93 /*
94 * Valid cases are:
95 * 1) Fully qualified pathname
96 * 2) Parent + Relative pathname
97 *
98 * Error for <null Parent + relative path>
99 */
100 if (acpi_ns_valid_root_prefix(pathname[0])) {
97 101
98 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 102 /* Pathname is fully qualified (starts with '\') */
99 if (ACPI_FAILURE(status)) { 103
100 return (status); 104 /* Special case for root-only, since we can't search for it */
105
106 if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) {
107 *ret_handle =
108 acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
109 return (AE_OK);
101 } 110 }
102 } 111 } else if (!prefix_node) {
103 112
104 /* Special case for root, since we can't search for it */ 113 /* Relative path with null prefix is disallowed */
105 114
106 if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) { 115 return (AE_BAD_PARAMETER);
107 *ret_handle =
108 acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
109 return (AE_OK);
110 } 116 }
111 117
112 /* 118 /* Find the Node and convert to a handle */
113 * Find the Node and convert to a handle
114 */
115 status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH,
116 &node);
117 119
118 *ret_handle = NULL; 120 status =
121 acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
119 if (ACPI_SUCCESS(status)) { 122 if (ACPI_SUCCESS(status)) {
120 *ret_handle = acpi_ns_convert_entry_to_handle(node); 123 *ret_handle = acpi_ns_convert_entry_to_handle(node);
121 } 124 }
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index a18b1c223129..faa375887201 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index bd96a7045925..4a9faff4c01d 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -45,7 +45,7 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
45int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] 45int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
46 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; 46 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
47 47
48extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, 48extern int __init acpi_table_parse_madt_family(char *id,
49 unsigned long madt_size, 49 unsigned long madt_size,
50 int entry_id, 50 int entry_id,
51 acpi_madt_entry_handler handler, 51 acpi_madt_entry_handler handler,
@@ -89,7 +89,7 @@ void __cpuinit acpi_unmap_pxm_to_node(int node)
89 node_clear(node, nodes_found_map); 89 node_clear(node, nodes_found_map);
90} 90}
91 91
92void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) 92void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
93{ 93{
94 94
95 ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); 95 ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
@@ -99,36 +99,35 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
99 99
100 switch (header->type) { 100 switch (header->type) {
101 101
102 case ACPI_SRAT_PROCESSOR_AFFINITY: 102 case ACPI_SRAT_TYPE_CPU_AFFINITY:
103#ifdef ACPI_DEBUG_OUTPUT 103#ifdef ACPI_DEBUG_OUTPUT
104 { 104 {
105 struct acpi_table_processor_affinity *p = 105 struct acpi_srat_cpu_affinity *p =
106 (struct acpi_table_processor_affinity *)header; 106 (struct acpi_srat_cpu_affinity *)header;
107 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 107 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
108 "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", 108 "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
109 p->apic_id, p->lsapic_eid, 109 p->apic_id, p->local_sapic_eid,
110 p->proximity_domain, 110 p->proximity_domain_lo,
111 p->flags. 111 (p->flags & ACPI_SRAT_CPU_ENABLED)?
112 enabled ? "enabled" : "disabled")); 112 "enabled" : "disabled"));
113 } 113 }
114#endif /* ACPI_DEBUG_OUTPUT */ 114#endif /* ACPI_DEBUG_OUTPUT */
115 break; 115 break;
116 116
117 case ACPI_SRAT_MEMORY_AFFINITY: 117 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
118#ifdef ACPI_DEBUG_OUTPUT 118#ifdef ACPI_DEBUG_OUTPUT
119 { 119 {
120 struct acpi_table_memory_affinity *p = 120 struct acpi_srat_mem_affinity *p =
121 (struct acpi_table_memory_affinity *)header; 121 (struct acpi_srat_mem_affinity *)header;
122 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 122 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
123 "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n", 123 "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n",
124 p->base_addr_hi, p->base_addr_lo, 124 (unsigned long)p->base_address,
125 p->length_hi, p->length_lo, 125 (unsigned long)p->length,
126 p->memory_type, p->proximity_domain, 126 p->memory_type, p->proximity_domain,
127 p->flags. 127 (p->flags & ACPI_SRAT_MEM_ENABLED)?
128 enabled ? "enabled" : "disabled", 128 "enabled" : "disabled",
129 p->flags. 129 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
130 hot_pluggable ? " hot-pluggable" : 130 " hot-pluggable" : ""));
131 ""));
132 } 131 }
133#endif /* ACPI_DEBUG_OUTPUT */ 132#endif /* ACPI_DEBUG_OUTPUT */
134 break; 133 break;
@@ -141,18 +140,18 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
141 } 140 }
142} 141}
143 142
144static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size) 143static int __init acpi_parse_slit(struct acpi_table_header *table)
145{ 144{
146 struct acpi_table_slit *slit; 145 struct acpi_table_slit *slit;
147 u32 localities; 146 u32 localities;
148 147
149 if (!phys_addr || !size) 148 if (!table)
150 return -EINVAL; 149 return -EINVAL;
151 150
152 slit = (struct acpi_table_slit *)__va(phys_addr); 151 slit = (struct acpi_table_slit *)table;
153 152
154 /* downcast just for %llu vs %lu for i386/ia64 */ 153 /* downcast just for %llu vs %lu for i386/ia64 */
155 localities = (u32) slit->localities; 154 localities = (u32) slit->locality_count;
156 155
157 acpi_numa_slit_init(slit); 156 acpi_numa_slit_init(slit);
158 157
@@ -160,12 +159,12 @@ static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size)
160} 159}
161 160
162static int __init 161static int __init
163acpi_parse_processor_affinity(acpi_table_entry_header * header, 162acpi_parse_processor_affinity(struct acpi_subtable_header * header,
164 const unsigned long end) 163 const unsigned long end)
165{ 164{
166 struct acpi_table_processor_affinity *processor_affinity; 165 struct acpi_srat_cpu_affinity *processor_affinity;
167 166
168 processor_affinity = (struct acpi_table_processor_affinity *)header; 167 processor_affinity = (struct acpi_srat_cpu_affinity *)header;
169 if (!processor_affinity) 168 if (!processor_affinity)
170 return -EINVAL; 169 return -EINVAL;
171 170
@@ -178,12 +177,12 @@ acpi_parse_processor_affinity(acpi_table_entry_header * header,
178} 177}
179 178
180static int __init 179static int __init
181acpi_parse_memory_affinity(acpi_table_entry_header * header, 180acpi_parse_memory_affinity(struct acpi_subtable_header * header,
182 const unsigned long end) 181 const unsigned long end)
183{ 182{
184 struct acpi_table_memory_affinity *memory_affinity; 183 struct acpi_srat_mem_affinity *memory_affinity;
185 184
186 memory_affinity = (struct acpi_table_memory_affinity *)header; 185 memory_affinity = (struct acpi_srat_mem_affinity *)header;
187 if (!memory_affinity) 186 if (!memory_affinity)
188 return -EINVAL; 187 return -EINVAL;
189 188
@@ -195,23 +194,23 @@ acpi_parse_memory_affinity(acpi_table_entry_header * header,
195 return 0; 194 return 0;
196} 195}
197 196
198static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size) 197static int __init acpi_parse_srat(struct acpi_table_header *table)
199{ 198{
200 struct acpi_table_srat *srat; 199 struct acpi_table_srat *srat;
201 200
202 if (!phys_addr || !size) 201 if (!table)
203 return -EINVAL; 202 return -EINVAL;
204 203
205 srat = (struct acpi_table_srat *)__va(phys_addr); 204 srat = (struct acpi_table_srat *)table;
206 205
207 return 0; 206 return 0;
208} 207}
209 208
210int __init 209int __init
211acpi_table_parse_srat(enum acpi_srat_entry_id id, 210acpi_table_parse_srat(enum acpi_srat_type id,
212 acpi_madt_entry_handler handler, unsigned int max_entries) 211 acpi_madt_entry_handler handler, unsigned int max_entries)
213{ 212{
214 return acpi_table_parse_madt_family(ACPI_SRAT, 213 return acpi_table_parse_madt_family(ACPI_SIG_SRAT,
215 sizeof(struct acpi_table_srat), id, 214 sizeof(struct acpi_table_srat), id,
216 handler, max_entries); 215 handler, max_entries);
217} 216}
@@ -221,17 +220,17 @@ int __init acpi_numa_init(void)
221 int result; 220 int result;
222 221
223 /* SRAT: Static Resource Affinity Table */ 222 /* SRAT: Static Resource Affinity Table */
224 result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat); 223 result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat);
225 224
226 if (result > 0) { 225 if (result > 0) {
227 result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY, 226 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
228 acpi_parse_processor_affinity, 227 acpi_parse_processor_affinity,
229 NR_CPUS); 228 NR_CPUS);
230 result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific 229 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific
231 } 230 }
232 231
233 /* SLIT: System Locality Information Table */ 232 /* SLIT: System Locality Information Table */
234 result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit); 233 result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
235 234
236 acpi_numa_arch_fixup(); 235 acpi_numa_arch_fixup();
237 return 0; 236 return 0;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 57ae1e5cde0a..0f6f3bcbc8eb 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -36,6 +36,7 @@
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/nmi.h> 38#include <linux/nmi.h>
39#include <linux/acpi.h>
39#include <acpi/acpi.h> 40#include <acpi/acpi.h>
40#include <asm/io.h> 41#include <asm/io.h>
41#include <acpi/acpi_bus.h> 42#include <acpi/acpi_bus.h>
@@ -75,6 +76,54 @@ static acpi_osd_handler acpi_irq_handler;
75static void *acpi_irq_context; 76static void *acpi_irq_context;
76static struct workqueue_struct *kacpid_wq; 77static struct workqueue_struct *kacpid_wq;
77 78
79static void __init acpi_request_region (struct acpi_generic_address *addr,
80 unsigned int length, char *desc)
81{
82 struct resource *res;
83
84 if (!addr->address || !length)
85 return;
86
87 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
88 res = request_region(addr->address, length, desc);
89 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
90 res = request_mem_region(addr->address, length, desc);
91}
92
93static int __init acpi_reserve_resources(void)
94{
95 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
96 "ACPI PM1a_EVT_BLK");
97
98 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
99 "ACPI PM1b_EVT_BLK");
100
101 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
102 "ACPI PM1a_CNT_BLK");
103
104 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
105 "ACPI PM1b_CNT_BLK");
106
107 if (acpi_gbl_FADT.pm_timer_length == 4)
108 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
109
110 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
111 "ACPI PM2_CNT_BLK");
112
113 /* Length of GPE blocks must be a non-negative multiple of 2 */
114
115 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
116 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
117 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
118
119 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
120 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
121 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
122
123 return 0;
124}
125device_initcall(acpi_reserve_resources);
126
78acpi_status acpi_os_initialize(void) 127acpi_status acpi_os_initialize(void)
79{ 128{
80 return AE_OK; 129 return AE_OK;
@@ -136,53 +185,43 @@ void acpi_os_vprintf(const char *fmt, va_list args)
136#endif 185#endif
137} 186}
138 187
139acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) 188acpi_physical_address __init acpi_os_get_root_pointer(void)
140{ 189{
141 if (efi_enabled) { 190 if (efi_enabled) {
142 addr->pointer_type = ACPI_PHYSICAL_POINTER;
143 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) 191 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
144 addr->pointer.physical = efi.acpi20; 192 return efi.acpi20;
145 else if (efi.acpi != EFI_INVALID_TABLE_ADDR) 193 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
146 addr->pointer.physical = efi.acpi; 194 return efi.acpi;
147 else { 195 else {
148 printk(KERN_ERR PREFIX 196 printk(KERN_ERR PREFIX
149 "System description tables not found\n"); 197 "System description tables not found\n");
150 return AE_NOT_FOUND; 198 return 0;
151 } 199 }
152 } else { 200 } else
153 if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { 201 return acpi_find_rsdp();
154 printk(KERN_ERR PREFIX
155 "System description tables not found\n");
156 return AE_NOT_FOUND;
157 }
158 }
159
160 return AE_OK;
161} 202}
162 203
163acpi_status 204void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
164acpi_os_map_memory(acpi_physical_address phys, acpi_size size,
165 void __iomem ** virt)
166{ 205{
167 if (phys > ULONG_MAX) { 206 if (phys > ULONG_MAX) {
168 printk(KERN_ERR PREFIX "Cannot map memory that high\n"); 207 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
169 return AE_BAD_PARAMETER; 208 return 0;
170 } 209 }
171 /* 210 if (acpi_gbl_permanent_mmap)
172 * ioremap checks to ensure this is in reserved space 211 /*
173 */ 212 * ioremap checks to ensure this is in reserved space
174 *virt = ioremap((unsigned long)phys, size); 213 */
175 214 return ioremap((unsigned long)phys, size);
176 if (!*virt) 215 else
177 return AE_NO_MEMORY; 216 return __acpi_map_table((unsigned long)phys, size);
178
179 return AE_OK;
180} 217}
181EXPORT_SYMBOL_GPL(acpi_os_map_memory); 218EXPORT_SYMBOL_GPL(acpi_os_map_memory);
182 219
183void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) 220void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
184{ 221{
185 iounmap(virt); 222 if (acpi_gbl_permanent_mmap) {
223 iounmap(virt);
224 }
186} 225}
187EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 226EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
188 227
@@ -254,7 +293,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
254 * FADT. It may not be the same if an interrupt source override exists 293 * FADT. It may not be the same if an interrupt source override exists
255 * for the SCI. 294 * for the SCI.
256 */ 295 */
257 gsi = acpi_fadt.sci_int; 296 gsi = acpi_gbl_FADT.sci_interrupt;
258 if (acpi_gsi_to_irq(gsi, &irq) < 0) { 297 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
259 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", 298 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
260 gsi); 299 gsi);
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index bf88e076c3e9..c2b9835c890b 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index e1541db3753a..773aee82fbb8 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -42,12 +42,11 @@
42 */ 42 */
43 43
44/* 44/*
45 * Parse the AML and build an operation tree as most interpreters, 45 * Parse the AML and build an operation tree as most interpreters, (such as
46 * like Perl, do. Parsing is done by hand rather than with a YACC 46 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
47 * generated parser to tightly constrain stack and dynamic memory 47 * to tightly constrain stack and dynamic memory usage. Parsing is kept
48 * usage. At the same time, parsing is kept flexible and the code 48 * flexible and the code fairly compact by parsing based on a list of AML
49 * fairly compact by parsing based on a list of AML opcode 49 * opcode templates in aml_op_info[].
50 * templates in aml_op_info[]
51 */ 50 */
52 51
53#include <acpi/acpi.h> 52#include <acpi/acpi.h>
@@ -60,766 +59,679 @@ ACPI_MODULE_NAME("psloop")
60 59
61static u32 acpi_gbl_depth = 0; 60static u32 acpi_gbl_depth = 0;
62 61
62/* Local prototypes */
63
64static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
65
66static acpi_status
67acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
68 u8 * aml_op_start,
69 union acpi_parse_object *unnamed_op,
70 union acpi_parse_object **op);
71
72static acpi_status
73acpi_ps_create_op(struct acpi_walk_state *walk_state,
74 u8 * aml_op_start, union acpi_parse_object **new_op);
75
76static acpi_status
77acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
78 u8 * aml_op_start, union acpi_parse_object *op);
79
80static acpi_status
81acpi_ps_complete_op(struct acpi_walk_state *walk_state,
82 union acpi_parse_object **op, acpi_status status);
83
84static acpi_status
85acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
86 union acpi_parse_object *op, acpi_status status);
87
63/******************************************************************************* 88/*******************************************************************************
64 * 89 *
65 * FUNCTION: acpi_ps_parse_loop 90 * FUNCTION: acpi_ps_get_aml_opcode
66 * 91 *
67 * PARAMETERS: walk_state - Current state 92 * PARAMETERS: walk_state - Current state
68 * 93 *
69 * RETURN: Status 94 * RETURN: Status
70 * 95 *
71 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return 96 * DESCRIPTION: Extract the next AML opcode from the input stream.
72 * a tree of ops.
73 * 97 *
74 ******************************************************************************/ 98 ******************************************************************************/
75 99
76acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) 100static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
77{ 101{
78 acpi_status status = AE_OK;
79 acpi_status status2;
80 union acpi_parse_object *op = NULL; /* current op */
81 union acpi_parse_object *arg = NULL;
82 union acpi_parse_object *pre_op = NULL;
83 struct acpi_parse_state *parser_state;
84 u8 *aml_op_start = NULL;
85 102
86 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); 103 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
87 104
88 if (walk_state->descending_callback == NULL) { 105 walk_state->aml_offset =
89 return_ACPI_STATUS(AE_BAD_PARAMETER); 106 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
90 } 107 walk_state->parser_state.aml_start);
108 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
91 109
92 parser_state = &walk_state->parser_state; 110 /*
93 walk_state->arg_types = 0; 111 * First cut to determine what we have found:
112 * 1) A valid AML opcode
113 * 2) A name string
114 * 3) An unknown/invalid opcode
115 */
116 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
94 117
95#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 118 switch (walk_state->op_info->class) {
119 case AML_CLASS_ASCII:
120 case AML_CLASS_PREFIX:
121 /*
122 * Starts with a valid prefix or ASCII char, this is a name
123 * string. Convert the bare name string to a namepath.
124 */
125 walk_state->opcode = AML_INT_NAMEPATH_OP;
126 walk_state->arg_types = ARGP_NAMESTRING;
127 break;
96 128
97 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { 129 case AML_CLASS_UNKNOWN:
98 130
99 /* We are restarting a preempted control method */ 131 /* The opcode is unrecognized. Just skip unknown opcodes */
100 132
101 if (acpi_ps_has_completed_scope(parser_state)) { 133 ACPI_ERROR((AE_INFO,
102 /* 134 "Found unknown opcode %X at AML address %p offset %X, ignoring",
103 * We must check if a predicate to an IF or WHILE statement 135 walk_state->opcode, walk_state->parser_state.aml,
104 * was just completed 136 walk_state->aml_offset));
105 */
106 if ((parser_state->scope->parse_scope.op) &&
107 ((parser_state->scope->parse_scope.op->common.
108 aml_opcode == AML_IF_OP)
109 || (parser_state->scope->parse_scope.op->common.
110 aml_opcode == AML_WHILE_OP))
111 && (walk_state->control_state)
112 && (walk_state->control_state->common.state ==
113 ACPI_CONTROL_PREDICATE_EXECUTING)) {
114 /*
115 * A predicate was just completed, get the value of the
116 * predicate and branch based on that value
117 */
118 walk_state->op = NULL;
119 status =
120 acpi_ds_get_predicate_value(walk_state,
121 ACPI_TO_POINTER
122 (TRUE));
123 if (ACPI_FAILURE(status)
124 && ((status & AE_CODE_MASK) !=
125 AE_CODE_CONTROL)) {
126 if (status == AE_AML_NO_RETURN_VALUE) {
127 ACPI_EXCEPTION((AE_INFO, status,
128 "Invoked method did not return a value"));
129 137
130 } 138 ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
131 ACPI_EXCEPTION((AE_INFO, status,
132 "GetPredicate Failed"));
133 return_ACPI_STATUS(status);
134 }
135 139
136 status = 140 /* Assume one-byte bad opcode */
137 acpi_ps_next_parse_state(walk_state, op,
138 status);
139 }
140 141
141 acpi_ps_pop_scope(parser_state, &op, 142 walk_state->parser_state.aml++;
142 &walk_state->arg_types, 143 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
143 &walk_state->arg_count);
144 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
145 "Popped scope, Op=%p\n", op));
146 } else if (walk_state->prev_op) {
147 144
148 /* We were in the middle of an op */ 145 default:
149 146
150 op = walk_state->prev_op; 147 /* Found opcode info, this is a normal opcode */
151 walk_state->arg_types = walk_state->prev_arg_types; 148
152 } 149 walk_state->parser_state.aml +=
150 acpi_ps_get_opcode_size(walk_state->opcode);
151 walk_state->arg_types = walk_state->op_info->parse_args;
152 break;
153 } 153 }
154#endif
155 154
156 /* Iterative parsing loop, while there is more AML to process: */ 155 return_ACPI_STATUS(AE_OK);
156}
157 157
158 while ((parser_state->aml < parser_state->aml_end) || (op)) { 158/*******************************************************************************
159 aml_op_start = parser_state->aml; 159 *
160 if (!op) { 160 * FUNCTION: acpi_ps_build_named_op
161 *
162 * PARAMETERS: walk_state - Current state
163 * aml_op_start - Begin of named Op in AML
164 * unnamed_op - Early Op (not a named Op)
165 * Op - Returned Op
166 *
167 * RETURN: Status
168 *
169 * DESCRIPTION: Parse a named Op
170 *
171 ******************************************************************************/
161 172
162 /* Get the next opcode from the AML stream */ 173static acpi_status
174acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
175 u8 * aml_op_start,
176 union acpi_parse_object *unnamed_op,
177 union acpi_parse_object **op)
178{
179 acpi_status status = AE_OK;
180 union acpi_parse_object *arg = NULL;
163 181
164 walk_state->aml_offset = 182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
165 (u32) ACPI_PTR_DIFF(parser_state->aml,
166 parser_state->aml_start);
167 walk_state->opcode = acpi_ps_peek_opcode(parser_state);
168 183
169 /* 184 unnamed_op->common.value.arg = NULL;
170 * First cut to determine what we have found: 185 unnamed_op->common.aml_opcode = walk_state->opcode;
171 * 1) A valid AML opcode
172 * 2) A name string
173 * 3) An unknown/invalid opcode
174 */
175 walk_state->op_info =
176 acpi_ps_get_opcode_info(walk_state->opcode);
177 switch (walk_state->op_info->class) {
178 case AML_CLASS_ASCII:
179 case AML_CLASS_PREFIX:
180 /*
181 * Starts with a valid prefix or ASCII char, this is a name
182 * string. Convert the bare name string to a namepath.
183 */
184 walk_state->opcode = AML_INT_NAMEPATH_OP;
185 walk_state->arg_types = ARGP_NAMESTRING;
186 break;
187 186
188 case AML_CLASS_UNKNOWN: 187 /*
188 * Get and append arguments until we find the node that contains
189 * the name (the type ARGP_NAME).
190 */
191 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
192 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
193 status =
194 acpi_ps_get_next_arg(walk_state,
195 &(walk_state->parser_state),
196 GET_CURRENT_ARG_TYPE(walk_state->
197 arg_types), &arg);
198 if (ACPI_FAILURE(status)) {
199 return_ACPI_STATUS(status);
200 }
189 201
190 /* The opcode is unrecognized. Just skip unknown opcodes */ 202 acpi_ps_append_arg(unnamed_op, arg);
203 INCREMENT_ARG_LIST(walk_state->arg_types);
204 }
191 205
192 ACPI_ERROR((AE_INFO, 206 /*
193 "Found unknown opcode %X at AML address %p offset %X, ignoring", 207 * Make sure that we found a NAME and didn't run out of arguments
194 walk_state->opcode, 208 */
195 parser_state->aml, 209 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
196 walk_state->aml_offset)); 210 return_ACPI_STATUS(AE_AML_NO_OPERAND);
211 }
197 212
198 ACPI_DUMP_BUFFER(parser_state->aml, 128); 213 /* We know that this arg is a name, move to next arg */
199 214
200 /* Assume one-byte bad opcode */ 215 INCREMENT_ARG_LIST(walk_state->arg_types);
201 216
202 parser_state->aml++; 217 /*
203 continue; 218 * Find the object. This will either insert the object into
219 * the namespace or simply look it up
220 */
221 walk_state->op = NULL;
204 222
205 default: 223 status = walk_state->descending_callback(walk_state, op);
224 if (ACPI_FAILURE(status)) {
225 ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
226 return_ACPI_STATUS(status);
227 }
206 228
207 /* Found opcode info, this is a normal opcode */ 229 if (!*op) {
230 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
231 }
208 232
209 parser_state->aml += 233 status = acpi_ps_next_parse_state(walk_state, *op, status);
210 acpi_ps_get_opcode_size(walk_state->opcode); 234 if (ACPI_FAILURE(status)) {
211 walk_state->arg_types = 235 if (status == AE_CTRL_PENDING) {
212 walk_state->op_info->parse_args; 236 return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
213 break; 237 }
214 } 238 return_ACPI_STATUS(status);
239 }
215 240
216 /* Create Op structure and append to parent's argument list */ 241 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
242 acpi_gbl_depth++;
217 243
218 if (walk_state->op_info->flags & AML_NAMED) { 244 if ((*op)->common.aml_opcode == AML_REGION_OP) {
245 /*
246 * Defer final parsing of an operation_region body, because we don't
247 * have enough info in the first pass to parse it correctly (i.e.,
248 * there may be method calls within the term_arg elements of the body.)
249 *
250 * However, we must continue parsing because the opregion is not a
251 * standalone package -- we don't know where the end is at this point.
252 *
253 * (Length is unknown until parse of the body complete)
254 */
255 (*op)->named.data = aml_op_start;
256 (*op)->named.length = 0;
257 }
219 258
220 /* Allocate a new pre_op if necessary */ 259 return_ACPI_STATUS(AE_OK);
260}
221 261
222 if (!pre_op) { 262/*******************************************************************************
223 pre_op = 263 *
224 acpi_ps_alloc_op(walk_state-> 264 * FUNCTION: acpi_ps_create_op
225 opcode); 265 *
226 if (!pre_op) { 266 * PARAMETERS: walk_state - Current state
227 status = AE_NO_MEMORY; 267 * aml_op_start - Op start in AML
228 goto close_this_op; 268 * new_op - Returned Op
229 } 269 *
230 } 270 * RETURN: Status
271 *
272 * DESCRIPTION: Get Op from AML
273 *
274 ******************************************************************************/
231 275
232 pre_op->common.value.arg = NULL; 276static acpi_status
233 pre_op->common.aml_opcode = walk_state->opcode; 277acpi_ps_create_op(struct acpi_walk_state *walk_state,
278 u8 * aml_op_start, union acpi_parse_object **new_op)
279{
280 acpi_status status = AE_OK;
281 union acpi_parse_object *op;
282 union acpi_parse_object *named_op = NULL;
234 283
235 /* 284 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
236 * Get and append arguments until we find the node that contains
237 * the name (the type ARGP_NAME).
238 */
239 while (GET_CURRENT_ARG_TYPE
240 (walk_state->arg_types)
241 &&
242 (GET_CURRENT_ARG_TYPE
243 (walk_state->arg_types) != ARGP_NAME)) {
244 status =
245 acpi_ps_get_next_arg(walk_state,
246 parser_state,
247 GET_CURRENT_ARG_TYPE
248 (walk_state->
249 arg_types),
250 &arg);
251 if (ACPI_FAILURE(status)) {
252 goto close_this_op;
253 }
254 285
255 acpi_ps_append_arg(pre_op, arg); 286 status = acpi_ps_get_aml_opcode(walk_state);
256 INCREMENT_ARG_LIST(walk_state-> 287 if (status == AE_CTRL_PARSE_CONTINUE) {
257 arg_types); 288 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
258 } 289 }
259 290
260 /* 291 /* Create Op structure and append to parent's argument list */
261 * Make sure that we found a NAME and didn't run out of
262 * arguments
263 */
264 if (!GET_CURRENT_ARG_TYPE
265 (walk_state->arg_types)) {
266 status = AE_AML_NO_OPERAND;
267 goto close_this_op;
268 }
269 292
270 /* We know that this arg is a name, move to next arg */ 293 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
294 op = acpi_ps_alloc_op(walk_state->opcode);
295 if (!op) {
296 return_ACPI_STATUS(AE_NO_MEMORY);
297 }
271 298
272 INCREMENT_ARG_LIST(walk_state->arg_types); 299 if (walk_state->op_info->flags & AML_NAMED) {
300 status =
301 acpi_ps_build_named_op(walk_state, aml_op_start, op,
302 &named_op);
303 acpi_ps_free_op(op);
304 if (ACPI_FAILURE(status)) {
305 return_ACPI_STATUS(status);
306 }
273 307
274 /* 308 *new_op = named_op;
275 * Find the object. This will either insert the object into 309 return_ACPI_STATUS(AE_OK);
276 * the namespace or simply look it up 310 }
277 */
278 walk_state->op = NULL;
279 311
280 status = 312 /* Not a named opcode, just allocate Op and append to parent */
281 walk_state->descending_callback(walk_state,
282 &op);
283 if (ACPI_FAILURE(status)) {
284 ACPI_EXCEPTION((AE_INFO, status,
285 "During name lookup/catalog"));
286 goto close_this_op;
287 }
288 313
289 if (!op) { 314 if (walk_state->op_info->flags & AML_CREATE) {
290 continue; 315 /*
291 } 316 * Backup to beginning of create_xXXfield declaration
317 * body_length is unknown until we parse the body
318 */
319 op->named.data = aml_op_start;
320 op->named.length = 0;
321 }
292 322
293 status = 323 acpi_ps_append_arg(acpi_ps_get_parent_scope
294 acpi_ps_next_parse_state(walk_state, op, 324 (&(walk_state->parser_state)), op);
295 status);
296 if (status == AE_CTRL_PENDING) {
297 status = AE_OK;
298 goto close_this_op;
299 }
300 325
301 if (ACPI_FAILURE(status)) { 326 if (walk_state->descending_callback != NULL) {
302 goto close_this_op; 327 /*
303 } 328 * Find the object. This will either insert the object into
329 * the namespace or simply look it up
330 */
331 walk_state->op = *new_op = op;
304 332
305 acpi_ps_append_arg(op, 333 status = walk_state->descending_callback(walk_state, &op);
306 pre_op->common.value.arg); 334 status = acpi_ps_next_parse_state(walk_state, op, status);
307 acpi_gbl_depth++; 335 if (status == AE_CTRL_PENDING) {
308 336 status = AE_CTRL_PARSE_PENDING;
309 if (op->common.aml_opcode == AML_REGION_OP) { 337 }
310 /* 338 }
311 * Defer final parsing of an operation_region body,
312 * because we don't have enough info in the first pass
313 * to parse it correctly (i.e., there may be method
314 * calls within the term_arg elements of the body.)
315 *
316 * However, we must continue parsing because
317 * the opregion is not a standalone package --
318 * we don't know where the end is at this point.
319 *
320 * (Length is unknown until parse of the body complete)
321 */
322 op->named.data = aml_op_start;
323 op->named.length = 0;
324 }
325 } else {
326 /* Not a named opcode, just allocate Op and append to parent */
327 339
328 walk_state->op_info = 340 return_ACPI_STATUS(status);
329 acpi_ps_get_opcode_info(walk_state->opcode); 341}
330 op = acpi_ps_alloc_op(walk_state->opcode);
331 if (!op) {
332 status = AE_NO_MEMORY;
333 goto close_this_op;
334 }
335 342
336 if (walk_state->op_info->flags & AML_CREATE) { 343/*******************************************************************************
337 /* 344 *
338 * Backup to beginning of create_xXXfield declaration 345 * FUNCTION: acpi_ps_get_arguments
339 * body_length is unknown until we parse the body 346 *
340 */ 347 * PARAMETERS: walk_state - Current state
341 op->named.data = aml_op_start; 348 * aml_op_start - Op start in AML
342 op->named.length = 0; 349 * Op - Current Op
343 } 350 *
351 * RETURN: Status
352 *
353 * DESCRIPTION: Get arguments for passed Op.
354 *
355 ******************************************************************************/
344 356
345 acpi_ps_append_arg(acpi_ps_get_parent_scope 357static acpi_status
346 (parser_state), op); 358acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
359 u8 * aml_op_start, union acpi_parse_object *op)
360{
361 acpi_status status = AE_OK;
362 union acpi_parse_object *arg = NULL;
347 363
348 if ((walk_state->descending_callback != NULL)) { 364 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
349 /*
350 * Find the object. This will either insert the object into
351 * the namespace or simply look it up
352 */
353 walk_state->op = op;
354 365
355 status = 366 switch (op->common.aml_opcode) {
356 walk_state-> 367 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
357 descending_callback(walk_state, 368 case AML_WORD_OP: /* AML_WORDDATA_ARG */
358 &op); 369 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
359 status = 370 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
360 acpi_ps_next_parse_state(walk_state, 371 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
361 op,
362 status);
363 if (status == AE_CTRL_PENDING) {
364 status = AE_OK;
365 goto close_this_op;
366 }
367 372
368 if (ACPI_FAILURE(status)) { 373 /* Fill in constant or string argument directly */
369 goto close_this_op;
370 }
371 }
372 }
373 374
374 op->common.aml_offset = walk_state->aml_offset; 375 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
376 GET_CURRENT_ARG_TYPE(walk_state->
377 arg_types),
378 op);
379 break;
375 380
376 if (walk_state->op_info) { 381 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
377 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 382
378 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", 383 status =
379 (u32) op->common.aml_opcode, 384 acpi_ps_get_next_namepath(walk_state,
380 walk_state->op_info->name, op, 385 &(walk_state->parser_state), op,
381 parser_state->aml, 386 1);
382 op->common.aml_offset)); 387 if (ACPI_FAILURE(status)) {
383 } 388 return_ACPI_STATUS(status);
384 } 389 }
385 390
391 walk_state->arg_types = 0;
392 break;
393
394 default:
386 /* 395 /*
387 * Start arg_count at zero because we don't know if there are 396 * Op is not a constant or string, append each argument to the Op
388 * any args yet
389 */ 397 */
390 walk_state->arg_count = 0; 398 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
391 399 && !walk_state->arg_count) {
392 /* Are there any arguments that must be processed? */ 400 walk_state->aml_offset =
393 401 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
394 if (walk_state->arg_types) { 402 walk_state->parser_state.
395 403 aml_start);
396 /* Get arguments */
397
398 switch (op->common.aml_opcode) {
399 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
400 case AML_WORD_OP: /* AML_WORDDATA_ARG */
401 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
402 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
403 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
404
405 /* Fill in constant or string argument directly */
406
407 acpi_ps_get_next_simple_arg(parser_state,
408 GET_CURRENT_ARG_TYPE
409 (walk_state->
410 arg_types), op);
411 break;
412
413 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
414
415 status =
416 acpi_ps_get_next_namepath(walk_state,
417 parser_state, op,
418 1);
419 if (ACPI_FAILURE(status)) {
420 goto close_this_op;
421 }
422
423 walk_state->arg_types = 0;
424 break;
425 404
426 default: 405 status =
427 /* 406 acpi_ps_get_next_arg(walk_state,
428 * Op is not a constant or string, append each argument 407 &(walk_state->parser_state),
429 * to the Op 408 GET_CURRENT_ARG_TYPE
430 */ 409 (walk_state->arg_types), &arg);
431 while (GET_CURRENT_ARG_TYPE 410 if (ACPI_FAILURE(status)) {
432 (walk_state->arg_types) 411 return_ACPI_STATUS(status);
433 && !walk_state->arg_count) { 412 }
434 walk_state->aml_offset = (u32)
435 ACPI_PTR_DIFF(parser_state->aml,
436 parser_state->
437 aml_start);
438 413
439 status = 414 if (arg) {
440 acpi_ps_get_next_arg(walk_state, 415 arg->common.aml_offset = walk_state->aml_offset;
441 parser_state, 416 acpi_ps_append_arg(op, arg);
442 GET_CURRENT_ARG_TYPE 417 }
443 (walk_state->
444 arg_types),
445 &arg);
446 if (ACPI_FAILURE(status)) {
447 goto close_this_op;
448 }
449 418
450 if (arg) { 419 INCREMENT_ARG_LIST(walk_state->arg_types);
451 arg->common.aml_offset = 420 }
452 walk_state->aml_offset;
453 acpi_ps_append_arg(op, arg);
454 }
455 INCREMENT_ARG_LIST(walk_state->
456 arg_types);
457 }
458 421
459 /* Special processing for certain opcodes */ 422 /* Special processing for certain opcodes */
460 423
461 /* TBD (remove): Temporary mechanism to disable this code if needed */ 424 /* TBD (remove): Temporary mechanism to disable this code if needed */
462 425
463#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE 426#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
464 427
465 if ((walk_state->pass_number <= 428 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
466 ACPI_IMODE_LOAD_PASS1) 429 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
467 && 430 /*
468 ((walk_state-> 431 * We want to skip If/Else/While constructs during Pass1 because we
469 parse_flags & ACPI_PARSE_DISASSEMBLE) == 432 * want to actually conditionally execute the code during Pass2.
470 0)) { 433 *
471 /* 434 * Except for disassembly, where we always want to walk the
472 * We want to skip If/Else/While constructs during Pass1 435 * If/Else/While packages
473 * because we want to actually conditionally execute the 436 */
474 * code during Pass2. 437 switch (op->common.aml_opcode) {
475 * 438 case AML_IF_OP:
476 * Except for disassembly, where we always want to 439 case AML_ELSE_OP:
477 * walk the If/Else/While packages 440 case AML_WHILE_OP:
478 */
479 switch (op->common.aml_opcode) {
480 case AML_IF_OP:
481 case AML_ELSE_OP:
482 case AML_WHILE_OP:
483
484 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
485 "Pass1: Skipping an If/Else/While body\n"));
486
487 /* Skip body of if/else/while in pass 1 */
488
489 parser_state->aml =
490 parser_state->pkg_end;
491 walk_state->arg_count = 0;
492 break;
493
494 default:
495 break;
496 }
497 }
498#endif
499 switch (op->common.aml_opcode) {
500 case AML_METHOD_OP:
501
502 /*
503 * Skip parsing of control method
504 * because we don't have enough info in the first pass
505 * to parse it correctly.
506 *
507 * Save the length and address of the body
508 */
509 op->named.data = parser_state->aml;
510 op->named.length =
511 (u32) (parser_state->pkg_end -
512 parser_state->aml);
513
514 /* Skip body of method */
515
516 parser_state->aml =
517 parser_state->pkg_end;
518 walk_state->arg_count = 0;
519 break;
520
521 case AML_BUFFER_OP:
522 case AML_PACKAGE_OP:
523 case AML_VAR_PACKAGE_OP:
524
525 if ((op->common.parent) &&
526 (op->common.parent->common.
527 aml_opcode == AML_NAME_OP)
528 && (walk_state->pass_number <=
529 ACPI_IMODE_LOAD_PASS2)) {
530 /*
531 * Skip parsing of Buffers and Packages
532 * because we don't have enough info in the first pass
533 * to parse them correctly.
534 */
535 op->named.data = aml_op_start;
536 op->named.length =
537 (u32) (parser_state->
538 pkg_end -
539 aml_op_start);
540
541 /* Skip body */
542
543 parser_state->aml =
544 parser_state->pkg_end;
545 walk_state->arg_count = 0;
546 }
547 break;
548 441
549 case AML_WHILE_OP: 442 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
443 "Pass1: Skipping an If/Else/While body\n"));
550 444
551 if (walk_state->control_state) { 445 /* Skip body of if/else/while in pass 1 */
552 walk_state->control_state->
553 control.package_end =
554 parser_state->pkg_end;
555 }
556 break;
557 446
558 default: 447 walk_state->parser_state.aml =
448 walk_state->parser_state.pkg_end;
449 walk_state->arg_count = 0;
450 break;
559 451
560 /* No action for all other opcodes */ 452 default:
561 break;
562 }
563 break; 453 break;
564 } 454 }
565 } 455 }
456#endif
566 457
567 /* Check for arguments that need to be processed */ 458 switch (op->common.aml_opcode) {
568 459 case AML_METHOD_OP:
569 if (walk_state->arg_count) {
570 /* 460 /*
571 * There are arguments (complex ones), push Op and 461 * Skip parsing of control method because we don't have enough
572 * prepare for argument 462 * info in the first pass to parse it correctly.
463 *
464 * Save the length and address of the body
573 */ 465 */
574 status = acpi_ps_push_scope(parser_state, op, 466 op->named.data = walk_state->parser_state.aml;
575 walk_state->arg_types, 467 op->named.length = (u32)
576 walk_state->arg_count); 468 (walk_state->parser_state.pkg_end -
577 if (ACPI_FAILURE(status)) { 469 walk_state->parser_state.aml);
578 goto close_this_op;
579 }
580 op = NULL;
581 continue;
582 }
583 470
584 /* 471 /* Skip body of method */
585 * All arguments have been processed -- Op is complete,
586 * prepare for next
587 */
588 walk_state->op_info =
589 acpi_ps_get_opcode_info(op->common.aml_opcode);
590 if (walk_state->op_info->flags & AML_NAMED) {
591 if (acpi_gbl_depth) {
592 acpi_gbl_depth--;
593 }
594 472
595 if (op->common.aml_opcode == AML_REGION_OP) { 473 walk_state->parser_state.aml =
474 walk_state->parser_state.pkg_end;
475 walk_state->arg_count = 0;
476 break;
477
478 case AML_BUFFER_OP:
479 case AML_PACKAGE_OP:
480 case AML_VAR_PACKAGE_OP:
481
482 if ((op->common.parent) &&
483 (op->common.parent->common.aml_opcode ==
484 AML_NAME_OP)
485 && (walk_state->pass_number <=
486 ACPI_IMODE_LOAD_PASS2)) {
596 /* 487 /*
597 * Skip parsing of control method or opregion body, 488 * Skip parsing of Buffers and Packages because we don't have
598 * because we don't have enough info in the first pass 489 * enough info in the first pass to parse them correctly.
599 * to parse them correctly.
600 *
601 * Completed parsing an op_region declaration, we now
602 * know the length.
603 */ 490 */
604 op->named.length = 491 op->named.data = aml_op_start;
605 (u32) (parser_state->aml - op->named.data); 492 op->named.length = (u32)
606 } 493 (walk_state->parser_state.pkg_end -
607 } 494 aml_op_start);
608 495
609 if (walk_state->op_info->flags & AML_CREATE) { 496 /* Skip body */
610 /*
611 * Backup to beginning of create_xXXfield declaration (1 for
612 * Opcode)
613 *
614 * body_length is unknown until we parse the body
615 */
616 op->named.length =
617 (u32) (parser_state->aml - op->named.data);
618 }
619 497
620 /* This op complete, notify the dispatcher */ 498 walk_state->parser_state.aml =
499 walk_state->parser_state.pkg_end;
500 walk_state->arg_count = 0;
501 }
502 break;
621 503
622 if (walk_state->ascending_callback != NULL) { 504 case AML_WHILE_OP:
623 walk_state->op = op;
624 walk_state->opcode = op->common.aml_opcode;
625 505
626 status = walk_state->ascending_callback(walk_state); 506 if (walk_state->control_state) {
627 status = 507 walk_state->control_state->control.package_end =
628 acpi_ps_next_parse_state(walk_state, op, status); 508 walk_state->parser_state.pkg_end;
629 if (status == AE_CTRL_PENDING) {
630 status = AE_OK;
631 goto close_this_op;
632 } 509 }
633 } 510 break;
634
635 close_this_op:
636 /*
637 * Finished one argument of the containing scope
638 */
639 parser_state->scope->parse_scope.arg_count--;
640 511
641 /* Finished with pre_op */ 512 default:
642 513
643 if (pre_op) { 514 /* No action for all other opcodes */
644 acpi_ps_free_op(pre_op); 515 break;
645 pre_op = NULL;
646 } 516 }
647 517
648 /* Close this Op (will result in parse subtree deletion) */ 518 break;
519 }
649 520
650 status2 = acpi_ps_complete_this_op(walk_state, op); 521 return_ACPI_STATUS(AE_OK);
651 if (ACPI_FAILURE(status2)) { 522}
652 return_ACPI_STATUS(status2);
653 }
654 op = NULL;
655 523
656 switch (status) { 524/*******************************************************************************
657 case AE_OK: 525 *
658 break; 526 * FUNCTION: acpi_ps_complete_op
527 *
528 * PARAMETERS: walk_state - Current state
529 * Op - Returned Op
530 * Status - Parse status before complete Op
531 *
532 * RETURN: Status
533 *
534 * DESCRIPTION: Complete Op
535 *
536 ******************************************************************************/
659 537
660 case AE_CTRL_TRANSFER: 538static acpi_status
539acpi_ps_complete_op(struct acpi_walk_state *walk_state,
540 union acpi_parse_object **op, acpi_status status)
541{
542 acpi_status status2;
661 543
662 /* We are about to transfer to a called method. */ 544 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
663 545
664 walk_state->prev_op = op; 546 /*
665 walk_state->prev_arg_types = walk_state->arg_types; 547 * Finished one argument of the containing scope
666 return_ACPI_STATUS(status); 548 */
549 walk_state->parser_state.scope->parse_scope.arg_count--;
667 550
668 case AE_CTRL_END: 551 /* Close this Op (will result in parse subtree deletion) */
669 552
670 acpi_ps_pop_scope(parser_state, &op, 553 status2 = acpi_ps_complete_this_op(walk_state, *op);
671 &walk_state->arg_types, 554 if (ACPI_FAILURE(status2)) {
672 &walk_state->arg_count); 555 return_ACPI_STATUS(status2);
556 }
673 557
674 if (op) { 558 *op = NULL;
675 walk_state->op = op;
676 walk_state->op_info =
677 acpi_ps_get_opcode_info(op->common.
678 aml_opcode);
679 walk_state->opcode = op->common.aml_opcode;
680 559
681 status = 560 switch (status) {
682 walk_state->ascending_callback(walk_state); 561 case AE_OK:
683 status = 562 break;
684 acpi_ps_next_parse_state(walk_state, op,
685 status);
686 563
687 status2 = 564 case AE_CTRL_TRANSFER:
688 acpi_ps_complete_this_op(walk_state, op);
689 if (ACPI_FAILURE(status2)) {
690 return_ACPI_STATUS(status2);
691 }
692 op = NULL;
693 }
694 status = AE_OK;
695 break;
696 565
697 case AE_CTRL_BREAK: 566 /* We are about to transfer to a called method */
698 case AE_CTRL_CONTINUE:
699 567
700 /* Pop off scopes until we find the While */ 568 walk_state->prev_op = NULL;
569 walk_state->prev_arg_types = walk_state->arg_types;
570 return_ACPI_STATUS(status);
701 571
702 while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { 572 case AE_CTRL_END:
703 acpi_ps_pop_scope(parser_state, &op,
704 &walk_state->arg_types,
705 &walk_state->arg_count);
706 573
707 if (op->common.aml_opcode != AML_WHILE_OP) { 574 acpi_ps_pop_scope(&(walk_state->parser_state), op,
708 status2 = 575 &walk_state->arg_types,
709 acpi_ds_result_stack_pop 576 &walk_state->arg_count);
710 (walk_state);
711 if (ACPI_FAILURE(status2)) {
712 return_ACPI_STATUS(status2);
713 }
714 }
715 }
716
717 /* Close this iteration of the While loop */
718 577
719 walk_state->op = op; 578 if (*op) {
579 walk_state->op = *op;
720 walk_state->op_info = 580 walk_state->op_info =
721 acpi_ps_get_opcode_info(op->common.aml_opcode); 581 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
722 walk_state->opcode = op->common.aml_opcode; 582 walk_state->opcode = (*op)->common.aml_opcode;
723 583
724 status = walk_state->ascending_callback(walk_state); 584 status = walk_state->ascending_callback(walk_state);
725 status = 585 status =
726 acpi_ps_next_parse_state(walk_state, op, status); 586 acpi_ps_next_parse_state(walk_state, *op, status);
727 587
728 status2 = acpi_ps_complete_this_op(walk_state, op); 588 status2 = acpi_ps_complete_this_op(walk_state, *op);
729 if (ACPI_FAILURE(status2)) { 589 if (ACPI_FAILURE(status2)) {
730 return_ACPI_STATUS(status2); 590 return_ACPI_STATUS(status2);
731 } 591 }
732 op = NULL; 592 }
733
734 status = AE_OK;
735 break;
736 593
737 case AE_CTRL_TERMINATE: 594 status = AE_OK;
595 break;
738 596
739 status = AE_OK; 597 case AE_CTRL_BREAK:
598 case AE_CTRL_CONTINUE:
740 599
741 /* Clean up */ 600 /* Pop off scopes until we find the While */
742 do {
743 if (op) {
744 status2 =
745 acpi_ps_complete_this_op(walk_state,
746 op);
747 if (ACPI_FAILURE(status2)) {
748 return_ACPI_STATUS(status2);
749 }
750 601
751 status2 = 602 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
752 acpi_ds_result_stack_pop 603 acpi_ps_pop_scope(&(walk_state->parser_state), op,
753 (walk_state); 604 &walk_state->arg_types,
754 if (ACPI_FAILURE(status2)) { 605 &walk_state->arg_count);
755 return_ACPI_STATUS(status2);
756 }
757 606
758 acpi_ut_delete_generic_state 607 if ((*op)->common.aml_opcode != AML_WHILE_OP) {
759 (acpi_ut_pop_generic_state 608 status2 = acpi_ds_result_stack_pop(walk_state);
760 (&walk_state->control_state)); 609 if (ACPI_FAILURE(status2)) {
610 return_ACPI_STATUS(status2);
761 } 611 }
612 }
613 }
762 614
763 acpi_ps_pop_scope(parser_state, &op, 615 /* Close this iteration of the While loop */
764 &walk_state->arg_types,
765 &walk_state->arg_count);
766 616
767 } while (op); 617 walk_state->op = *op;
618 walk_state->op_info =
619 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
620 walk_state->opcode = (*op)->common.aml_opcode;
768 621
769 return_ACPI_STATUS(status); 622 status = walk_state->ascending_callback(walk_state);
623 status = acpi_ps_next_parse_state(walk_state, *op, status);
770 624
771 default: /* All other non-AE_OK status */ 625 status2 = acpi_ps_complete_this_op(walk_state, *op);
626 if (ACPI_FAILURE(status2)) {
627 return_ACPI_STATUS(status2);
628 }
772 629
773 do { 630 status = AE_OK;
774 if (op) { 631 break;
775 status2 = 632
776 acpi_ps_complete_this_op(walk_state, 633 case AE_CTRL_TERMINATE:
777 op); 634
778 if (ACPI_FAILURE(status2)) { 635 /* Clean up */
779 return_ACPI_STATUS(status2); 636 do {
780 } 637 if (*op) {
638 status2 =
639 acpi_ps_complete_this_op(walk_state, *op);
640 if (ACPI_FAILURE(status2)) {
641 return_ACPI_STATUS(status2);
642 }
643 status2 = acpi_ds_result_stack_pop(walk_state);
644 if (ACPI_FAILURE(status2)) {
645 return_ACPI_STATUS(status2);
781 } 646 }
782 647
783 acpi_ps_pop_scope(parser_state, &op, 648 acpi_ut_delete_generic_state
784 &walk_state->arg_types, 649 (acpi_ut_pop_generic_state
785 &walk_state->arg_count); 650 (&walk_state->control_state));
651 }
786 652
787 } while (op); 653 acpi_ps_pop_scope(&(walk_state->parser_state), op,
654 &walk_state->arg_types,
655 &walk_state->arg_count);
788 656
789 /* 657 } while (*op);
790 * TBD: Cleanup parse ops on error 658
791 */ 659 return_ACPI_STATUS(AE_OK);
792#if 0 660
793 if (op == NULL) { 661 default: /* All other non-AE_OK status */
794 acpi_ps_pop_scope(parser_state, &op, 662
795 &walk_state->arg_types, 663 do {
796 &walk_state->arg_count); 664 if (*op) {
665 status2 =
666 acpi_ps_complete_this_op(walk_state, *op);
667 if (ACPI_FAILURE(status2)) {
668 return_ACPI_STATUS(status2);
669 }
797 } 670 }
798#endif
799 walk_state->prev_op = op;
800 walk_state->prev_arg_types = walk_state->arg_types;
801 return_ACPI_STATUS(status);
802 }
803 671
804 /* This scope complete? */ 672 acpi_ps_pop_scope(&(walk_state->parser_state), op,
673 &walk_state->arg_types,
674 &walk_state->arg_count);
805 675
806 if (acpi_ps_has_completed_scope(parser_state)) { 676 } while (*op);
807 acpi_ps_pop_scope(parser_state, &op, 677
678#if 0
679 /*
680 * TBD: Cleanup parse ops on error
681 */
682 if (*op == NULL) {
683 acpi_ps_pop_scope(parser_state, op,
808 &walk_state->arg_types, 684 &walk_state->arg_types,
809 &walk_state->arg_count); 685 &walk_state->arg_count);
810 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
811 "Popped scope, Op=%p\n", op));
812 } else {
813 op = NULL;
814 } 686 }
687#endif
688 walk_state->prev_op = NULL;
689 walk_state->prev_arg_types = walk_state->arg_types;
690 return_ACPI_STATUS(status);
691 }
815 692
816 } /* while parser_state->Aml */ 693 /* This scope complete? */
694
695 if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
696 acpi_ps_pop_scope(&(walk_state->parser_state), op,
697 &walk_state->arg_types,
698 &walk_state->arg_count);
699 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
700 } else {
701 *op = NULL;
702 }
703
704 return_ACPI_STATUS(AE_OK);
705}
706
707/*******************************************************************************
708 *
709 * FUNCTION: acpi_ps_complete_final_op
710 *
711 * PARAMETERS: walk_state - Current state
712 * Op - Current Op
713 * Status - Current parse status before complete last
714 * Op
715 *
716 * RETURN: Status
717 *
718 * DESCRIPTION: Complete last Op.
719 *
720 ******************************************************************************/
721
722static acpi_status
723acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
724 union acpi_parse_object *op, acpi_status status)
725{
726 acpi_status status2;
727
728 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
817 729
818 /* 730 /*
819 * Complete the last Op (if not completed), and clear the scope stack. 731 * Complete the last Op (if not completed), and clear the scope stack.
820 * It is easily possible to end an AML "package" with an unbounded number 732 * It is easily possible to end an AML "package" with an unbounded number
821 * of open scopes (such as when several ASL blocks are closed with 733 * of open scopes (such as when several ASL blocks are closed with
822 * sequential closing braces). We want to terminate each one cleanly. 734 * sequential closing braces). We want to terminate each one cleanly.
823 */ 735 */
824 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n", 736 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
825 op)); 737 op));
@@ -838,8 +750,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
838 acpi_ps_next_parse_state(walk_state, op, 750 acpi_ps_next_parse_state(walk_state, op,
839 status); 751 status);
840 if (status == AE_CTRL_PENDING) { 752 if (status == AE_CTRL_PENDING) {
841 status = AE_OK; 753 status =
842 goto close_this_op; 754 acpi_ps_complete_op(walk_state, &op,
755 AE_OK);
756 if (ACPI_FAILURE(status)) {
757 return_ACPI_STATUS(status);
758 }
843 } 759 }
844 760
845 if (status == AE_CTRL_TERMINATE) { 761 if (status == AE_CTRL_TERMINATE) {
@@ -858,7 +774,9 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
858 } 774 }
859 } 775 }
860 776
861 acpi_ps_pop_scope(parser_state, 777 acpi_ps_pop_scope(&
778 (walk_state->
779 parser_state),
862 &op, 780 &op,
863 &walk_state-> 781 &walk_state->
864 arg_types, 782 arg_types,
@@ -887,10 +805,252 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
887 } 805 }
888 } 806 }
889 807
890 acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, 808 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
809 &walk_state->arg_types,
891 &walk_state->arg_count); 810 &walk_state->arg_count);
892 811
893 } while (op); 812 } while (op);
894 813
895 return_ACPI_STATUS(status); 814 return_ACPI_STATUS(status);
896} 815}
816
817/*******************************************************************************
818 *
819 * FUNCTION: acpi_ps_parse_loop
820 *
821 * PARAMETERS: walk_state - Current state
822 *
823 * RETURN: Status
824 *
825 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
826 * a tree of ops.
827 *
828 ******************************************************************************/
829
830acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
831{
832 acpi_status status = AE_OK;
833 union acpi_parse_object *op = NULL; /* current op */
834 struct acpi_parse_state *parser_state;
835 u8 *aml_op_start = NULL;
836
837 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
838
839 if (walk_state->descending_callback == NULL) {
840 return_ACPI_STATUS(AE_BAD_PARAMETER);
841 }
842
843 parser_state = &walk_state->parser_state;
844 walk_state->arg_types = 0;
845
846#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
847
848 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
849
850 /* We are restarting a preempted control method */
851
852 if (acpi_ps_has_completed_scope(parser_state)) {
853 /*
854 * We must check if a predicate to an IF or WHILE statement
855 * was just completed
856 */
857 if ((parser_state->scope->parse_scope.op) &&
858 ((parser_state->scope->parse_scope.op->common.
859 aml_opcode == AML_IF_OP)
860 || (parser_state->scope->parse_scope.op->common.
861 aml_opcode == AML_WHILE_OP))
862 && (walk_state->control_state)
863 && (walk_state->control_state->common.state ==
864 ACPI_CONTROL_PREDICATE_EXECUTING)) {
865 /*
866 * A predicate was just completed, get the value of the
867 * predicate and branch based on that value
868 */
869 walk_state->op = NULL;
870 status =
871 acpi_ds_get_predicate_value(walk_state,
872 ACPI_TO_POINTER
873 (TRUE));
874 if (ACPI_FAILURE(status)
875 && ((status & AE_CODE_MASK) !=
876 AE_CODE_CONTROL)) {
877 if (status == AE_AML_NO_RETURN_VALUE) {
878 ACPI_EXCEPTION((AE_INFO, status,
879 "Invoked method did not return a value"));
880
881 }
882
883 ACPI_EXCEPTION((AE_INFO, status,
884 "GetPredicate Failed"));
885 return_ACPI_STATUS(status);
886 }
887
888 status =
889 acpi_ps_next_parse_state(walk_state, op,
890 status);
891 }
892
893 acpi_ps_pop_scope(parser_state, &op,
894 &walk_state->arg_types,
895 &walk_state->arg_count);
896 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
897 "Popped scope, Op=%p\n", op));
898 } else if (walk_state->prev_op) {
899
900 /* We were in the middle of an op */
901
902 op = walk_state->prev_op;
903 walk_state->arg_types = walk_state->prev_arg_types;
904 }
905 }
906#endif
907
908 /* Iterative parsing loop, while there is more AML to process: */
909
910 while ((parser_state->aml < parser_state->aml_end) || (op)) {
911 aml_op_start = parser_state->aml;
912 if (!op) {
913 status =
914 acpi_ps_create_op(walk_state, aml_op_start, &op);
915 if (ACPI_FAILURE(status)) {
916 if (status == AE_CTRL_PARSE_CONTINUE) {
917 continue;
918 }
919
920 if (status == AE_CTRL_PARSE_PENDING) {
921 status = AE_OK;
922 }
923
924 status =
925 acpi_ps_complete_op(walk_state, &op,
926 status);
927 if (ACPI_FAILURE(status)) {
928 return_ACPI_STATUS(status);
929 }
930
931 continue;
932 }
933
934 op->common.aml_offset = walk_state->aml_offset;
935
936 if (walk_state->op_info) {
937 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
938 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
939 (u32) op->common.aml_opcode,
940 walk_state->op_info->name, op,
941 parser_state->aml,
942 op->common.aml_offset));
943 }
944 }
945
946 /*
947 * Start arg_count at zero because we don't know if there are
948 * any args yet
949 */
950 walk_state->arg_count = 0;
951
952 /* Are there any arguments that must be processed? */
953
954 if (walk_state->arg_types) {
955
956 /* Get arguments */
957
958 status =
959 acpi_ps_get_arguments(walk_state, aml_op_start, op);
960 if (ACPI_FAILURE(status)) {
961 status =
962 acpi_ps_complete_op(walk_state, &op,
963 status);
964 if (ACPI_FAILURE(status)) {
965 return_ACPI_STATUS(status);
966 }
967
968 continue;
969 }
970 }
971
972 /* Check for arguments that need to be processed */
973
974 if (walk_state->arg_count) {
975 /*
976 * There are arguments (complex ones), push Op and
977 * prepare for argument
978 */
979 status = acpi_ps_push_scope(parser_state, op,
980 walk_state->arg_types,
981 walk_state->arg_count);
982 if (ACPI_FAILURE(status)) {
983 status =
984 acpi_ps_complete_op(walk_state, &op,
985 status);
986 if (ACPI_FAILURE(status)) {
987 return_ACPI_STATUS(status);
988 }
989
990 continue;
991 }
992
993 op = NULL;
994 continue;
995 }
996
997 /*
998 * All arguments have been processed -- Op is complete,
999 * prepare for next
1000 */
1001 walk_state->op_info =
1002 acpi_ps_get_opcode_info(op->common.aml_opcode);
1003 if (walk_state->op_info->flags & AML_NAMED) {
1004 if (acpi_gbl_depth) {
1005 acpi_gbl_depth--;
1006 }
1007
1008 if (op->common.aml_opcode == AML_REGION_OP) {
1009 /*
1010 * Skip parsing of control method or opregion body,
1011 * because we don't have enough info in the first pass
1012 * to parse them correctly.
1013 *
1014 * Completed parsing an op_region declaration, we now
1015 * know the length.
1016 */
1017 op->named.length =
1018 (u32) (parser_state->aml - op->named.data);
1019 }
1020 }
1021
1022 if (walk_state->op_info->flags & AML_CREATE) {
1023 /*
1024 * Backup to beginning of create_xXXfield declaration (1 for
1025 * Opcode)
1026 *
1027 * body_length is unknown until we parse the body
1028 */
1029 op->named.length =
1030 (u32) (parser_state->aml - op->named.data);
1031 }
1032
1033 /* This op complete, notify the dispatcher */
1034
1035 if (walk_state->ascending_callback != NULL) {
1036 walk_state->op = op;
1037 walk_state->opcode = op->common.aml_opcode;
1038
1039 status = walk_state->ascending_callback(walk_state);
1040 status =
1041 acpi_ps_next_parse_state(walk_state, op, status);
1042 if (status == AE_CTRL_PENDING) {
1043 status = AE_OK;
1044 }
1045 }
1046
1047 status = acpi_ps_complete_op(walk_state, &op, status);
1048 if (ACPI_FAILURE(status)) {
1049 return_ACPI_STATUS(status);
1050 }
1051
1052 } /* while parser_state->Aml */
1053
1054 status = acpi_ps_complete_final_op(walk_state, op, status);
1055 return_ACPI_STATUS(status);
1056}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 4bd25e32769f..16d8b6cc3c22 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index a02aa62fe1e5..5d63f48e56b5 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -540,6 +540,11 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
540 540
541 if ((status == AE_ALREADY_EXISTS) && 541 if ((status == AE_ALREADY_EXISTS) &&
542 (!walk_state->method_desc->method.mutex)) { 542 (!walk_state->method_desc->method.mutex)) {
543 ACPI_INFO((AE_INFO,
544 "Marking method %4.4s as Serialized",
545 walk_state->method_node->name.
546 ascii));
547
543 /* 548 /*
544 * Method tried to create an object twice. The probable cause is 549 * Method tried to create an object twice. The probable cause is
545 * that the method cannot handle reentrancy. 550 * that the method cannot handle reentrancy.
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index a3e0314de24d..77cfa4ed0cfe 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index 0015717ef096..966e7ea2a0c4 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index d405387b7414..8ca52002db55 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index a84a547a0f1b..49f9757434e4 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5d996c1140af..94103bced75e 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,6 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info);
54 54
55static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); 55static void acpi_ps_stop_trace(struct acpi_evaluate_info *info);
56 56
57static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info);
58
59static void 57static void
60acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); 58acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
61 59
@@ -215,6 +213,8 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
215acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) 213acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
216{ 214{
217 acpi_status status; 215 acpi_status status;
216 union acpi_parse_object *op;
217 struct acpi_walk_state *walk_state;
218 218
219 ACPI_FUNCTION_TRACE(ps_execute_method); 219 ACPI_FUNCTION_TRACE(ps_execute_method);
220 220
@@ -234,8 +234,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
234 } 234 }
235 235
236 /* 236 /*
237 * The caller "owns" the parameters, so give each one an extra 237 * The caller "owns" the parameters, so give each one an extra reference
238 * reference
239 */ 238 */
240 acpi_ps_update_parameter_list(info, REF_INCREMENT); 239 acpi_ps_update_parameter_list(info, REF_INCREMENT);
241 240
@@ -244,30 +243,50 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
244 acpi_ps_start_trace(info); 243 acpi_ps_start_trace(info);
245 244
246 /* 245 /*
247 * 1) Perform the first pass parse of the method to enter any 246 * Execute the method. Performs parse simultaneously
248 * named objects that it creates into the namespace
249 */ 247 */
250 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 248 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
251 "**** Begin Method Parse **** Entry=%p obj=%p\n", 249 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
252 info->resolved_node, info->obj_desc)); 250 info->resolved_node->name.ascii, info->resolved_node,
251 info->obj_desc));
252
253 /* Create and init a Root Node */
254
255 op = acpi_ps_create_scope_op();
256 if (!op) {
257 status = AE_NO_MEMORY;
258 goto cleanup;
259 }
260
261 /* Create and initialize a new walk state */
262
263 info->pass_number = ACPI_IMODE_EXECUTE;
264 walk_state =
265 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
266 NULL, NULL);
267 if (!walk_state) {
268 status = AE_NO_MEMORY;
269 goto cleanup;
270 }
253 271
254 info->pass_number = 1; 272 status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
255 status = acpi_ps_execute_pass(info); 273 info->obj_desc->method.aml_start,
274 info->obj_desc->method.aml_length, info,
275 info->pass_number);
256 if (ACPI_FAILURE(status)) { 276 if (ACPI_FAILURE(status)) {
277 acpi_ds_delete_walk_state(walk_state);
257 goto cleanup; 278 goto cleanup;
258 } 279 }
259 280
260 /* 281 /* Parse the AML */
261 * 2) Execute the method. Performs second pass parse simultaneously
262 */
263 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
264 "**** Begin Method Execution **** Entry=%p obj=%p\n",
265 info->resolved_node, info->obj_desc));
266 282
267 info->pass_number = 3; 283 status = acpi_ps_parse_aml(walk_state);
268 status = acpi_ps_execute_pass(info); 284
285 /* walk_state was deleted by parse_aml */
269 286
270 cleanup: 287 cleanup:
288 acpi_ps_delete_parse_tree(op);
289
271 /* End optional tracing */ 290 /* End optional tracing */
272 291
273 acpi_ps_stop_trace(info); 292 acpi_ps_stop_trace(info);
@@ -330,62 +349,3 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
330 } 349 }
331 } 350 }
332} 351}
333
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_ps_execute_pass
337 *
338 * PARAMETERS: Info - See struct acpi_evaluate_info
339 * (Used: pass_number, Node, and obj_desc)
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Single AML pass: Parse or Execute a control method
344 *
345 ******************************************************************************/
346
347static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info)
348{
349 acpi_status status;
350 union acpi_parse_object *op;
351 struct acpi_walk_state *walk_state;
352
353 ACPI_FUNCTION_TRACE(ps_execute_pass);
354
355 /* Create and init a Root Node */
356
357 op = acpi_ps_create_scope_op();
358 if (!op) {
359 return_ACPI_STATUS(AE_NO_MEMORY);
360 }
361
362 /* Create and initialize a new walk state */
363
364 walk_state =
365 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
366 NULL, NULL);
367 if (!walk_state) {
368 status = AE_NO_MEMORY;
369 goto cleanup;
370 }
371
372 status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
373 info->obj_desc->method.aml_start,
374 info->obj_desc->method.aml_length,
375 info->pass_number == 1 ? NULL : info,
376 info->pass_number);
377 if (ACPI_FAILURE(status)) {
378 acpi_ds_delete_walk_state(walk_state);
379 goto cleanup;
380 }
381
382 /* Parse the AML */
383
384 status = acpi_ps_parse_aml(walk_state);
385
386 /* Walk state was deleted by parse_aml */
387
388 cleanup:
389 acpi_ps_delete_parse_tree(op);
390 return_ACPI_STATUS(status);
391}
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 481e633bbf41..0f683c8c6fbc 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -513,7 +513,7 @@ int __init acpi_irq_penalty_init(void)
513 } 513 }
514 } 514 }
515 /* Add a penalty for the SCI */ 515 /* Add a penalty for the SCI */
516 acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING; 516 acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
517 517
518 return 0; 518 return 0;
519} 519}
@@ -785,7 +785,7 @@ static int irqrouter_resume(struct sys_device *dev)
785 785
786 786
787 /* Make sure SCI is enabled again (Apple firmware bug?) */ 787 /* Make sure SCI is enabled again (Apple firmware bug?) */
788 acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK); 788 acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
789 789
790 list_for_each(node, &acpi_link.entries) { 790 list_for_each(node, &acpi_link.entries) {
791 link = list_entry(node, struct acpi_pci_link, node); 791 link = list_entry(node, struct acpi_pci_link, node);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a860efa2c562..4ecf701687e8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -117,6 +117,19 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
117 117
118EXPORT_SYMBOL(acpi_pci_unregister_driver); 118EXPORT_SYMBOL(acpi_pci_unregister_driver);
119 119
120acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
121{
122 struct acpi_pci_root *tmp;
123
124 list_for_each_entry(tmp, &acpi_pci_roots, node) {
125 if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
126 return tmp->device->handle;
127 }
128 return NULL;
129}
130
131EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
132
120static acpi_status 133static acpi_status
121get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 134get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
122{ 135{
@@ -152,6 +165,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
152 return AE_OK; 165 return AE_OK;
153} 166}
154 167
168static void acpi_pci_bridge_scan(struct acpi_device *device)
169{
170 int status;
171 struct acpi_device *child = NULL;
172
173 if (device->flags.bus_address)
174 if (device->parent && device->parent->ops.bind) {
175 status = device->parent->ops.bind(device);
176 if (!status) {
177 list_for_each_entry(child, &device->children, node)
178 acpi_pci_bridge_scan(child);
179 }
180 }
181}
182
155static int acpi_pci_root_add(struct acpi_device *device) 183static int acpi_pci_root_add(struct acpi_device *device)
156{ 184{
157 int result = 0; 185 int result = 0;
@@ -160,6 +188,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
160 acpi_status status = AE_OK; 188 acpi_status status = AE_OK;
161 unsigned long value = 0; 189 unsigned long value = 0;
162 acpi_handle handle = NULL; 190 acpi_handle handle = NULL;
191 struct acpi_device *child;
163 192
164 193
165 if (!device) 194 if (!device)
@@ -175,9 +204,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
175 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 204 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
176 acpi_driver_data(device) = root; 205 acpi_driver_data(device) = root;
177 206
178 /*
179 * TBD: Doesn't the bus driver automatically set this?
180 */
181 device->ops.bind = acpi_pci_bind; 207 device->ops.bind = acpi_pci_bind;
182 208
183 /* 209 /*
@@ -299,6 +325,12 @@ static int acpi_pci_root_add(struct acpi_device *device)
299 result = acpi_pci_irq_add_prt(device->handle, root->id.segment, 325 result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
300 root->id.bus); 326 root->id.bus);
301 327
328 /*
329 * Scan and bind all _ADR-Based Devices
330 */
331 list_for_each_entry(child, &device->children, node)
332 acpi_pci_bridge_scan(child);
333
302 end: 334 end:
303 if (result) { 335 if (result) {
304 if (!list_empty(&root->node)) 336 if (!list_empty(&root->node))
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 5f9496d59ed6..0079bc51082c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -375,30 +375,126 @@ static int acpi_processor_remove_fs(struct acpi_device *device)
375} 375}
376 376
377/* Use the acpiid in MADT to map cpus in case of SMP */ 377/* Use the acpiid in MADT to map cpus in case of SMP */
378
378#ifndef CONFIG_SMP 379#ifndef CONFIG_SMP
379#define convert_acpiid_to_cpu(acpi_id) (-1) 380static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;}
380#else 381#else
381 382
383static struct acpi_table_madt *madt;
384
385static int map_lapic_id(struct acpi_subtable_header *entry,
386 u32 acpi_id, int *apic_id)
387{
388 struct acpi_madt_local_apic *lapic =
389 (struct acpi_madt_local_apic *)entry;
390 if ((lapic->lapic_flags & ACPI_MADT_ENABLED) &&
391 lapic->processor_id == acpi_id) {
392 *apic_id = lapic->id;
393 return 1;
394 }
395 return 0;
396}
397
398static int map_lsapic_id(struct acpi_subtable_header *entry,
399 u32 acpi_id, int *apic_id)
400{
401 struct acpi_madt_local_sapic *lsapic =
402 (struct acpi_madt_local_sapic *)entry;
403 /* Only check enabled APICs*/
404 if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
405 /* First check against id */
406 if (lsapic->processor_id == acpi_id) {
407 *apic_id = lsapic->id;
408 return 1;
409 /* Check against optional uid */
410 } else if (entry->length >= 16 &&
411 lsapic->uid == acpi_id) {
412 *apic_id = lsapic->uid;
413 return 1;
414 }
415 }
416 return 0;
417}
418
382#ifdef CONFIG_IA64 419#ifdef CONFIG_IA64
383#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid
384#define arch_cpu_to_apicid ia64_cpu_to_sapicid 420#define arch_cpu_to_apicid ia64_cpu_to_sapicid
385#define ARCH_BAD_APICID (0xffff)
386#else 421#else
387#define arch_acpiid_to_apicid x86_acpiid_to_apicid
388#define arch_cpu_to_apicid x86_cpu_to_apicid 422#define arch_cpu_to_apicid x86_cpu_to_apicid
389#define ARCH_BAD_APICID (0xff)
390#endif 423#endif
391 424
392static int convert_acpiid_to_cpu(u8 acpi_id) 425static int map_madt_entry(u32 acpi_id)
426{
427 unsigned long madt_end, entry;
428 int apic_id = -1;
429
430 if (!madt)
431 return apic_id;
432
433 entry = (unsigned long)madt;
434 madt_end = entry + madt->header.length;
435
436 /* Parse all entries looking for a match. */
437
438 entry += sizeof(struct acpi_table_madt);
439 while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
440 struct acpi_subtable_header *header =
441 (struct acpi_subtable_header *)entry;
442 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
443 if (map_lapic_id(header, acpi_id, &apic_id))
444 break;
445 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
446 if (map_lsapic_id(header, acpi_id, &apic_id))
447 break;
448 }
449 entry += header->length;
450 }
451 return apic_id;
452}
453
454static int map_mat_entry(acpi_handle handle, u32 acpi_id)
455{
456 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
457 union acpi_object *obj;
458 struct acpi_subtable_header *header;
459 int apic_id = -1;
460
461 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
462 goto exit;
463
464 if (!buffer.length || !buffer.pointer)
465 goto exit;
466
467 obj = buffer.pointer;
468 if (obj->type != ACPI_TYPE_BUFFER ||
469 obj->buffer.length < sizeof(struct acpi_subtable_header)) {
470 goto exit;
471 }
472
473 header = (struct acpi_subtable_header *)obj->buffer.pointer;
474 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
475 map_lapic_id(header, acpi_id, &apic_id);
476 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
477 map_lsapic_id(header, acpi_id, &apic_id);
478 }
479
480exit:
481 if (buffer.pointer)
482 kfree(buffer.pointer);
483 return apic_id;
484}
485
486static int get_cpu_id(acpi_handle handle, u32 acpi_id)
393{ 487{
394 u16 apic_id;
395 int i; 488 int i;
489 int apic_id = -1;
396 490
397 apic_id = arch_acpiid_to_apicid[acpi_id]; 491 apic_id = map_mat_entry(handle, acpi_id);
398 if (apic_id == ARCH_BAD_APICID) 492 if (apic_id == -1)
399 return -1; 493 apic_id = map_madt_entry(acpi_id);
494 if (apic_id == -1)
495 return apic_id;
400 496
401 for (i = 0; i < NR_CPUS; i++) { 497 for (i = 0; i < NR_CPUS; ++i) {
402 if (arch_cpu_to_apicid[i] == apic_id) 498 if (arch_cpu_to_apicid[i] == apic_id)
403 return i; 499 return i;
404 } 500 }
@@ -410,7 +506,7 @@ static int convert_acpiid_to_cpu(u8 acpi_id)
410 Driver Interface 506 Driver Interface
411 -------------------------------------------------------------------------- */ 507 -------------------------------------------------------------------------- */
412 508
413static int acpi_processor_get_info(struct acpi_processor *pr) 509static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
414{ 510{
415 acpi_status status = 0; 511 acpi_status status = 0;
416 union acpi_object object = { 0 }; 512 union acpi_object object = { 0 };
@@ -431,7 +527,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
431 * Check to see if we have bus mastering arbitration control. This 527 * Check to see if we have bus mastering arbitration control. This
432 * is required for proper C3 usage (to maintain cache coherency). 528 * is required for proper C3 usage (to maintain cache coherency).
433 */ 529 */
434 if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { 530 if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
435 pr->flags.bm_control = 1; 531 pr->flags.bm_control = 1;
436 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 532 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
437 "Bus mastering arbitration control present\n")); 533 "Bus mastering arbitration control present\n"));
@@ -439,24 +535,35 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
439 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 535 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
440 "No bus mastering arbitration control\n")); 536 "No bus mastering arbitration control\n"));
441 537
442 /* 538 /* Check if it is a Device with HID and UID */
443 * Evalute the processor object. Note that it is common on SMP to 539 if (has_uid) {
444 * have the first (boot) processor with a valid PBLK address while 540 unsigned long value;
445 * all others have a NULL address. 541 status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
446 */ 542 NULL, &value);
447 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); 543 if (ACPI_FAILURE(status)) {
448 if (ACPI_FAILURE(status)) { 544 printk(KERN_ERR PREFIX "Evaluating processor _UID\n");
449 printk(KERN_ERR PREFIX "Evaluating processor object\n"); 545 return -ENODEV;
450 return -ENODEV; 546 }
451 } 547 pr->acpi_id = value;
452 548 } else {
453 /* 549 /*
454 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. 550 * Evalute the processor object. Note that it is common on SMP to
455 * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c 551 * have the first (boot) processor with a valid PBLK address while
456 */ 552 * all others have a NULL address.
457 pr->acpi_id = object.processor.proc_id; 553 */
554 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
555 if (ACPI_FAILURE(status)) {
556 printk(KERN_ERR PREFIX "Evaluating processor object\n");
557 return -ENODEV;
558 }
458 559
459 cpu_index = convert_acpiid_to_cpu(pr->acpi_id); 560 /*
561 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
562 * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
563 */
564 pr->acpi_id = object.processor.proc_id;
565 }
566 cpu_index = get_cpu_id(pr->handle, pr->acpi_id);
460 567
461 /* Handle UP system running SMP kernel, with no LAPIC in MADT */ 568 /* Handle UP system running SMP kernel, with no LAPIC in MADT */
462 if (!cpu0_initialized && (cpu_index == -1) && 569 if (!cpu0_initialized && (cpu_index == -1) &&
@@ -473,7 +580,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
473 * less than the max # of CPUs. They should be ignored _iff 580 * less than the max # of CPUs. They should be ignored _iff
474 * they are physically not present. 581 * they are physically not present.
475 */ 582 */
476 if (cpu_index == -1) { 583 if (pr->id == -1) {
477 if (ACPI_FAILURE 584 if (ACPI_FAILURE
478 (acpi_processor_hotadd_init(pr->handle, &pr->id))) { 585 (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
479 return -ENODEV; 586 return -ENODEV;
@@ -490,8 +597,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
490 object.processor.pblk_length); 597 object.processor.pblk_length);
491 else { 598 else {
492 pr->throttling.address = object.processor.pblk_address; 599 pr->throttling.address = object.processor.pblk_address;
493 pr->throttling.duty_offset = acpi_fadt.duty_offset; 600 pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
494 pr->throttling.duty_width = acpi_fadt.duty_width; 601 pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
495 602
496 pr->pblk = object.processor.pblk_address; 603 pr->pblk = object.processor.pblk_address;
497 604
@@ -525,7 +632,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
525 632
526 pr = acpi_driver_data(device); 633 pr = acpi_driver_data(device);
527 634
528 result = acpi_processor_get_info(pr); 635 result = acpi_processor_get_info(pr, device->flags.unique_id);
529 if (result) { 636 if (result) {
530 /* Processor is physically not present */ 637 /* Processor is physically not present */
531 return 0; 638 return 0;
@@ -707,7 +814,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
707 return -ENODEV; 814 return -ENODEV;
708 815
709 if ((pr->id >= 0) && (pr->id < NR_CPUS)) { 816 if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
710 kobject_uevent(&(*device)->kobj, KOBJ_ONLINE); 817 kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
711 } 818 }
712 return 0; 819 return 0;
713} 820}
@@ -745,13 +852,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
745 } 852 }
746 853
747 if (pr->id >= 0 && (pr->id < NR_CPUS)) { 854 if (pr->id >= 0 && (pr->id < NR_CPUS)) {
748 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 855 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
749 break; 856 break;
750 } 857 }
751 858
752 result = acpi_processor_start(device); 859 result = acpi_processor_start(device);
753 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { 860 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
754 kobject_uevent(&device->kobj, KOBJ_ONLINE); 861 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
755 } else { 862 } else {
756 printk(KERN_ERR PREFIX "Device [%s] failed to start\n", 863 printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
757 acpi_device_bid(device)); 864 acpi_device_bid(device));
@@ -774,7 +881,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
774 } 881 }
775 882
776 if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) 883 if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
777 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 884 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
778 break; 885 break;
779 default: 886 default:
780 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 887 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -895,6 +1002,12 @@ static int __init acpi_processor_init(void)
895 memset(&processors, 0, sizeof(processors)); 1002 memset(&processors, 0, sizeof(processors));
896 memset(&errata, 0, sizeof(errata)); 1003 memset(&errata, 0, sizeof(errata));
897 1004
1005#ifdef CONFIG_SMP
1006 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
1007 (struct acpi_table_header **)&madt)))
1008 madt = 0;
1009#endif
1010
898 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); 1011 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
899 if (!acpi_processor_dir) 1012 if (!acpi_processor_dir)
900 return -ENOMEM; 1013 return -ENOMEM;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 3f30af21574e..6c6751b1405b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -160,7 +160,7 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
160{ 160{
161 if (t2 >= t1) 161 if (t2 >= t1)
162 return (t2 - t1); 162 return (t2 - t1);
163 else if (!acpi_fadt.tmr_val_ext) 163 else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
164 return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); 164 return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
165 else 165 else
166 return ((0xFFFFFFFF - t1) + t2); 166 return ((0xFFFFFFFF - t1) + t2);
@@ -187,8 +187,7 @@ acpi_processor_power_activate(struct acpi_processor *pr,
187 case ACPI_STATE_C3: 187 case ACPI_STATE_C3:
188 /* Disable bus master reload */ 188 /* Disable bus master reload */
189 if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) 189 if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
190 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, 190 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
191 ACPI_MTX_DO_NOT_LOCK);
192 break; 191 break;
193 } 192 }
194 } 193 }
@@ -198,8 +197,7 @@ acpi_processor_power_activate(struct acpi_processor *pr,
198 case ACPI_STATE_C3: 197 case ACPI_STATE_C3:
199 /* Enable bus master reload */ 198 /* Enable bus master reload */
200 if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) 199 if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
201 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, 200 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
202 ACPI_MTX_DO_NOT_LOCK);
203 break; 201 break;
204 } 202 }
205 203
@@ -236,7 +234,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
236 /* Dummy wait op - must do something useless after P_LVL2 read 234 /* Dummy wait op - must do something useless after P_LVL2 read
237 because chipsets cannot guarantee that STPCLK# signal 235 because chipsets cannot guarantee that STPCLK# signal
238 gets asserted in time to freeze execution properly. */ 236 gets asserted in time to freeze execution properly. */
239 unused = inl(acpi_fadt.xpm_tmr_blk.address); 237 unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
240 } 238 }
241} 239}
242 240
@@ -291,12 +289,10 @@ static void acpi_processor_idle(void)
291 289
292 pr->power.bm_activity <<= diff; 290 pr->power.bm_activity <<= diff;
293 291
294 acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, 292 acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
295 &bm_status, ACPI_MTX_DO_NOT_LOCK);
296 if (bm_status) { 293 if (bm_status) {
297 pr->power.bm_activity |= 0x1; 294 pr->power.bm_activity |= 0x1;
298 acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 295 acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
299 1, ACPI_MTX_DO_NOT_LOCK);
300 } 296 }
301 /* 297 /*
302 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect 298 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
@@ -338,7 +334,7 @@ static void acpi_processor_idle(void)
338 * detection phase, to work cleanly with logical CPU hotplug. 334 * detection phase, to work cleanly with logical CPU hotplug.
339 */ 335 */
340 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 336 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
341 !pr->flags.has_cst && !acpi_fadt.plvl2_up) 337 !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
342 cx = &pr->power.states[ACPI_STATE_C1]; 338 cx = &pr->power.states[ACPI_STATE_C1];
343#endif 339#endif
344 340
@@ -384,11 +380,11 @@ static void acpi_processor_idle(void)
384 380
385 case ACPI_STATE_C2: 381 case ACPI_STATE_C2:
386 /* Get start time (ticks) */ 382 /* Get start time (ticks) */
387 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 383 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
388 /* Invoke C2 */ 384 /* Invoke C2 */
389 acpi_cstate_enter(cx); 385 acpi_cstate_enter(cx);
390 /* Get end time (ticks) */ 386 /* Get end time (ticks) */
391 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 387 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
392 388
393#ifdef CONFIG_GENERIC_TIME 389#ifdef CONFIG_GENERIC_TIME
394 /* TSC halts in C2, so notify users */ 390 /* TSC halts in C2, so notify users */
@@ -411,8 +407,7 @@ static void acpi_processor_idle(void)
411 * All CPUs are trying to go to C3 407 * All CPUs are trying to go to C3
412 * Disable bus master arbitration 408 * Disable bus master arbitration
413 */ 409 */
414 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, 410 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
415 ACPI_MTX_DO_NOT_LOCK);
416 } 411 }
417 } else { 412 } else {
418 /* SMP with no shared cache... Invalidate cache */ 413 /* SMP with no shared cache... Invalidate cache */
@@ -420,16 +415,15 @@ static void acpi_processor_idle(void)
420 } 415 }
421 416
422 /* Get start time (ticks) */ 417 /* Get start time (ticks) */
423 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 418 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
424 /* Invoke C3 */ 419 /* Invoke C3 */
425 acpi_cstate_enter(cx); 420 acpi_cstate_enter(cx);
426 /* Get end time (ticks) */ 421 /* Get end time (ticks) */
427 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 422 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
428 if (pr->flags.bm_check) { 423 if (pr->flags.bm_check) {
429 /* Enable bus master arbitration */ 424 /* Enable bus master arbitration */
430 atomic_dec(&c3_cpu_count); 425 atomic_dec(&c3_cpu_count);
431 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, 426 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
432 ACPI_MTX_DO_NOT_LOCK);
433 } 427 }
434 428
435#ifdef CONFIG_GENERIC_TIME 429#ifdef CONFIG_GENERIC_TIME
@@ -457,7 +451,7 @@ static void acpi_processor_idle(void)
457#ifdef CONFIG_HOTPLUG_CPU 451#ifdef CONFIG_HOTPLUG_CPU
458 /* Don't do promotion/demotion */ 452 /* Don't do promotion/demotion */
459 if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && 453 if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
460 !pr->flags.has_cst && !acpi_fadt.plvl2_up) { 454 !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
461 next_state = cx; 455 next_state = cx;
462 goto end; 456 goto end;
463 } 457 }
@@ -627,7 +621,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
627 * Check for P_LVL2_UP flag before entering C2 and above on 621 * Check for P_LVL2_UP flag before entering C2 and above on
628 * an SMP system. 622 * an SMP system.
629 */ 623 */
630 if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up) 624 if ((num_online_cpus() > 1) &&
625 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
631 return -ENODEV; 626 return -ENODEV;
632#endif 627#endif
633 628
@@ -636,8 +631,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
636 pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; 631 pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
637 632
638 /* determine latencies from FADT */ 633 /* determine latencies from FADT */
639 pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; 634 pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
640 pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; 635 pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
641 636
642 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 637 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
643 "lvl2[0x%08x] lvl3[0x%08x]\n", 638 "lvl2[0x%08x] lvl3[0x%08x]\n",
@@ -883,14 +878,13 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
883 * WBINVD should be set in fadt, for C3 state to be 878 * WBINVD should be set in fadt, for C3 state to be
884 * supported on when bm_check is not required. 879 * supported on when bm_check is not required.
885 */ 880 */
886 if (acpi_fadt.wb_invd != 1) { 881 if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) {
887 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 882 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
888 "Cache invalidation should work properly" 883 "Cache invalidation should work properly"
889 " for C3 to be enabled on SMP systems\n")); 884 " for C3 to be enabled on SMP systems\n"));
890 return; 885 return;
891 } 886 }
892 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 887 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
893 0, ACPI_MTX_DO_NOT_LOCK);
894 } 888 }
895 889
896 /* 890 /*
@@ -1096,7 +1090,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1096 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", 1090 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n",
1097 pr->power.states[i].latency, 1091 pr->power.states[i].latency,
1098 pr->power.states[i].usage, 1092 pr->power.states[i].usage,
1099 pr->power.states[i].time); 1093 (unsigned long long)pr->power.states[i].time);
1100 } 1094 }
1101 1095
1102 end: 1096 end:
@@ -1164,9 +1158,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1164 if (!pr) 1158 if (!pr)
1165 return -EINVAL; 1159 return -EINVAL;
1166 1160
1167 if (acpi_fadt.cst_cnt && !nocst) { 1161 if (acpi_gbl_FADT.cst_control && !nocst) {
1168 status = 1162 status =
1169 acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8); 1163 acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8);
1170 if (ACPI_FAILURE(status)) { 1164 if (ACPI_FAILURE(status)) {
1171 ACPI_EXCEPTION((AE_INFO, status, 1165 ACPI_EXCEPTION((AE_INFO, status,
1172 "Notifying BIOS of _CST ability failed")); 1166 "Notifying BIOS of _CST ability failed"));
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index cbb6f0814ce2..058f13cf3b79 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -352,31 +352,24 @@ int acpi_processor_notify_smm(struct module *calling_module)
352 352
353 is_done = -EIO; 353 is_done = -EIO;
354 354
355 /* Can't write pstate_cnt to smi_cmd if either value is zero */ 355 /* Can't write pstate_control to smi_command if either value is zero */
356 if ((!acpi_fadt.smi_cmd) || (!acpi_fadt.pstate_cnt)) { 356 if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) {
357 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_cnt\n")); 357 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n"));
358 module_put(calling_module); 358 module_put(calling_module);
359 return 0; 359 return 0;
360 } 360 }
361 361
362 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 362 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
363 "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", 363 "Writing pstate_control [0x%x] to smi_command [0x%x]\n",
364 acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd)); 364 acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
365 365
366 /* FADT v1 doesn't support pstate_cnt, many BIOS vendors use 366 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
367 * it anyway, so we need to support it... */ 367 (u32) acpi_gbl_FADT.pstate_control, 8);
368 if (acpi_fadt_is_v1) {
369 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
370 "Using v1.0 FADT reserved value for pstate_cnt\n"));
371 }
372
373 status = acpi_os_write_port(acpi_fadt.smi_cmd,
374 (u32) acpi_fadt.pstate_cnt, 8);
375 if (ACPI_FAILURE(status)) { 368 if (ACPI_FAILURE(status)) {
376 ACPI_EXCEPTION((AE_INFO, status, 369 ACPI_EXCEPTION((AE_INFO, status,
377 "Failed to write pstate_cnt [0x%x] to " 370 "Failed to write pstate_control [0x%x] to "
378 "smi_cmd [0x%x]", acpi_fadt.pstate_cnt, 371 "smi_command [0x%x]", acpi_gbl_FADT.pstate_control,
379 acpi_fadt.smi_cmd)); 372 acpi_gbl_FADT.smi_command));
380 module_put(calling_module); 373 module_put(calling_module);
381 return status; 374 return status;
382 } 375 }
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 0ec7dcde0063..89dff3639abe 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -125,7 +125,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
125 /* Used to clear all duty_value bits */ 125 /* Used to clear all duty_value bits */
126 duty_mask = pr->throttling.state_count - 1; 126 duty_mask = pr->throttling.state_count - 1;
127 127
128 duty_mask <<= acpi_fadt.duty_offset; 128 duty_mask <<= acpi_gbl_FADT.duty_offset;
129 duty_mask = ~duty_mask; 129 duty_mask = ~duty_mask;
130 } 130 }
131 131
@@ -208,7 +208,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
208 return 0; 208 return 0;
209 } 209 }
210 210
211 pr->throttling.state_count = 1 << acpi_fadt.duty_width; 211 pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
212 212
213 /* 213 /*
214 * Compute state values. Note that throttling displays a linear power/ 214 * Compute state values. Note that throttling displays a linear power/
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 8fa3213ce000..271e61509eeb 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index cf87b0230026..8c6d3fdec38a 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 008058acdd39..1358c06a969c 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index 9c99a723a860..de20a5d6decf 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c
index 9e7ae2f8a1d3..7e3c335ab320 100644
--- a/drivers/acpi/resources/rsinfo.c
+++ b/drivers/acpi/resources/rsinfo.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index ea567167c4f2..b297bc3e4419 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 1fa63bc2e36f..5657f7b95039 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index 29423ce030ca..a92755c8877d 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index a5131936d690..521eab7dd8df 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index faf6e106b785..3b63b561b94e 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index a9cbee8e8b44..2442a8f8df57 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 1999e2ab7daa..991f8901498c 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 283d87522c5d..64f26db10c8e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -21,101 +21,305 @@ extern struct acpi_device *acpi_root;
21#define ACPI_BUS_DEVICE_NAME "System Bus" 21#define ACPI_BUS_DEVICE_NAME "System Bus"
22 22
23static LIST_HEAD(acpi_device_list); 23static LIST_HEAD(acpi_device_list);
24static LIST_HEAD(acpi_bus_id_list);
24DEFINE_SPINLOCK(acpi_device_lock); 25DEFINE_SPINLOCK(acpi_device_lock);
25LIST_HEAD(acpi_wakeup_device_list); 26LIST_HEAD(acpi_wakeup_device_list);
26 27
28struct acpi_device_bus_id{
29 char bus_id[15];
30 unsigned int instance_no;
31 struct list_head node;
32};
33static int acpi_eject_operation(acpi_handle handle, int lockable)
34{
35 struct acpi_object_list arg_list;
36 union acpi_object arg;
37 acpi_status status = AE_OK;
38
39 /*
40 * TBD: evaluate _PS3?
41 */
42
43 if (lockable) {
44 arg_list.count = 1;
45 arg_list.pointer = &arg;
46 arg.type = ACPI_TYPE_INTEGER;
47 arg.integer.value = 0;
48 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
49 }
50
51 arg_list.count = 1;
52 arg_list.pointer = &arg;
53 arg.type = ACPI_TYPE_INTEGER;
54 arg.integer.value = 1;
55
56 /*
57 * TBD: _EJD support.
58 */
59
60 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
61 if (ACPI_FAILURE(status)) {
62 return (-ENODEV);
63 }
64
65 return (0);
66}
27 67
28static void acpi_device_release(struct kobject *kobj) 68static ssize_t
69acpi_eject_store(struct device *d, struct device_attribute *attr,
70 const char *buf, size_t count)
29{ 71{
30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); 72 int result;
31 kfree(dev->pnp.cid_list); 73 int ret = count;
32 kfree(dev); 74 int islockable;
75 acpi_status status;
76 acpi_handle handle;
77 acpi_object_type type = 0;
78 struct acpi_device *acpi_device = to_acpi_device(d);
79
80 if ((!count) || (buf[0] != '1')) {
81 return -EINVAL;
82 }
83#ifndef FORCE_EJECT
84 if (acpi_device->driver == NULL) {
85 ret = -ENODEV;
86 goto err;
87 }
88#endif
89 status = acpi_get_type(acpi_device->handle, &type);
90 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
91 ret = -ENODEV;
92 goto err;
93 }
94
95 islockable = acpi_device->flags.lockable;
96 handle = acpi_device->handle;
97
98 result = acpi_bus_trim(acpi_device, 1);
99
100 if (!result)
101 result = acpi_eject_operation(handle, islockable);
102
103 if (result) {
104 ret = -EBUSY;
105 }
106 err:
107 return ret;
33} 108}
34 109
35struct acpi_device_attribute { 110static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
36 struct attribute attr; 111
37 ssize_t(*show) (struct acpi_device *, char *); 112static ssize_t
38 ssize_t(*store) (struct acpi_device *, const char *, size_t); 113acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
39}; 114 struct acpi_device *acpi_dev = to_acpi_device(dev);
115
116 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
117}
118static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
119
120static ssize_t
121acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
122 struct acpi_device *acpi_dev = to_acpi_device(dev);
123 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
124 int result;
125
126 result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
127 if(result)
128 goto end;
129
130 result = sprintf(buf, "%s\n", (char*)path.pointer);
131 kfree(path.pointer);
132 end:
133 return result;
134}
135static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
136
137static int acpi_device_setup_files(struct acpi_device *dev)
138{
139 acpi_status status;
140 acpi_handle temp;
141 int result = 0;
142
143 /*
144 * Devices gotten from FADT don't have a "path" attribute
145 */
146 if(dev->handle) {
147 result = device_create_file(&dev->dev, &dev_attr_path);
148 if(result)
149 goto end;
150 }
40 151
41typedef void acpi_device_sysfs_files(struct kobject *, 152 if(dev->flags.hardware_id) {
42 const struct attribute *); 153 result = device_create_file(&dev->dev, &dev_attr_hid);
154 if(result)
155 goto end;
156 }
43 157
44static void setup_sys_fs_device_files(struct acpi_device *dev, 158 /*
45 acpi_device_sysfs_files * func); 159 * If device has _EJ0, 'eject' file is created that is used to trigger
160 * hot-removal function from userland.
161 */
162 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
163 if (ACPI_SUCCESS(status))
164 result = device_create_file(&dev->dev, &dev_attr_eject);
165 end:
166 return result;
167}
46 168
47#define create_sysfs_device_files(dev) \ 169static void acpi_device_remove_files(struct acpi_device *dev)
48 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file) 170{
49#define remove_sysfs_device_files(dev) \ 171 acpi_status status;
50 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file) 172 acpi_handle temp;
51 173
52#define to_acpi_device(n) container_of(n, struct acpi_device, kobj) 174 /*
53#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr); 175 * If device has _EJ0, 'eject' file is created that is used to trigger
176 * hot-removal function from userland.
177 */
178 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
179 if (ACPI_SUCCESS(status))
180 device_remove_file(&dev->dev, &dev_attr_eject);
54 181
55static ssize_t acpi_device_attr_show(struct kobject *kobj, 182 if(dev->flags.hardware_id)
56 struct attribute *attr, char *buf) 183 device_remove_file(&dev->dev, &dev_attr_hid);
184 if(dev->handle)
185 device_remove_file(&dev->dev, &dev_attr_path);
186}
187/* --------------------------------------------------------------------------
188 ACPI Bus operations
189 -------------------------------------------------------------------------- */
190static void acpi_device_release(struct device *dev)
57{ 191{
58 struct acpi_device *device = to_acpi_device(kobj); 192 struct acpi_device *acpi_dev = to_acpi_device(dev);
59 struct acpi_device_attribute *attribute = to_handle_attr(attr); 193
60 return attribute->show ? attribute->show(device, buf) : -EIO; 194 kfree(acpi_dev->pnp.cid_list);
195 kfree(acpi_dev);
61} 196}
62static ssize_t acpi_device_attr_store(struct kobject *kobj, 197
63 struct attribute *attr, const char *buf, 198static int acpi_device_suspend(struct device *dev, pm_message_t state)
64 size_t len)
65{ 199{
66 struct acpi_device *device = to_acpi_device(kobj); 200 struct acpi_device *acpi_dev = to_acpi_device(dev);
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 201 struct acpi_driver *acpi_drv = acpi_dev->driver;
68 return attribute->store ? attribute->store(device, buf, len) : -EIO; 202
203 if (acpi_drv && acpi_drv->ops.suspend)
204 return acpi_drv->ops.suspend(acpi_dev, state);
205 return 0;
69} 206}
70 207
71static struct sysfs_ops acpi_device_sysfs_ops = { 208static int acpi_device_resume(struct device *dev)
72 .show = acpi_device_attr_show, 209{
73 .store = acpi_device_attr_store, 210 struct acpi_device *acpi_dev = to_acpi_device(dev);
74}; 211 struct acpi_driver *acpi_drv = acpi_dev->driver;
75 212
76static struct kobj_type ktype_acpi_ns = { 213 if (acpi_drv && acpi_drv->ops.resume)
77 .sysfs_ops = &acpi_device_sysfs_ops, 214 return acpi_drv->ops.resume(acpi_dev);
78 .release = acpi_device_release, 215 return 0;
79}; 216}
80 217
81static int namespace_uevent(struct kset *kset, struct kobject *kobj, 218static int acpi_bus_match(struct device *dev, struct device_driver *drv)
82 char **envp, int num_envp, char *buffer,
83 int buffer_size)
84{ 219{
85 struct acpi_device *dev = to_acpi_device(kobj); 220 struct acpi_device *acpi_dev = to_acpi_device(dev);
86 int i = 0; 221 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
87 int len = 0;
88 222
89 if (!dev->driver) 223 return !acpi_match_ids(acpi_dev, acpi_drv->ids);
90 return 0; 224}
91 225
92 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 226static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
93 "PHYSDEVDRIVER=%s", dev->driver->name)) 227 char *buffer, int buffer_size)
228{
229 struct acpi_device *acpi_dev = to_acpi_device(dev);
230 int i = 0, length = 0, ret = 0;
231
232 if (acpi_dev->flags.hardware_id)
233 ret = add_uevent_var(envp, num_envp, &i,
234 buffer, buffer_size, &length,
235 "HWID=%s", acpi_dev->pnp.hardware_id);
236 if (ret)
94 return -ENOMEM; 237 return -ENOMEM;
238 if (acpi_dev->flags.compatible_ids) {
239 int j;
240 struct acpi_compatible_id_list *cid_list;
241
242 cid_list = acpi_dev->pnp.cid_list;
243
244 for (j = 0; j < cid_list->count; j++) {
245 ret = add_uevent_var(envp, num_envp, &i, buffer,
246 buffer_size, &length, "COMPTID=%s",
247 cid_list->id[j].value);
248 if (ret)
249 return -ENOMEM;
250 }
251 }
95 252
96 envp[i] = NULL; 253 envp[i] = NULL;
254 return 0;
255}
256
257static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
258static int acpi_start_single_object(struct acpi_device *);
259static int acpi_device_probe(struct device * dev)
260{
261 struct acpi_device *acpi_dev = to_acpi_device(dev);
262 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
263 int ret;
264
265 ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
266 if (!ret) {
267 if (acpi_dev->bus_ops.acpi_op_start)
268 acpi_start_single_object(acpi_dev);
269 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
270 "Found driver [%s] for device [%s]\n",
271 acpi_drv->name, acpi_dev->pnp.bus_id));
272 get_device(dev);
273 }
274 return ret;
275}
97 276
277static int acpi_device_remove(struct device * dev)
278{
279 struct acpi_device *acpi_dev = to_acpi_device(dev);
280 struct acpi_driver *acpi_drv = acpi_dev->driver;
281
282 if (acpi_drv) {
283 if (acpi_drv->ops.stop)
284 acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
285 if (acpi_drv->ops.remove)
286 acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
287 }
288 acpi_dev->driver = NULL;
289 acpi_driver_data(dev) = NULL;
290
291 put_device(dev);
98 return 0; 292 return 0;
99} 293}
100 294
101static struct kset_uevent_ops namespace_uevent_ops = { 295static void acpi_device_shutdown(struct device *dev)
102 .uevent = &namespace_uevent, 296{
103}; 297 struct acpi_device *acpi_dev = to_acpi_device(dev);
298 struct acpi_driver *acpi_drv = acpi_dev->driver;
299
300 if (acpi_drv && acpi_drv->ops.shutdown)
301 acpi_drv->ops.shutdown(acpi_dev);
104 302
105static struct kset acpi_namespace_kset = { 303 return ;
106 .kobj = { 304}
107 .name = "namespace", 305
108 }, 306static struct bus_type acpi_bus_type = {
109 .subsys = &acpi_subsys, 307 .name = "acpi",
110 .ktype = &ktype_acpi_ns, 308 .suspend = acpi_device_suspend,
111 .uevent_ops = &namespace_uevent_ops, 309 .resume = acpi_device_resume,
310 .shutdown = acpi_device_shutdown,
311 .match = acpi_bus_match,
312 .probe = acpi_device_probe,
313 .remove = acpi_device_remove,
314 .uevent = acpi_device_uevent,
112}; 315};
113 316
114static void acpi_device_register(struct acpi_device *device, 317static int acpi_device_register(struct acpi_device *device,
115 struct acpi_device *parent) 318 struct acpi_device *parent)
116{ 319{
117 int err; 320 int result;
118 321 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
322 int found = 0;
119 /* 323 /*
120 * Linkage 324 * Linkage
121 * ------- 325 * -------
@@ -126,7 +330,33 @@ static void acpi_device_register(struct acpi_device *device,
126 INIT_LIST_HEAD(&device->g_list); 330 INIT_LIST_HEAD(&device->g_list);
127 INIT_LIST_HEAD(&device->wakeup_list); 331 INIT_LIST_HEAD(&device->wakeup_list);
128 332
333 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
334 if (!new_bus_id) {
335 printk(KERN_ERR PREFIX "Memory allocation error\n");
336 return -ENOMEM;
337 }
338
129 spin_lock(&acpi_device_lock); 339 spin_lock(&acpi_device_lock);
340 /*
341 * Find suitable bus_id and instance number in acpi_bus_id_list
342 * If failed, create one and link it into acpi_bus_id_list
343 */
344 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
345 if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) {
346 acpi_device_bus_id->instance_no ++;
347 found = 1;
348 kfree(new_bus_id);
349 break;
350 }
351 }
352 if(!found) {
353 acpi_device_bus_id = new_bus_id;
354 strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
355 acpi_device_bus_id->instance_no = 0;
356 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
357 }
358 sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
359
130 if (device->parent) { 360 if (device->parent) {
131 list_add_tail(&device->node, &device->parent->children); 361 list_add_tail(&device->node, &device->parent->children);
132 list_add_tail(&device->g_list, &device->parent->g_list); 362 list_add_tail(&device->g_list, &device->parent->g_list);
@@ -136,16 +366,33 @@ static void acpi_device_register(struct acpi_device *device,
136 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); 366 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
137 spin_unlock(&acpi_device_lock); 367 spin_unlock(&acpi_device_lock);
138 368
139 strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN); 369 if (device->parent)
140 if (parent) 370 device->dev.parent = &parent->dev;
141 device->kobj.parent = &parent->kobj; 371 device->dev.bus = &acpi_bus_type;
142 device->kobj.ktype = &ktype_acpi_ns; 372 device_initialize(&device->dev);
143 device->kobj.kset = &acpi_namespace_kset; 373 device->dev.release = &acpi_device_release;
144 err = kobject_register(&device->kobj); 374 result = device_add(&device->dev);
145 if (err < 0) 375 if(result) {
146 printk(KERN_WARNING "%s: kobject_register error: %d\n", 376 printk("Error adding device %s", device->dev.bus_id);
147 __FUNCTION__, err); 377 goto end;
148 create_sysfs_device_files(device); 378 }
379
380 result = acpi_device_setup_files(device);
381 if(result)
382 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
383
384 device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
385 return 0;
386 end:
387 spin_lock(&acpi_device_lock);
388 if (device->parent) {
389 list_del(&device->node);
390 list_del(&device->g_list);
391 } else
392 list_del(&device->g_list);
393 list_del(&device->wakeup_list);
394 spin_unlock(&acpi_device_lock);
395 return result;
149} 396}
150 397
151static void acpi_device_unregister(struct acpi_device *device, int type) 398static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -158,81 +405,143 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
158 list_del(&device->g_list); 405 list_del(&device->g_list);
159 406
160 list_del(&device->wakeup_list); 407 list_del(&device->wakeup_list);
161
162 spin_unlock(&acpi_device_lock); 408 spin_unlock(&acpi_device_lock);
163 409
164 acpi_detach_data(device->handle, acpi_bus_data_handler); 410 acpi_detach_data(device->handle, acpi_bus_data_handler);
165 remove_sysfs_device_files(device); 411
166 kobject_unregister(&device->kobj); 412 acpi_device_remove_files(device);
413 device_unregister(&device->dev);
167} 414}
168 415
169void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 416/* --------------------------------------------------------------------------
417 Driver Management
418 -------------------------------------------------------------------------- */
419/**
420 * acpi_bus_driver_init - add a device to a driver
421 * @device: the device to add and initialize
422 * @driver: driver for the device
423 *
424 * Used to initialize a device via its device driver. Called whenever a
425 * driver is bound to a device. Invokes the driver's add() ops.
426 */
427static int
428acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
170{ 429{
430 int result = 0;
171 431
172 /* TBD */
173 432
174 return; 433 if (!device || !driver)
175} 434 return -EINVAL;
176 435
177static int acpi_bus_get_power_flags(struct acpi_device *device) 436 if (!driver->ops.add)
178{ 437 return -ENOSYS;
179 acpi_status status = 0;
180 acpi_handle handle = NULL;
181 u32 i = 0;
182 438
439 result = driver->ops.add(device);
440 if (result) {
441 device->driver = NULL;
442 acpi_driver_data(device) = NULL;
443 return result;
444 }
183 445
184 /* 446 device->driver = driver;
185 * Power Management Flags
186 */
187 status = acpi_get_handle(device->handle, "_PSC", &handle);
188 if (ACPI_SUCCESS(status))
189 device->power.flags.explicit_get = 1;
190 status = acpi_get_handle(device->handle, "_IRC", &handle);
191 if (ACPI_SUCCESS(status))
192 device->power.flags.inrush_current = 1;
193 447
194 /* 448 /*
195 * Enumerate supported power management states 449 * TBD - Configuration Management: Assign resources to device based
450 * upon possible configuration and currently allocated resources.
196 */ 451 */
197 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
198 struct acpi_device_power_state *ps = &device->power.states[i];
199 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
200 452
201 /* Evaluate "_PRx" to se if power resources are referenced */ 453 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
202 acpi_evaluate_reference(device->handle, object_name, NULL, 454 "Driver successfully bound to device\n"));
203 &ps->resources); 455 return 0;
204 if (ps->resources.count) { 456}
205 device->power.flags.power_resources = 1;
206 ps->flags.valid = 1;
207 }
208 457
209 /* Evaluate "_PSx" to see if we can do explicit sets */ 458static int acpi_start_single_object(struct acpi_device *device)
210 object_name[2] = 'S'; 459{
211 status = acpi_get_handle(device->handle, object_name, &handle); 460 int result = 0;
212 if (ACPI_SUCCESS(status)) { 461 struct acpi_driver *driver;
213 ps->flags.explicit_set = 1;
214 ps->flags.valid = 1;
215 }
216 462
217 /* State is valid if we have some power control */
218 if (ps->resources.count || ps->flags.explicit_set)
219 ps->flags.valid = 1;
220 463
221 ps->power = -1; /* Unknown - driver assigned */ 464 if (!(driver = device->driver))
222 ps->latency = -1; /* Unknown - driver assigned */ 465 return 0;
466
467 if (driver->ops.start) {
468 result = driver->ops.start(device);
469 if (result && driver->ops.remove)
470 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
223 } 471 }
224 472
225 /* Set defaults for D0 and D3 states (always valid) */ 473 return result;
226 device->power.states[ACPI_STATE_D0].flags.valid = 1; 474}
227 device->power.states[ACPI_STATE_D0].power = 100;
228 device->power.states[ACPI_STATE_D3].flags.valid = 1;
229 device->power.states[ACPI_STATE_D3].power = 0;
230 475
231 /* TBD: System wake support and resource requirements. */ 476/**
477 * acpi_bus_register_driver - register a driver with the ACPI bus
478 * @driver: driver being registered
479 *
480 * Registers a driver with the ACPI bus. Searches the namespace for all
481 * devices that match the driver's criteria and binds. Returns zero for
482 * success or a negative error status for failure.
483 */
484int acpi_bus_register_driver(struct acpi_driver *driver)
485{
486 int ret;
232 487
233 device->power.state = ACPI_STATE_UNKNOWN; 488 if (acpi_disabled)
489 return -ENODEV;
490 driver->drv.name = driver->name;
491 driver->drv.bus = &acpi_bus_type;
492 driver->drv.owner = driver->owner;
234 493
235 return 0; 494 ret = driver_register(&driver->drv);
495 return ret;
496}
497
498EXPORT_SYMBOL(acpi_bus_register_driver);
499
500/**
501 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
502 * @driver: driver to unregister
503 *
504 * Unregisters a driver with the ACPI bus. Searches the namespace for all
505 * devices that match the driver's criteria and unbinds.
506 */
507void acpi_bus_unregister_driver(struct acpi_driver *driver)
508{
509 driver_unregister(&driver->drv);
510}
511
512EXPORT_SYMBOL(acpi_bus_unregister_driver);
513
514/* --------------------------------------------------------------------------
515 Device Enumeration
516 -------------------------------------------------------------------------- */
517acpi_status
518acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
519{
520 acpi_status status;
521 acpi_handle tmp;
522 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
523 union acpi_object *obj;
524
525 status = acpi_get_handle(handle, "_EJD", &tmp);
526 if (ACPI_FAILURE(status))
527 return status;
528
529 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
530 if (ACPI_SUCCESS(status)) {
531 obj = buffer.pointer;
532 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
533 kfree(buffer.pointer);
534 }
535 return status;
536}
537EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
538
539void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
540{
541
542 /* TBD */
543
544 return;
236} 545}
237 546
238int acpi_match_ids(struct acpi_device *device, char *ids) 547int acpi_match_ids(struct acpi_device *device, char *ids)
@@ -254,6 +563,12 @@ int acpi_match_ids(struct acpi_device *device, char *ids)
254 return -ENOENT; 563 return -ENOENT;
255} 564}
256 565
566static int acpi_bus_get_perf_flags(struct acpi_device *device)
567{
568 device->performance.state = ACPI_STATE_UNKNOWN;
569 return 0;
570}
571
257static acpi_status 572static acpi_status
258acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 573acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
259 union acpi_object *package) 574 union acpi_object *package)
@@ -338,359 +653,66 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
338 return 0; 653 return 0;
339} 654}
340 655
341/* -------------------------------------------------------------------------- 656static int acpi_bus_get_power_flags(struct acpi_device *device)
342 ACPI sysfs device file support
343 -------------------------------------------------------------------------- */
344static ssize_t acpi_eject_store(struct acpi_device *device,
345 const char *buf, size_t count);
346
347#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
348static struct acpi_device_attribute acpi_device_attr_##_name = \
349 __ATTR(_name, _mode, _show, _store)
350
351ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
352
353/**
354 * setup_sys_fs_device_files - sets up the device files under device namespace
355 * @dev: acpi_device object
356 * @func: function pointer to create or destroy the device file
357 */
358static void
359setup_sys_fs_device_files(struct acpi_device *dev,
360 acpi_device_sysfs_files * func)
361{
362 acpi_status status;
363 acpi_handle temp = NULL;
364
365 /*
366 * If device has _EJ0, 'eject' file is created that is used to trigger
367 * hot-removal function from userland.
368 */
369 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
370 if (ACPI_SUCCESS(status))
371 (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
372}
373
374static int acpi_eject_operation(acpi_handle handle, int lockable)
375{ 657{
376 struct acpi_object_list arg_list; 658 acpi_status status = 0;
377 union acpi_object arg; 659 acpi_handle handle = NULL;
378 acpi_status status = AE_OK; 660 u32 i = 0;
379
380 /*
381 * TBD: evaluate _PS3?
382 */
383
384 if (lockable) {
385 arg_list.count = 1;
386 arg_list.pointer = &arg;
387 arg.type = ACPI_TYPE_INTEGER;
388 arg.integer.value = 0;
389 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
390 }
391 661
392 arg_list.count = 1;
393 arg_list.pointer = &arg;
394 arg.type = ACPI_TYPE_INTEGER;
395 arg.integer.value = 1;
396 662
397 /* 663 /*
398 * TBD: _EJD support. 664 * Power Management Flags
399 */ 665 */
400 666 status = acpi_get_handle(device->handle, "_PSC", &handle);
401 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); 667 if (ACPI_SUCCESS(status))
402 if (ACPI_FAILURE(status)) { 668 device->power.flags.explicit_get = 1;
403 return (-ENODEV); 669 status = acpi_get_handle(device->handle, "_IRC", &handle);
404 } 670 if (ACPI_SUCCESS(status))
405 671 device->power.flags.inrush_current = 1;
406 return (0);
407}
408
409static ssize_t
410acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
411{
412 int result;
413 int ret = count;
414 int islockable;
415 acpi_status status;
416 acpi_handle handle;
417 acpi_object_type type = 0;
418
419 if ((!count) || (buf[0] != '1')) {
420 return -EINVAL;
421 }
422#ifndef FORCE_EJECT
423 if (device->driver == NULL) {
424 ret = -ENODEV;
425 goto err;
426 }
427#endif
428 status = acpi_get_type(device->handle, &type);
429 if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
430 ret = -ENODEV;
431 goto err;
432 }
433
434 islockable = device->flags.lockable;
435 handle = device->handle;
436
437 result = acpi_bus_trim(device, 1);
438
439 if (!result)
440 result = acpi_eject_operation(handle, islockable);
441
442 if (result) {
443 ret = -EBUSY;
444 }
445 err:
446 return ret;
447}
448
449/* --------------------------------------------------------------------------
450 Performance Management
451 -------------------------------------------------------------------------- */
452
453static int acpi_bus_get_perf_flags(struct acpi_device *device)
454{
455 device->performance.state = ACPI_STATE_UNKNOWN;
456 return 0;
457}
458
459/* --------------------------------------------------------------------------
460 Driver Management
461 -------------------------------------------------------------------------- */
462
463static LIST_HEAD(acpi_bus_drivers);
464
465/**
466 * acpi_bus_match - match device IDs to driver's supported IDs
467 * @device: the device that we are trying to match to a driver
468 * @driver: driver whose device id table is being checked
469 *
470 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
471 * matches the specified driver's criteria.
472 */
473static int
474acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
475{
476 if (driver && driver->ops.match)
477 return driver->ops.match(device, driver);
478 return acpi_match_ids(device, driver->ids);
479}
480
481/**
482 * acpi_bus_driver_init - add a device to a driver
483 * @device: the device to add and initialize
484 * @driver: driver for the device
485 *
486 * Used to initialize a device via its device driver. Called whenever a
487 * driver is bound to a device. Invokes the driver's add() and start() ops.
488 */
489static int
490acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
491{
492 int result = 0;
493
494
495 if (!device || !driver)
496 return -EINVAL;
497
498 if (!driver->ops.add)
499 return -ENOSYS;
500
501 result = driver->ops.add(device);
502 if (result) {
503 device->driver = NULL;
504 acpi_driver_data(device) = NULL;
505 return result;
506 }
507
508 device->driver = driver;
509 672
510 /* 673 /*
511 * TBD - Configuration Management: Assign resources to device based 674 * Enumerate supported power management states
512 * upon possible configuration and currently allocated resources.
513 */ 675 */
676 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
677 struct acpi_device_power_state *ps = &device->power.states[i];
678 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
514 679
515 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 680 /* Evaluate "_PRx" to se if power resources are referenced */
516 "Driver successfully bound to device\n")); 681 acpi_evaluate_reference(device->handle, object_name, NULL,
517 return 0; 682 &ps->resources);
518} 683 if (ps->resources.count) {
519 684 device->power.flags.power_resources = 1;
520static int acpi_start_single_object(struct acpi_device *device) 685 ps->flags.valid = 1;
521{
522 int result = 0;
523 struct acpi_driver *driver;
524
525
526 if (!(driver = device->driver))
527 return 0;
528
529 if (driver->ops.start) {
530 result = driver->ops.start(device);
531 if (result && driver->ops.remove)
532 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
533 }
534
535 return result;
536}
537
538static void acpi_driver_attach(struct acpi_driver *drv)
539{
540 struct list_head *node, *next;
541
542
543 spin_lock(&acpi_device_lock);
544 list_for_each_safe(node, next, &acpi_device_list) {
545 struct acpi_device *dev =
546 container_of(node, struct acpi_device, g_list);
547
548 if (dev->driver || !dev->status.present)
549 continue;
550 spin_unlock(&acpi_device_lock);
551
552 if (!acpi_bus_match(dev, drv)) {
553 if (!acpi_bus_driver_init(dev, drv)) {
554 acpi_start_single_object(dev);
555 atomic_inc(&drv->references);
556 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
557 "Found driver [%s] for device [%s]\n",
558 drv->name, dev->pnp.bus_id));
559 }
560 } 686 }
561 spin_lock(&acpi_device_lock);
562 }
563 spin_unlock(&acpi_device_lock);
564}
565
566static void acpi_driver_detach(struct acpi_driver *drv)
567{
568 struct list_head *node, *next;
569 687
570 688 /* Evaluate "_PSx" to see if we can do explicit sets */
571 spin_lock(&acpi_device_lock); 689 object_name[2] = 'S';
572 list_for_each_safe(node, next, &acpi_device_list) { 690 status = acpi_get_handle(device->handle, object_name, &handle);
573 struct acpi_device *dev = 691 if (ACPI_SUCCESS(status)) {
574 container_of(node, struct acpi_device, g_list); 692 ps->flags.explicit_set = 1;
575 693 ps->flags.valid = 1;
576 if (dev->driver == drv) {
577 spin_unlock(&acpi_device_lock);
578 if (drv->ops.remove)
579 drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
580 spin_lock(&acpi_device_lock);
581 dev->driver = NULL;
582 dev->driver_data = NULL;
583 atomic_dec(&drv->references);
584 } 694 }
585 }
586 spin_unlock(&acpi_device_lock);
587}
588
589/**
590 * acpi_bus_register_driver - register a driver with the ACPI bus
591 * @driver: driver being registered
592 *
593 * Registers a driver with the ACPI bus. Searches the namespace for all
594 * devices that match the driver's criteria and binds. Returns zero for
595 * success or a negative error status for failure.
596 */
597int acpi_bus_register_driver(struct acpi_driver *driver)
598{
599
600 if (acpi_disabled)
601 return -ENODEV;
602
603 spin_lock(&acpi_device_lock);
604 list_add_tail(&driver->node, &acpi_bus_drivers);
605 spin_unlock(&acpi_device_lock);
606 acpi_driver_attach(driver);
607
608 return 0;
609}
610
611EXPORT_SYMBOL(acpi_bus_register_driver);
612
613/**
614 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
615 * @driver: driver to unregister
616 *
617 * Unregisters a driver with the ACPI bus. Searches the namespace for all
618 * devices that match the driver's criteria and unbinds.
619 */
620void acpi_bus_unregister_driver(struct acpi_driver *driver)
621{
622 acpi_driver_detach(driver);
623
624 if (!atomic_read(&driver->references)) {
625 spin_lock(&acpi_device_lock);
626 list_del_init(&driver->node);
627 spin_unlock(&acpi_device_lock);
628 }
629 return;
630}
631
632EXPORT_SYMBOL(acpi_bus_unregister_driver);
633
634/**
635 * acpi_bus_find_driver - check if there is a driver installed for the device
636 * @device: device that we are trying to find a supporting driver for
637 *
638 * Parses the list of registered drivers looking for a driver applicable for
639 * the specified device.
640 */
641static int acpi_bus_find_driver(struct acpi_device *device)
642{
643 int result = 0;
644 struct list_head *node, *next;
645 695
696 /* State is valid if we have some power control */
697 if (ps->resources.count || ps->flags.explicit_set)
698 ps->flags.valid = 1;
646 699
647 spin_lock(&acpi_device_lock); 700 ps->power = -1; /* Unknown - driver assigned */
648 list_for_each_safe(node, next, &acpi_bus_drivers) { 701 ps->latency = -1; /* Unknown - driver assigned */
649 struct acpi_driver *driver =
650 container_of(node, struct acpi_driver, node);
651
652 atomic_inc(&driver->references);
653 spin_unlock(&acpi_device_lock);
654 if (!acpi_bus_match(device, driver)) {
655 result = acpi_bus_driver_init(device, driver);
656 if (!result)
657 goto Done;
658 }
659 atomic_dec(&driver->references);
660 spin_lock(&acpi_device_lock);
661 } 702 }
662 spin_unlock(&acpi_device_lock);
663
664 Done:
665 return result;
666}
667 703
668/* -------------------------------------------------------------------------- 704 /* Set defaults for D0 and D3 states (always valid) */
669 Device Enumeration 705 device->power.states[ACPI_STATE_D0].flags.valid = 1;
670 -------------------------------------------------------------------------- */ 706 device->power.states[ACPI_STATE_D0].power = 100;
707 device->power.states[ACPI_STATE_D3].flags.valid = 1;
708 device->power.states[ACPI_STATE_D3].power = 0;
671 709
672acpi_status 710 /* TBD: System wake support and resource requirements. */
673acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
674{
675 acpi_status status;
676 acpi_handle tmp;
677 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
678 union acpi_object *obj;
679 711
680 status = acpi_get_handle(handle, "_EJD", &tmp); 712 device->power.state = ACPI_STATE_UNKNOWN;
681 if (ACPI_FAILURE(status))
682 return status;
683 713
684 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); 714 return 0;
685 if (ACPI_SUCCESS(status)) {
686 obj = buffer.pointer;
687 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
688 kfree(buffer.pointer);
689 }
690 return status;
691} 715}
692EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
693
694 716
695static int acpi_bus_get_flags(struct acpi_device *device) 717static int acpi_bus_get_flags(struct acpi_device *device)
696{ 718{
@@ -782,6 +804,75 @@ static void acpi_device_get_busid(struct acpi_device *device,
782 } 804 }
783} 805}
784 806
807static int
808acpi_video_bus_match(struct acpi_device *device)
809{
810 acpi_handle h_dummy1;
811 acpi_handle h_dummy2;
812 acpi_handle h_dummy3;
813
814
815 if (!device)
816 return -EINVAL;
817
818 /* Since there is no HID, CID for ACPI Video drivers, we have
819 * to check well known required nodes for each feature we support.
820 */
821
822 /* Does this device able to support video switching ? */
823 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
824 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
825 return 0;
826
827 /* Does this device able to retrieve a video ROM ? */
828 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
829 return 0;
830
831 /* Does this device able to configure which video head to be POSTed ? */
832 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
833 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
834 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
835 return 0;
836
837 return -ENODEV;
838}
839
840/*
841 * acpi_bay_match - see if a device is an ejectable driver bay
842 *
843 * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
844 * then we can safely call it an ejectable drive bay
845 */
846static int acpi_bay_match(struct acpi_device *device){
847 acpi_status status;
848 acpi_handle handle;
849 acpi_handle tmp;
850 acpi_handle phandle;
851
852 handle = device->handle;
853
854 status = acpi_get_handle(handle, "_EJ0", &tmp);
855 if (ACPI_FAILURE(status))
856 return -ENODEV;
857
858 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
859 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
860 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
861 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
862 return 0;
863
864 if (acpi_get_parent(handle, &phandle))
865 return -ENODEV;
866
867 if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) ||
868 (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) ||
869 (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) ||
870 (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp))))
871 return 0;
872
873 return -ENODEV;
874}
875
785static void acpi_device_set_id(struct acpi_device *device, 876static void acpi_device_set_id(struct acpi_device *device,
786 struct acpi_device *parent, acpi_handle handle, 877 struct acpi_device *parent, acpi_handle handle,
787 int type) 878 int type)
@@ -812,6 +903,16 @@ static void acpi_device_set_id(struct acpi_device *device,
812 device->pnp.bus_address = info->address; 903 device->pnp.bus_address = info->address;
813 device->flags.bus_address = 1; 904 device->flags.bus_address = 1;
814 } 905 }
906
907 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
908 status = acpi_video_bus_match(device);
909 if(ACPI_SUCCESS(status))
910 hid = ACPI_VIDEO_HID;
911
912 status = acpi_bay_match(device);
913 if (ACPI_SUCCESS(status))
914 hid = ACPI_BAY_HID;
915 }
815 break; 916 break;
816 case ACPI_BUS_TYPE_POWER: 917 case ACPI_BUS_TYPE_POWER:
817 hid = ACPI_POWER_HID; 918 hid = ACPI_POWER_HID;
@@ -888,86 +989,24 @@ static int acpi_device_set_context(struct acpi_device *device, int type)
888 return result; 989 return result;
889} 990}
890 991
891static void acpi_device_get_debug_info(struct acpi_device *device,
892 acpi_handle handle, int type)
893{
894#ifdef CONFIG_ACPI_DEBUG_OUTPUT
895 char *type_string = NULL;
896 char name[80] = { '?', '\0' };
897 struct acpi_buffer buffer = { sizeof(name), name };
898
899 switch (type) {
900 case ACPI_BUS_TYPE_DEVICE:
901 type_string = "Device";
902 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
903 break;
904 case ACPI_BUS_TYPE_POWER:
905 type_string = "Power Resource";
906 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
907 break;
908 case ACPI_BUS_TYPE_PROCESSOR:
909 type_string = "Processor";
910 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
911 break;
912 case ACPI_BUS_TYPE_SYSTEM:
913 type_string = "System";
914 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
915 break;
916 case ACPI_BUS_TYPE_THERMAL:
917 type_string = "Thermal Zone";
918 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
919 break;
920 case ACPI_BUS_TYPE_POWER_BUTTON:
921 type_string = "Power Button";
922 sprintf(name, "PWRB");
923 break;
924 case ACPI_BUS_TYPE_SLEEP_BUTTON:
925 type_string = "Sleep Button";
926 sprintf(name, "SLPB");
927 break;
928 }
929
930 printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
931#endif /*CONFIG_ACPI_DEBUG_OUTPUT */
932}
933
934static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 992static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
935{ 993{
936 int result = 0;
937 struct acpi_driver *driver;
938
939
940 if (!dev) 994 if (!dev)
941 return -EINVAL; 995 return -EINVAL;
942 996
943 driver = dev->driver; 997 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
944 998 device_release_driver(&dev->dev);
945 if ((driver) && (driver->ops.remove)) {
946
947 if (driver->ops.stop) {
948 result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
949 if (result)
950 return result;
951 }
952
953 result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
954 if (result) {
955 return result;
956 }
957
958 atomic_dec(&dev->driver->references);
959 dev->driver = NULL;
960 acpi_driver_data(dev) = NULL;
961 }
962 999
963 if (!rmdevice) 1000 if (!rmdevice)
964 return 0; 1001 return 0;
965 1002
1003 /*
1004 * unbind _ADR-Based Devices when hot removal
1005 */
966 if (dev->flags.bus_address) { 1006 if (dev->flags.bus_address) {
967 if ((dev->parent) && (dev->parent->ops.unbind)) 1007 if ((dev->parent) && (dev->parent->ops.unbind))
968 dev->parent->ops.unbind(dev); 1008 dev->parent->ops.unbind(dev);
969 } 1009 }
970
971 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); 1010 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
972 1011
973 return 0; 1012 return 0;
@@ -975,7 +1014,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
975 1014
976static int 1015static int
977acpi_add_single_object(struct acpi_device **child, 1016acpi_add_single_object(struct acpi_device **child,
978 struct acpi_device *parent, acpi_handle handle, int type) 1017 struct acpi_device *parent, acpi_handle handle, int type,
1018 struct acpi_bus_ops *ops)
979{ 1019{
980 int result = 0; 1020 int result = 0;
981 struct acpi_device *device = NULL; 1021 struct acpi_device *device = NULL;
@@ -992,6 +1032,8 @@ acpi_add_single_object(struct acpi_device **child,
992 1032
993 device->handle = handle; 1033 device->handle = handle;
994 device->parent = parent; 1034 device->parent = parent;
1035 device->bus_ops = *ops; /* workround for not call .start */
1036
995 1037
996 acpi_device_get_busid(device, handle, type); 1038 acpi_device_get_busid(device, handle, type);
997 1039
@@ -1076,33 +1118,16 @@ acpi_add_single_object(struct acpi_device **child,
1076 if ((result = acpi_device_set_context(device, type))) 1118 if ((result = acpi_device_set_context(device, type)))
1077 goto end; 1119 goto end;
1078 1120
1079 acpi_device_get_debug_info(device, handle, type); 1121 result = acpi_device_register(device, parent);
1080
1081 acpi_device_register(device, parent);
1082 1122
1083 /* 1123 /*
1084 * Bind _ADR-Based Devices 1124 * Bind _ADR-Based Devices when hot add
1085 * -----------------------
1086 * If there's a a bus address (_ADR) then we utilize the parent's
1087 * 'bind' function (if exists) to bind the ACPI- and natively-
1088 * enumerated device representations.
1089 */ 1125 */
1090 if (device->flags.bus_address) { 1126 if (device->flags.bus_address) {
1091 if (device->parent && device->parent->ops.bind) 1127 if (device->parent && device->parent->ops.bind)
1092 device->parent->ops.bind(device); 1128 device->parent->ops.bind(device);
1093 } 1129 }
1094 1130
1095 /*
1096 * Locate & Attach Driver
1097 * ----------------------
1098 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1099 * to see if there's a driver installed for this kind of device. Note
1100 * that drivers can install before or after a device is enumerated.
1101 *
1102 * TBD: Assumes LDM provides driver hot-plug capability.
1103 */
1104 acpi_bus_find_driver(device);
1105
1106 end: 1131 end:
1107 if (!result) 1132 if (!result)
1108 *child = device; 1133 *child = device;
@@ -1188,14 +1213,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1188 1213
1189 if (ops->acpi_op_add) 1214 if (ops->acpi_op_add)
1190 status = acpi_add_single_object(&child, parent, 1215 status = acpi_add_single_object(&child, parent,
1191 chandle, type); 1216 chandle, type, ops);
1192 else 1217 else
1193 status = acpi_bus_get_device(chandle, &child); 1218 status = acpi_bus_get_device(chandle, &child);
1194 1219
1195 if (ACPI_FAILURE(status)) 1220 if (ACPI_FAILURE(status))
1196 continue; 1221 continue;
1197 1222
1198 if (ops->acpi_op_start) { 1223 if (ops->acpi_op_start && !(ops->acpi_op_add)) {
1199 status = acpi_start_single_object(child); 1224 status = acpi_start_single_object(child);
1200 if (ACPI_FAILURE(status)) 1225 if (ACPI_FAILURE(status))
1201 continue; 1226 continue;
@@ -1233,13 +1258,13 @@ acpi_bus_add(struct acpi_device **child,
1233 int result; 1258 int result;
1234 struct acpi_bus_ops ops; 1259 struct acpi_bus_ops ops;
1235 1260
1261 memset(&ops, 0, sizeof(ops));
1262 ops.acpi_op_add = 1;
1236 1263
1237 result = acpi_add_single_object(child, parent, handle, type); 1264 result = acpi_add_single_object(child, parent, handle, type, &ops);
1238 if (!result) { 1265 if (!result)
1239 memset(&ops, 0, sizeof(ops));
1240 ops.acpi_op_add = 1;
1241 result = acpi_bus_scan(*child, &ops); 1266 result = acpi_bus_scan(*child, &ops);
1242 } 1267
1243 return result; 1268 return result;
1244} 1269}
1245 1270
@@ -1325,127 +1350,35 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1325{ 1350{
1326 int result = 0; 1351 int result = 0;
1327 struct acpi_device *device = NULL; 1352 struct acpi_device *device = NULL;
1328 1353 struct acpi_bus_ops ops;
1329 1354
1330 if (!root) 1355 if (!root)
1331 return -ENODEV; 1356 return -ENODEV;
1332 1357
1358 memset(&ops, 0, sizeof(ops));
1359 ops.acpi_op_add = 1;
1360 ops.acpi_op_start = 1;
1361
1333 /* 1362 /*
1334 * Enumerate all fixed-feature devices. 1363 * Enumerate all fixed-feature devices.
1335 */ 1364 */
1336 if (acpi_fadt.pwr_button == 0) { 1365 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
1337 result = acpi_add_single_object(&device, acpi_root, 1366 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, 1367 NULL,
1339 ACPI_BUS_TYPE_POWER_BUTTON); 1368 ACPI_BUS_TYPE_POWER_BUTTON,
1340 if (!result) 1369 &ops);
1341 result = acpi_start_single_object(device);
1342 } 1370 }
1343 1371
1344 if (acpi_fadt.sleep_button == 0) { 1372 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1345 result = acpi_add_single_object(&device, acpi_root, 1373 result = acpi_add_single_object(&device, acpi_root,
1346 NULL, 1374 NULL,
1347 ACPI_BUS_TYPE_SLEEP_BUTTON); 1375 ACPI_BUS_TYPE_SLEEP_BUTTON,
1348 if (!result) 1376 &ops);
1349 result = acpi_start_single_object(device);
1350 } 1377 }
1351 1378
1352 return result; 1379 return result;
1353} 1380}
1354 1381
1355
1356static inline struct acpi_device * to_acpi_dev(struct device * dev)
1357{
1358 return container_of(dev, struct acpi_device, dev);
1359}
1360
1361
1362static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
1363{
1364 struct acpi_device * dev, * next;
1365 int result;
1366
1367 spin_lock(&acpi_device_lock);
1368 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
1369 if (dev->driver && dev->driver->ops.suspend) {
1370 spin_unlock(&acpi_device_lock);
1371 result = dev->driver->ops.suspend(dev, 0);
1372 if (result) {
1373 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
1374 acpi_device_name(dev),
1375 acpi_device_bid(dev), result);
1376 }
1377 spin_lock(&acpi_device_lock);
1378 }
1379 }
1380 spin_unlock(&acpi_device_lock);
1381 return 0;
1382}
1383
1384
1385static int acpi_device_suspend(struct device * dev, pm_message_t state)
1386{
1387 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1388
1389 /*
1390 * For now, we should only register 1 generic device -
1391 * the ACPI root device - and from there, we walk the
1392 * tree of ACPI devices to suspend each one using the
1393 * ACPI driver methods.
1394 */
1395 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1396 root_suspend(acpi_dev, state);
1397 return 0;
1398}
1399
1400
1401
1402static int root_resume(struct acpi_device * acpi_dev)
1403{
1404 struct acpi_device * dev, * next;
1405 int result;
1406
1407 spin_lock(&acpi_device_lock);
1408 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
1409 if (dev->driver && dev->driver->ops.resume) {
1410 spin_unlock(&acpi_device_lock);
1411 result = dev->driver->ops.resume(dev, 0);
1412 if (result) {
1413 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
1414 acpi_device_name(dev),
1415 acpi_device_bid(dev), result);
1416 }
1417 spin_lock(&acpi_device_lock);
1418 }
1419 }
1420 spin_unlock(&acpi_device_lock);
1421 return 0;
1422}
1423
1424
1425static int acpi_device_resume(struct device * dev)
1426{
1427 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1428
1429 /*
1430 * For now, we should only register 1 generic device -
1431 * the ACPI root device - and from there, we walk the
1432 * tree of ACPI devices to resume each one using the
1433 * ACPI driver methods.
1434 */
1435 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1436 root_resume(acpi_dev);
1437 return 0;
1438}
1439
1440
1441static struct bus_type acpi_bus_type = {
1442 .name = "acpi",
1443 .suspend = acpi_device_suspend,
1444 .resume = acpi_device_resume,
1445};
1446
1447
1448
1449static int __init acpi_scan_init(void) 1382static int __init acpi_scan_init(void)
1450{ 1383{
1451 int result; 1384 int result;
@@ -1455,9 +1388,9 @@ static int __init acpi_scan_init(void)
1455 if (acpi_disabled) 1388 if (acpi_disabled)
1456 return 0; 1389 return 0;
1457 1390
1458 result = kset_register(&acpi_namespace_kset); 1391 memset(&ops, 0, sizeof(ops));
1459 if (result < 0) 1392 ops.acpi_op_add = 1;
1460 printk(KERN_ERR PREFIX "kset_register error: %d\n", result); 1393 ops.acpi_op_start = 1;
1461 1394
1462 result = bus_register(&acpi_bus_type); 1395 result = bus_register(&acpi_bus_type);
1463 if (result) { 1396 if (result) {
@@ -1469,32 +1402,16 @@ static int __init acpi_scan_init(void)
1469 * Create the root device in the bus's device tree 1402 * Create the root device in the bus's device tree
1470 */ 1403 */
1471 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1404 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1472 ACPI_BUS_TYPE_SYSTEM); 1405 ACPI_BUS_TYPE_SYSTEM, &ops);
1473 if (result) 1406 if (result)
1474 goto Done; 1407 goto Done;
1475 1408
1476 result = acpi_start_single_object(acpi_root);
1477 if (result)
1478 goto Done;
1479
1480 acpi_root->dev.bus = &acpi_bus_type;
1481 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1482 result = device_register(&acpi_root->dev);
1483 if (result) {
1484 /* We don't want to quit even if we failed to add suspend/resume */
1485 printk(KERN_ERR PREFIX "Could not register device\n");
1486 }
1487
1488 /* 1409 /*
1489 * Enumerate devices in the ACPI namespace. 1410 * Enumerate devices in the ACPI namespace.
1490 */ 1411 */
1491 result = acpi_bus_scan_fixed(acpi_root); 1412 result = acpi_bus_scan_fixed(acpi_root);
1492 if (!result) { 1413 if (!result)
1493 memset(&ops, 0, sizeof(ops));
1494 ops.acpi_op_add = 1;
1495 ops.acpi_op_start = 1;
1496 result = acpi_bus_scan(acpi_root, &ops); 1414 result = acpi_bus_scan(acpi_root, &ops);
1497 }
1498 1415
1499 if (result) 1416 if (result)
1500 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1417 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 34962578039d..ccc11b33d89c 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -73,7 +73,7 @@ acpi_system_write_sleep(struct file *file,
73static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) 73static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
74{ 74{
75 u32 sec, min, hr; 75 u32 sec, min, hr;
76 u32 day, mo, yr; 76 u32 day, mo, yr, cent = 0;
77 unsigned char rtc_control = 0; 77 unsigned char rtc_control = 0;
78 unsigned long flags; 78 unsigned long flags;
79 79
@@ -87,20 +87,19 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
87 rtc_control = CMOS_READ(RTC_CONTROL); 87 rtc_control = CMOS_READ(RTC_CONTROL);
88 88
89 /* If we ever get an FACP with proper values... */ 89 /* If we ever get an FACP with proper values... */
90 if (acpi_gbl_FADT->day_alrm) 90 if (acpi_gbl_FADT.day_alarm)
91 /* ACPI spec: only low 6 its should be cared */ 91 /* ACPI spec: only low 6 its should be cared */
92 day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F; 92 day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F;
93 else 93 else
94 day = CMOS_READ(RTC_DAY_OF_MONTH); 94 day = CMOS_READ(RTC_DAY_OF_MONTH);
95 if (acpi_gbl_FADT->mon_alrm) 95 if (acpi_gbl_FADT.month_alarm)
96 mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); 96 mo = CMOS_READ(acpi_gbl_FADT.month_alarm);
97 else 97 else
98 mo = CMOS_READ(RTC_MONTH); 98 mo = CMOS_READ(RTC_MONTH);
99 if (acpi_gbl_FADT->century) 99 if (acpi_gbl_FADT.century)
100 yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + 100 cent = CMOS_READ(acpi_gbl_FADT.century);
101 CMOS_READ(RTC_YEAR); 101
102 else 102 yr = CMOS_READ(RTC_YEAR);
103 yr = CMOS_READ(RTC_YEAR);
104 103
105 spin_unlock_irqrestore(&rtc_lock, flags); 104 spin_unlock_irqrestore(&rtc_lock, flags);
106 105
@@ -111,10 +110,11 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
111 BCD_TO_BIN(day); 110 BCD_TO_BIN(day);
112 BCD_TO_BIN(mo); 111 BCD_TO_BIN(mo);
113 BCD_TO_BIN(yr); 112 BCD_TO_BIN(yr);
113 BCD_TO_BIN(cent);
114 } 114 }
115 115
116 /* we're trusting the FADT (see above) */ 116 /* we're trusting the FADT (see above) */
117 if (!acpi_gbl_FADT->century) 117 if (!acpi_gbl_FADT.century)
118 /* If we're not trusting the FADT, we should at least make it 118 /* If we're not trusting the FADT, we should at least make it
119 * right for _this_ century... ehm, what is _this_ century? 119 * right for _this_ century... ehm, what is _this_ century?
120 * 120 *
@@ -134,6 +134,8 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
134 * 134 *
135 */ 135 */
136 yr += 2000; 136 yr += 2000;
137 else
138 yr += cent * 100;
137 139
138 seq_printf(seq, "%4.4u-", yr); 140 seq_printf(seq, "%4.4u-", yr);
139 (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); 141 (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
@@ -317,12 +319,12 @@ acpi_system_write_alarm(struct file *file,
317 * offsets into the CMOS RAM here -- which for some reason are pointing 319 * offsets into the CMOS RAM here -- which for some reason are pointing
318 * to the RTC area of memory. 320 * to the RTC area of memory.
319 */ 321 */
320 if (acpi_gbl_FADT->day_alrm) 322 if (acpi_gbl_FADT.day_alarm)
321 CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); 323 CMOS_WRITE(day, acpi_gbl_FADT.day_alarm);
322 if (acpi_gbl_FADT->mon_alrm) 324 if (acpi_gbl_FADT.month_alarm)
323 CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); 325 CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm);
324 if (acpi_gbl_FADT->century) 326 if (acpi_gbl_FADT.century)
325 CMOS_WRITE(yr / 100, acpi_gbl_FADT->century); 327 CMOS_WRITE(yr / 100, acpi_gbl_FADT.century);
326 /* enable the rtc alarm interrupt */ 328 /* enable the rtc alarm interrupt */
327 rtc_control |= RTC_AIE; 329 rtc_control |= RTC_AIE;
328 CMOS_WRITE(rtc_control, RTC_CONTROL); 330 CMOS_WRITE(rtc_control, RTC_CONTROL);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index d86dcb3c2366..7147b0bdab0a 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -32,6 +32,11 @@
32 32
33#define _COMPONENT ACPI_SYSTEM_COMPONENT 33#define _COMPONENT ACPI_SYSTEM_COMPONENT
34ACPI_MODULE_NAME("acpi_system") 34ACPI_MODULE_NAME("acpi_system")
35#ifdef MODULE_PARAM_PREFIX
36#undef MODULE_PARAM_PREFIX
37#endif
38#define MODULE_PARAM_PREFIX "acpi."
39
35#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
36#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver" 41#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver"
37#define ACPI_SYSTEM_DEVICE_NAME "System" 42#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -39,11 +44,24 @@ ACPI_MODULE_NAME("acpi_system")
39#define ACPI_SYSTEM_FILE_EVENT "event" 44#define ACPI_SYSTEM_FILE_EVENT "event"
40#define ACPI_SYSTEM_FILE_DSDT "dsdt" 45#define ACPI_SYSTEM_FILE_DSDT "dsdt"
41#define ACPI_SYSTEM_FILE_FADT "fadt" 46#define ACPI_SYSTEM_FILE_FADT "fadt"
42extern struct fadt_descriptor acpi_fadt; 47
48/*
49 * Make ACPICA version work as module param
50 */
51static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
52 int result;
53
54 result = sprintf(buffer, "%x", ACPI_CA_VERSION);
55
56 return result;
57}
58
59module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
43 60
44/* -------------------------------------------------------------------------- 61/* --------------------------------------------------------------------------
45 FS Interface (/proc) 62 FS Interface (/proc)
46 -------------------------------------------------------------------------- */ 63 -------------------------------------------------------------------------- */
64#ifdef CONFIG_ACPI_PROCFS
47 65
48static int acpi_system_read_info(struct seq_file *seq, void *offset) 66static int acpi_system_read_info(struct seq_file *seq, void *offset)
49{ 67{
@@ -63,6 +81,7 @@ static const struct file_operations acpi_system_info_ops = {
63 .llseek = seq_lseek, 81 .llseek = seq_lseek,
64 .release = single_release, 82 .release = single_release,
65}; 83};
84#endif
66 85
67static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, 86static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
68 loff_t *); 87 loff_t *);
@@ -76,17 +95,16 @@ acpi_system_read_dsdt(struct file *file,
76 char __user * buffer, size_t count, loff_t * ppos) 95 char __user * buffer, size_t count, loff_t * ppos)
77{ 96{
78 acpi_status status = AE_OK; 97 acpi_status status = AE_OK;
79 struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; 98 struct acpi_table_header *dsdt = NULL;
80 ssize_t res; 99 ssize_t res;
81 100
82 101
83 status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); 102 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
84 if (ACPI_FAILURE(status)) 103 if (ACPI_FAILURE(status))
85 return -ENODEV; 104 return -ENODEV;
86 105
87 res = simple_read_from_buffer(buffer, count, ppos, 106 res = simple_read_from_buffer(buffer, count, ppos,
88 dsdt.pointer, dsdt.length); 107 dsdt, dsdt->length);
89 kfree(dsdt.pointer);
90 108
91 return res; 109 return res;
92} 110}
@@ -103,17 +121,16 @@ acpi_system_read_fadt(struct file *file,
103 char __user * buffer, size_t count, loff_t * ppos) 121 char __user * buffer, size_t count, loff_t * ppos)
104{ 122{
105 acpi_status status = AE_OK; 123 acpi_status status = AE_OK;
106 struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL }; 124 struct acpi_table_header *fadt = NULL;
107 ssize_t res; 125 ssize_t res;
108 126
109 127
110 status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt); 128 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
111 if (ACPI_FAILURE(status)) 129 if (ACPI_FAILURE(status))
112 return -ENODEV; 130 return -ENODEV;
113 131
114 res = simple_read_from_buffer(buffer, count, ppos, 132 res = simple_read_from_buffer(buffer, count, ppos,
115 fadt.pointer, fadt.length); 133 fadt, fadt->length);
116 kfree(fadt.pointer);
117 134
118 return res; 135 return res;
119} 136}
@@ -128,6 +145,7 @@ static int __init acpi_system_init(void)
128 if (acpi_disabled) 145 if (acpi_disabled)
129 return 0; 146 return 0;
130 147
148#ifdef CONFIG_ACPI_PROCFS
131 /* 'info' [R] */ 149 /* 'info' [R] */
132 name = ACPI_SYSTEM_FILE_INFO; 150 name = ACPI_SYSTEM_FILE_INFO;
133 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); 151 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -136,6 +154,7 @@ static int __init acpi_system_init(void)
136 else { 154 else {
137 entry->proc_fops = &acpi_system_info_ops; 155 entry->proc_fops = &acpi_system_info_ops;
138 } 156 }
157#endif
139 158
140 /* 'dsdt' [R] */ 159 /* 'dsdt' [R] */
141 name = ACPI_SYSTEM_FILE_DSDT; 160 name = ACPI_SYSTEM_FILE_DSDT;
@@ -159,7 +178,9 @@ static int __init acpi_system_init(void)
159 Error: 178 Error:
160 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); 179 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
161 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); 180 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
181#ifdef CONFIG_ACPI_PROCFS
162 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); 182 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
183#endif
163 184
164 error = -EFAULT; 185 error = -EFAULT;
165 goto Done; 186 goto Done;
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index ffa30c9fccbf..ba4cb200314a 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -38,154 +38,97 @@
38 38
39#define ACPI_MAX_TABLES 128 39#define ACPI_MAX_TABLES 128
40 40
41static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
42 [ACPI_TABLE_UNKNOWN] = "????",
43 [ACPI_APIC] = "APIC",
44 [ACPI_BOOT] = "BOOT",
45 [ACPI_DBGP] = "DBGP",
46 [ACPI_DSDT] = "DSDT",
47 [ACPI_ECDT] = "ECDT",
48 [ACPI_ETDT] = "ETDT",
49 [ACPI_FADT] = "FACP",
50 [ACPI_FACS] = "FACS",
51 [ACPI_OEMX] = "OEM",
52 [ACPI_PSDT] = "PSDT",
53 [ACPI_SBST] = "SBST",
54 [ACPI_SLIT] = "SLIT",
55 [ACPI_SPCR] = "SPCR",
56 [ACPI_SRAT] = "SRAT",
57 [ACPI_SSDT] = "SSDT",
58 [ACPI_SPMI] = "SPMI",
59 [ACPI_HPET] = "HPET",
60 [ACPI_MCFG] = "MCFG",
61};
62
63static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; 41static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
64static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; 42static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
65 43
66/* System Description Table (RSDT/XSDT) */ 44static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
67struct acpi_table_sdt {
68 unsigned long pa;
69 enum acpi_table_id id;
70 unsigned long size;
71} __attribute__ ((packed));
72
73static unsigned long sdt_pa; /* Physical Address */
74static unsigned long sdt_count; /* Table count */
75 45
76static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata; 46void acpi_table_print_madt_entry(struct acpi_subtable_header * header)
77
78void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr)
79{
80 char *name = NULL;
81
82 if (!header)
83 return;
84
85 /* Some table signatures aren't good table names */
86
87 if (!strncmp((char *)&header->signature,
88 acpi_table_signatures[ACPI_APIC],
89 sizeof(header->signature))) {
90 name = "MADT";
91 } else if (!strncmp((char *)&header->signature,
92 acpi_table_signatures[ACPI_FADT],
93 sizeof(header->signature))) {
94 name = "FADT";
95 } else
96 name = header->signature;
97
98 printk(KERN_DEBUG PREFIX
99 "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", name,
100 header->revision, header->oem_id, header->oem_table_id,
101 header->oem_revision, header->asl_compiler_id,
102 header->asl_compiler_revision, (void *)phys_addr);
103}
104
105void acpi_table_print_madt_entry(acpi_table_entry_header * header)
106{ 47{
107 if (!header) 48 if (!header)
108 return; 49 return;
109 50
110 switch (header->type) { 51 switch (header->type) {
111 52
112 case ACPI_MADT_LAPIC: 53 case ACPI_MADT_TYPE_LOCAL_APIC:
113 { 54 {
114 struct acpi_table_lapic *p = 55 struct acpi_madt_local_apic *p =
115 (struct acpi_table_lapic *)header; 56 (struct acpi_madt_local_apic *)header;
116 printk(KERN_INFO PREFIX 57 printk(KERN_INFO PREFIX
117 "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", 58 "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
118 p->acpi_id, p->id, 59 p->processor_id, p->id,
119 p->flags.enabled ? "enabled" : "disabled"); 60 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
120 } 61 }
121 break; 62 break;
122 63
123 case ACPI_MADT_IOAPIC: 64 case ACPI_MADT_TYPE_IO_APIC:
124 { 65 {
125 struct acpi_table_ioapic *p = 66 struct acpi_madt_io_apic *p =
126 (struct acpi_table_ioapic *)header; 67 (struct acpi_madt_io_apic *)header;
127 printk(KERN_INFO PREFIX 68 printk(KERN_INFO PREFIX
128 "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", 69 "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
129 p->id, p->address, p->global_irq_base); 70 p->id, p->address, p->global_irq_base);
130 } 71 }
131 break; 72 break;
132 73
133 case ACPI_MADT_INT_SRC_OVR: 74 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
134 { 75 {
135 struct acpi_table_int_src_ovr *p = 76 struct acpi_madt_interrupt_override *p =
136 (struct acpi_table_int_src_ovr *)header; 77 (struct acpi_madt_interrupt_override *)header;
137 printk(KERN_INFO PREFIX 78 printk(KERN_INFO PREFIX
138 "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", 79 "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
139 p->bus, p->bus_irq, p->global_irq, 80 p->bus, p->source_irq, p->global_irq,
140 mps_inti_flags_polarity[p->flags.polarity], 81 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
141 mps_inti_flags_trigger[p->flags.trigger]); 82 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]);
142 if (p->flags.reserved) 83 if (p->inti_flags &
84 ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK))
143 printk(KERN_INFO PREFIX 85 printk(KERN_INFO PREFIX
144 "INT_SRC_OVR unexpected reserved flags: 0x%x\n", 86 "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
145 p->flags.reserved); 87 p->inti_flags &
88 ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK));
146 89
147 } 90 }
148 break; 91 break;
149 92
150 case ACPI_MADT_NMI_SRC: 93 case ACPI_MADT_TYPE_NMI_SOURCE:
151 { 94 {
152 struct acpi_table_nmi_src *p = 95 struct acpi_madt_nmi_source *p =
153 (struct acpi_table_nmi_src *)header; 96 (struct acpi_madt_nmi_source *)header;
154 printk(KERN_INFO PREFIX 97 printk(KERN_INFO PREFIX
155 "NMI_SRC (%s %s global_irq %d)\n", 98 "NMI_SRC (%s %s global_irq %d)\n",
156 mps_inti_flags_polarity[p->flags.polarity], 99 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
157 mps_inti_flags_trigger[p->flags.trigger], 100 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
158 p->global_irq); 101 p->global_irq);
159 } 102 }
160 break; 103 break;
161 104
162 case ACPI_MADT_LAPIC_NMI: 105 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
163 { 106 {
164 struct acpi_table_lapic_nmi *p = 107 struct acpi_madt_local_apic_nmi *p =
165 (struct acpi_table_lapic_nmi *)header; 108 (struct acpi_madt_local_apic_nmi *)header;
166 printk(KERN_INFO PREFIX 109 printk(KERN_INFO PREFIX
167 "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", 110 "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
168 p->acpi_id, 111 p->processor_id,
169 mps_inti_flags_polarity[p->flags.polarity], 112 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ],
170 mps_inti_flags_trigger[p->flags.trigger], 113 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
171 p->lint); 114 p->lint);
172 } 115 }
173 break; 116 break;
174 117
175 case ACPI_MADT_LAPIC_ADDR_OVR: 118 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
176 { 119 {
177 struct acpi_table_lapic_addr_ovr *p = 120 struct acpi_madt_local_apic_override *p =
178 (struct acpi_table_lapic_addr_ovr *)header; 121 (struct acpi_madt_local_apic_override *)header;
179 printk(KERN_INFO PREFIX 122 printk(KERN_INFO PREFIX
180 "LAPIC_ADDR_OVR (address[%p])\n", 123 "LAPIC_ADDR_OVR (address[%p])\n",
181 (void *)(unsigned long)p->address); 124 (void *)(unsigned long)p->address);
182 } 125 }
183 break; 126 break;
184 127
185 case ACPI_MADT_IOSAPIC: 128 case ACPI_MADT_TYPE_IO_SAPIC:
186 { 129 {
187 struct acpi_table_iosapic *p = 130 struct acpi_madt_io_sapic *p =
188 (struct acpi_table_iosapic *)header; 131 (struct acpi_madt_io_sapic *)header;
189 printk(KERN_INFO PREFIX 132 printk(KERN_INFO PREFIX
190 "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", 133 "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
191 p->id, (void *)(unsigned long)p->address, 134 p->id, (void *)(unsigned long)p->address,
@@ -193,26 +136,26 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
193 } 136 }
194 break; 137 break;
195 138
196 case ACPI_MADT_LSAPIC: 139 case ACPI_MADT_TYPE_LOCAL_SAPIC:
197 { 140 {
198 struct acpi_table_lsapic *p = 141 struct acpi_madt_local_sapic *p =
199 (struct acpi_table_lsapic *)header; 142 (struct acpi_madt_local_sapic *)header;
200 printk(KERN_INFO PREFIX 143 printk(KERN_INFO PREFIX
201 "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", 144 "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
202 p->acpi_id, p->id, p->eid, 145 p->processor_id, p->id, p->eid,
203 p->flags.enabled ? "enabled" : "disabled"); 146 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
204 } 147 }
205 break; 148 break;
206 149
207 case ACPI_MADT_PLAT_INT_SRC: 150 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
208 { 151 {
209 struct acpi_table_plat_int_src *p = 152 struct acpi_madt_interrupt_source *p =
210 (struct acpi_table_plat_int_src *)header; 153 (struct acpi_madt_interrupt_source *)header;
211 printk(KERN_INFO PREFIX 154 printk(KERN_INFO PREFIX
212 "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", 155 "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
213 mps_inti_flags_polarity[p->flags.polarity], 156 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
214 mps_inti_flags_trigger[p->flags.trigger], 157 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
215 p->type, p->id, p->eid, p->iosapic_vector, 158 p->type, p->id, p->eid, p->io_sapic_vector,
216 p->global_irq); 159 p->global_irq);
217 } 160 }
218 break; 161 break;
@@ -225,342 +168,76 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
225 } 168 }
226} 169}
227 170
228static int
229acpi_table_compute_checksum(void *table_pointer, unsigned long length)
230{
231 u8 *p = table_pointer;
232 unsigned long remains = length;
233 unsigned long sum = 0;
234
235 if (!p || !length)
236 return -EINVAL;
237
238 while (remains--)
239 sum += *p++;
240
241 return (sum & 0xFF);
242}
243 171
244/*
245 * acpi_get_table_header_early()
246 * for acpi_blacklisted(), acpi_table_get_sdt()
247 */
248int __init 172int __init
249acpi_get_table_header_early(enum acpi_table_id id, 173acpi_table_parse_madt_family(char *id,
250 struct acpi_table_header **header)
251{
252 unsigned int i;
253 enum acpi_table_id temp_id;
254
255 /* DSDT is different from the rest */
256 if (id == ACPI_DSDT)
257 temp_id = ACPI_FADT;
258 else
259 temp_id = id;
260
261 /* Locate the table. */
262
263 for (i = 0; i < sdt_count; i++) {
264 if (sdt_entry[i].id != temp_id)
265 continue;
266 *header = (void *)
267 __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
268 if (!*header) {
269 printk(KERN_WARNING PREFIX "Unable to map %s\n",
270 acpi_table_signatures[temp_id]);
271 return -ENODEV;
272 }
273 break;
274 }
275
276 if (!*header) {
277 printk(KERN_WARNING PREFIX "%s not present\n",
278 acpi_table_signatures[id]);
279 return -ENODEV;
280 }
281
282 /* Map the DSDT header via the pointer in the FADT */
283 if (id == ACPI_DSDT) {
284 struct fadt_descriptor *fadt =
285 (struct fadt_descriptor *)*header;
286
287 if (fadt->revision == 3 && fadt->Xdsdt) {
288 *header = (void *)__acpi_map_table(fadt->Xdsdt,
289 sizeof(struct
290 acpi_table_header));
291 } else if (fadt->V1_dsdt) {
292 *header = (void *)__acpi_map_table(fadt->V1_dsdt,
293 sizeof(struct
294 acpi_table_header));
295 } else
296 *header = NULL;
297
298 if (!*header) {
299 printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
300 return -ENODEV;
301 }
302 }
303
304 return 0;
305}
306
307int __init
308acpi_table_parse_madt_family(enum acpi_table_id id,
309 unsigned long madt_size, 174 unsigned long madt_size,
310 int entry_id, 175 int entry_id,
311 acpi_madt_entry_handler handler, 176 acpi_madt_entry_handler handler,
312 unsigned int max_entries) 177 unsigned int max_entries)
313{ 178{
314 void *madt = NULL; 179 struct acpi_table_header *madt = NULL;
315 acpi_table_entry_header *entry; 180 struct acpi_subtable_header *entry;
316 unsigned int count = 0; 181 unsigned int count = 0;
317 unsigned long madt_end; 182 unsigned long madt_end;
318 unsigned int i;
319 183
320 if (!handler) 184 if (!handler)
321 return -EINVAL; 185 return -EINVAL;
322 186
323 /* Locate the MADT (if exists). There should only be one. */ 187 /* Locate the MADT (if exists). There should only be one. */
324 188 acpi_get_table(id, 0, &madt);
325 for (i = 0; i < sdt_count; i++) {
326 if (sdt_entry[i].id != id)
327 continue;
328 madt = (void *)
329 __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
330 if (!madt) {
331 printk(KERN_WARNING PREFIX "Unable to map %s\n",
332 acpi_table_signatures[id]);
333 return -ENODEV;
334 }
335 break;
336 }
337 189
338 if (!madt) { 190 if (!madt) {
339 printk(KERN_WARNING PREFIX "%s not present\n", 191 printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
340 acpi_table_signatures[id]);
341 return -ENODEV; 192 return -ENODEV;
342 } 193 }
343 194
344 madt_end = (unsigned long)madt + sdt_entry[i].size; 195 madt_end = (unsigned long)madt + madt->length;
345 196
346 /* Parse all entries looking for a match. */ 197 /* Parse all entries looking for a match. */
347 198
348 entry = (acpi_table_entry_header *) 199 entry = (struct acpi_subtable_header *)
349 ((unsigned long)madt + madt_size); 200 ((unsigned long)madt + madt_size);
350 201
351 while (((unsigned long)entry) + sizeof(acpi_table_entry_header) < 202 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
352 madt_end) { 203 madt_end) {
353 if (entry->type == entry_id 204 if (entry->type == entry_id
354 && (!max_entries || count++ < max_entries)) 205 && (!max_entries || count++ < max_entries))
355 if (handler(entry, madt_end)) 206 if (handler(entry, madt_end))
356 return -EINVAL; 207 return -EINVAL;
357 208
358 entry = (acpi_table_entry_header *) 209 entry = (struct acpi_subtable_header *)
359 ((unsigned long)entry + entry->length); 210 ((unsigned long)entry + entry->length);
360 } 211 }
361 if (max_entries && count > max_entries) { 212 if (max_entries && count > max_entries) {
362 printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " 213 printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
363 "%i found\n", acpi_table_signatures[id], entry_id, 214 "%i found\n", id, entry_id, count - max_entries, count);
364 count - max_entries, count);
365 } 215 }
366 216
367 return count; 217 return count;
368} 218}
369 219
370int __init 220int __init
371acpi_table_parse_madt(enum acpi_madt_entry_id id, 221acpi_table_parse_madt(enum acpi_madt_type id,
372 acpi_madt_entry_handler handler, unsigned int max_entries) 222 acpi_madt_entry_handler handler, unsigned int max_entries)
373{ 223{
374 return acpi_table_parse_madt_family(ACPI_APIC, 224 return acpi_table_parse_madt_family(ACPI_SIG_MADT,
375 sizeof(struct acpi_table_madt), id, 225 sizeof(struct acpi_table_madt), id,
376 handler, max_entries); 226 handler, max_entries);
377} 227}
378 228
379int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler) 229int __init acpi_table_parse(char *id, acpi_table_handler handler)
380{ 230{
381 int count = 0; 231 struct acpi_table_header *table = NULL;
382 unsigned int i = 0;
383
384 if (!handler) 232 if (!handler)
385 return -EINVAL; 233 return -EINVAL;
386 234
387 for (i = 0; i < sdt_count; i++) { 235 acpi_get_table(id, 0, &table);
388 if (sdt_entry[i].id != id) 236 if (table) {
389 continue; 237 handler(table);
390 count++; 238 return 1;
391 if (count == 1) 239 } else
392 handler(sdt_entry[i].pa, sdt_entry[i].size); 240 return 0;
393
394 else
395 printk(KERN_WARNING PREFIX
396 "%d duplicate %s table ignored.\n", count,
397 acpi_table_signatures[id]);
398 }
399
400 return count;
401}
402
403static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp)
404{
405 struct acpi_table_header *header = NULL;
406 unsigned int i, id = 0;
407
408 if (!rsdp)
409 return -EINVAL;
410
411 /* First check XSDT (but only on ACPI 2.0-compatible systems) */
412
413 if ((rsdp->revision >= 2) &&
414 (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {
415
416 struct acpi_table_xsdt *mapped_xsdt = NULL;
417
418 sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;
419
420 /* map in just the header */
421 header = (struct acpi_table_header *)
422 __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
423
424 if (!header) {
425 printk(KERN_WARNING PREFIX
426 "Unable to map XSDT header\n");
427 return -ENODEV;
428 }
429
430 /* remap in the entire table before processing */
431 mapped_xsdt = (struct acpi_table_xsdt *)
432 __acpi_map_table(sdt_pa, header->length);
433 if (!mapped_xsdt) {
434 printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
435 return -ENODEV;
436 }
437 header = &mapped_xsdt->header;
438
439 if (strncmp(header->signature, "XSDT", 4)) {
440 printk(KERN_WARNING PREFIX
441 "XSDT signature incorrect\n");
442 return -ENODEV;
443 }
444
445 if (acpi_table_compute_checksum(header, header->length)) {
446 printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
447 return -ENODEV;
448 }
449
450 sdt_count =
451 (header->length - sizeof(struct acpi_table_header)) >> 3;
452 if (sdt_count > ACPI_MAX_TABLES) {
453 printk(KERN_WARNING PREFIX
454 "Truncated %lu XSDT entries\n",
455 (sdt_count - ACPI_MAX_TABLES));
456 sdt_count = ACPI_MAX_TABLES;
457 }
458
459 for (i = 0; i < sdt_count; i++)
460 sdt_entry[i].pa = (unsigned long)mapped_xsdt->entry[i];
461 }
462
463 /* Then check RSDT */
464
465 else if (rsdp->rsdt_address) {
466
467 struct acpi_table_rsdt *mapped_rsdt = NULL;
468
469 sdt_pa = rsdp->rsdt_address;
470
471 /* map in just the header */
472 header = (struct acpi_table_header *)
473 __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
474 if (!header) {
475 printk(KERN_WARNING PREFIX
476 "Unable to map RSDT header\n");
477 return -ENODEV;
478 }
479
480 /* remap in the entire table before processing */
481 mapped_rsdt = (struct acpi_table_rsdt *)
482 __acpi_map_table(sdt_pa, header->length);
483 if (!mapped_rsdt) {
484 printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
485 return -ENODEV;
486 }
487 header = &mapped_rsdt->header;
488
489 if (strncmp(header->signature, "RSDT", 4)) {
490 printk(KERN_WARNING PREFIX
491 "RSDT signature incorrect\n");
492 return -ENODEV;
493 }
494
495 if (acpi_table_compute_checksum(header, header->length)) {
496 printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
497 return -ENODEV;
498 }
499
500 sdt_count =
501 (header->length - sizeof(struct acpi_table_header)) >> 2;
502 if (sdt_count > ACPI_MAX_TABLES) {
503 printk(KERN_WARNING PREFIX
504 "Truncated %lu RSDT entries\n",
505 (sdt_count - ACPI_MAX_TABLES));
506 sdt_count = ACPI_MAX_TABLES;
507 }
508
509 for (i = 0; i < sdt_count; i++)
510 sdt_entry[i].pa = (unsigned long)mapped_rsdt->entry[i];
511 }
512
513 else {
514 printk(KERN_WARNING PREFIX
515 "No System Description Table (RSDT/XSDT) specified in RSDP\n");
516 return -ENODEV;
517 }
518
519 acpi_table_print(header, sdt_pa);
520
521 for (i = 0; i < sdt_count; i++) {
522
523 /* map in just the header */
524 header = (struct acpi_table_header *)
525 __acpi_map_table(sdt_entry[i].pa,
526 sizeof(struct acpi_table_header));
527 if (!header)
528 continue;
529
530 /* remap in the entire table before processing */
531 header = (struct acpi_table_header *)
532 __acpi_map_table(sdt_entry[i].pa, header->length);
533 if (!header)
534 continue;
535
536 acpi_table_print(header, sdt_entry[i].pa);
537
538 if (acpi_table_compute_checksum(header, header->length)) {
539 printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
540 continue;
541 }
542
543 sdt_entry[i].size = header->length;
544
545 for (id = 0; id < ACPI_TABLE_COUNT; id++) {
546 if (!strncmp((char *)&header->signature,
547 acpi_table_signatures[id],
548 sizeof(header->signature))) {
549 sdt_entry[i].id = id;
550 }
551 }
552 }
553
554 /*
555 * The DSDT is *not* in the RSDT (why not? no idea.) but we want
556 * to print its info, because this is what people usually blacklist
557 * against. Unfortunately, we don't know the phys_addr, so just
558 * print 0. Maybe no one will notice.
559 */
560 if (!acpi_get_table_header_early(ACPI_DSDT, &header))
561 acpi_table_print(header, 0);
562
563 return 0;
564} 241}
565 242
566/* 243/*
@@ -568,54 +245,13 @@ static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp)
568 * 245 *
569 * find RSDP, find and checksum SDT/XSDT. 246 * find RSDP, find and checksum SDT/XSDT.
570 * checksum all tables, print SDT/XSDT 247 * checksum all tables, print SDT/XSDT
571 * 248 *
572 * result: sdt_entry[] is initialized 249 * result: sdt_entry[] is initialized
573 */ 250 */
574 251
252
575int __init acpi_table_init(void) 253int __init acpi_table_init(void)
576{ 254{
577 struct acpi_table_rsdp *rsdp = NULL; 255 acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
578 unsigned long rsdp_phys = 0;
579 int result = 0;
580
581 /* Locate and map the Root System Description Table (RSDP) */
582
583 rsdp_phys = acpi_find_rsdp();
584 if (!rsdp_phys) {
585 printk(KERN_ERR PREFIX "Unable to locate RSDP\n");
586 return -ENODEV;
587 }
588
589 rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys,
590 sizeof(struct acpi_table_rsdp));
591 if (!rsdp) {
592 printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
593 return -ENODEV;
594 }
595
596 printk(KERN_DEBUG PREFIX
597 "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
598 rsdp->revision, rsdp->oem_id, (void *)rsdp_phys);
599
600 if (rsdp->revision < 2)
601 result =
602 acpi_table_compute_checksum(rsdp,
603 sizeof(struct acpi_table_rsdp));
604 else
605 result =
606 acpi_table_compute_checksum(rsdp,
607 ((struct acpi20_table_rsdp *)
608 rsdp)->length);
609
610 if (result) {
611 printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
612 return -ENODEV;
613 }
614
615 /* Locate and map the System Description table (RSDT/XSDT) */
616
617 if (acpi_table_get_sdt(rsdp))
618 return -ENODEV;
619
620 return 0; 256 return 0;
621} 257}
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
index aa4c69594d97..0a7d7afac255 100644
--- a/drivers/acpi/tables/Makefile
+++ b/drivers/acpi/tables/Makefile
@@ -2,7 +2,6 @@
2# Makefile for all Linux ACPI interpreter subdirectories 2# Makefile for all Linux ACPI interpreter subdirectories
3# 3#
4 4
5obj-y := tbconvrt.o tbget.o tbrsdt.o tbxface.o \ 5obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o
6 tbgetall.o tbinstal.o tbutils.o tbxfroot.o
7 6
8EXTRA_CFLAGS += $(ACPI_CFLAGS) 7EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
deleted file mode 100644
index d697fcb35d52..000000000000
--- a/drivers/acpi/tables/tbconvrt.c
+++ /dev/null
@@ -1,622 +0,0 @@
1/******************************************************************************
2 *
3 * Module Name: tbconvrt - ACPI Table conversion utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbconvrt")
49
50/* Local prototypes */
51static void
52acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
53 u8 register_bit_width,
54 acpi_physical_address address);
55
56static void
57acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt,
58 struct fadt_descriptor_rev1 *original_fadt);
59
60static void
61acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt,
62 struct fadt_descriptor *original_fadt);
63
64u8 acpi_fadt_is_v1;
65ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1)
66
67/*******************************************************************************
68 *
69 * FUNCTION: acpi_tb_get_table_count
70 *
71 * PARAMETERS: RSDP - Pointer to the RSDP
72 * RSDT - Pointer to the RSDT/XSDT
73 *
74 * RETURN: The number of tables pointed to by the RSDT or XSDT.
75 *
76 * DESCRIPTION: Calculate the number of tables. Automatically handles either
77 * an RSDT or XSDT.
78 *
79 ******************************************************************************/
80
81u32
82acpi_tb_get_table_count(struct rsdp_descriptor *RSDP,
83 struct acpi_table_header *RSDT)
84{
85 u32 pointer_size;
86
87 ACPI_FUNCTION_ENTRY();
88
89 /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
90
91 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
92 pointer_size = sizeof(u32);
93 } else {
94 pointer_size = sizeof(u64);
95 }
96
97 /*
98 * Determine the number of tables pointed to by the RSDT/XSDT.
99 * This is defined by the ACPI Specification to be the number of
100 * pointers contained within the RSDT/XSDT. The size of the pointers
101 * is architecture-dependent.
102 */
103 return ((RSDT->length -
104 sizeof(struct acpi_table_header)) / pointer_size);
105}
106
107/*******************************************************************************
108 *
109 * FUNCTION: acpi_tb_convert_to_xsdt
110 *
111 * PARAMETERS: table_info - Info about the RSDT
112 *
113 * RETURN: Status
114 *
115 * DESCRIPTION: Convert an RSDT to an XSDT (internal common format)
116 *
117 ******************************************************************************/
118
119acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info)
120{
121 acpi_size table_size;
122 u32 i;
123 struct xsdt_descriptor *new_table;
124
125 ACPI_FUNCTION_ENTRY();
126
127 /* Compute size of the converted XSDT */
128
129 table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) +
130 sizeof(struct acpi_table_header);
131
132 /* Allocate an XSDT */
133
134 new_table = ACPI_ALLOCATE_ZEROED(table_size);
135 if (!new_table) {
136 return (AE_NO_MEMORY);
137 }
138
139 /* Copy the header and set the length */
140
141 ACPI_MEMCPY(new_table, table_info->pointer,
142 sizeof(struct acpi_table_header));
143 new_table->length = (u32) table_size;
144
145 /* Copy the table pointers */
146
147 for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
148
149 /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
150
151 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
152 ACPI_STORE_ADDRESS(new_table->table_offset_entry[i],
153 (ACPI_CAST_PTR
154 (struct rsdt_descriptor,
155 table_info->pointer))->
156 table_offset_entry[i]);
157 } else {
158 new_table->table_offset_entry[i] =
159 (ACPI_CAST_PTR(struct xsdt_descriptor,
160 table_info->pointer))->
161 table_offset_entry[i];
162 }
163 }
164
165 /* Delete the original table (either mapped or in a buffer) */
166
167 acpi_tb_delete_single_table(table_info);
168
169 /* Point the table descriptor to the new table */
170
171 table_info->pointer =
172 ACPI_CAST_PTR(struct acpi_table_header, new_table);
173 table_info->length = table_size;
174 table_info->allocation = ACPI_MEM_ALLOCATED;
175
176 return (AE_OK);
177}
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_tb_init_generic_address
182 *
183 * PARAMETERS: new_gas_struct - GAS struct to be initialized
184 * register_bit_width - Width of this register
185 * Address - Address of the register
186 *
187 * RETURN: None
188 *
189 * DESCRIPTION: Initialize a GAS structure.
190 *
191 ******************************************************************************/
192
193static void
194acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
195 u8 register_bit_width,
196 acpi_physical_address address)
197{
198
199 ACPI_STORE_ADDRESS(new_gas_struct->address, address);
200
201 new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
202 new_gas_struct->register_bit_width = register_bit_width;
203 new_gas_struct->register_bit_offset = 0;
204 new_gas_struct->access_width = 0;
205}
206
207/*******************************************************************************
208 *
209 * FUNCTION: acpi_tb_convert_fadt1
210 *
211 * PARAMETERS: local_fadt - Pointer to new FADT
212 * original_fadt - Pointer to old FADT
213 *
214 * RETURN: None, populates local_fadt
215 *
216 * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
217 *
218 ******************************************************************************/
219
220static void
221acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt,
222 struct fadt_descriptor_rev1 *original_fadt)
223{
224
225 /* ACPI 1.0 FACS */
226 /* The BIOS stored FADT should agree with Revision 1.0 */
227 acpi_fadt_is_v1 = 1;
228
229 /*
230 * Copy the table header and the common part of the tables.
231 *
232 * The 2.0 table is an extension of the 1.0 table, so the entire 1.0
233 * table can be copied first, then expand some fields to 64 bits.
234 */
235 ACPI_MEMCPY(local_fadt, original_fadt,
236 sizeof(struct fadt_descriptor_rev1));
237
238 /* Convert table pointers to 64-bit fields */
239
240 ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl,
241 local_fadt->V1_firmware_ctrl);
242 ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt);
243
244 /*
245 * System Interrupt Model isn't used in ACPI 2.0
246 * (local_fadt->Reserved1 = 0;)
247 */
248
249 /*
250 * This field is set by the OEM to convey the preferred power management
251 * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't
252 * know what kind of 32-bit system this is, we will use "unspecified".
253 */
254 local_fadt->prefer_PM_profile = PM_UNSPECIFIED;
255
256 /*
257 * Processor Performance State Control. This is the value OSPM writes to
258 * the SMI_CMD register to assume processor performance state control
259 * responsibility. There isn't any equivalence in 1.0, but as many 1.x
260 * ACPI tables contain _PCT and _PSS we also keep this value, unless
261 * acpi_strict is set.
262 */
263 if (acpi_strict)
264 local_fadt->pstate_cnt = 0;
265
266 /*
267 * Support for the _CST object and C States change notification.
268 * This data item hasn't any 1.0 equivalence so leave it zero.
269 */
270 local_fadt->cst_cnt = 0;
271
272 /*
273 * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
274 * It primarily adds the FADT reset mechanism.
275 */
276 if ((original_fadt->revision == 2) &&
277 (original_fadt->length ==
278 sizeof(struct fadt_descriptor_rev2_minus))) {
279 /*
280 * Grab the entire generic address struct, plus the 1-byte reset value
281 * that immediately follows.
282 */
283 ACPI_MEMCPY(&local_fadt->reset_register,
284 &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus,
285 original_fadt))->reset_register,
286 sizeof(struct acpi_generic_address) + 1);
287 } else {
288 /*
289 * Since there isn't any equivalence in 1.0 and since it is highly
290 * likely that a 1.0 system has legacy support.
291 */
292 local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
293 }
294
295 /*
296 * Convert the V1.0 block addresses to V2.0 GAS structures
297 */
298 acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk,
299 local_fadt->pm1_evt_len,
300 (acpi_physical_address) local_fadt->
301 V1_pm1a_evt_blk);
302 acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk,
303 local_fadt->pm1_evt_len,
304 (acpi_physical_address) local_fadt->
305 V1_pm1b_evt_blk);
306 acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk,
307 local_fadt->pm1_cnt_len,
308 (acpi_physical_address) local_fadt->
309 V1_pm1a_cnt_blk);
310 acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk,
311 local_fadt->pm1_cnt_len,
312 (acpi_physical_address) local_fadt->
313 V1_pm1b_cnt_blk);
314 acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk,
315 local_fadt->pm2_cnt_len,
316 (acpi_physical_address) local_fadt->
317 V1_pm2_cnt_blk);
318 acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk,
319 local_fadt->pm_tm_len,
320 (acpi_physical_address) local_fadt->
321 V1_pm_tmr_blk);
322 acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0,
323 (acpi_physical_address) local_fadt->
324 V1_gpe0_blk);
325 acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0,
326 (acpi_physical_address) local_fadt->
327 V1_gpe1_blk);
328
329 /* Create separate GAS structs for the PM1 Enable registers */
330
331 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
332 (u8) ACPI_DIV_2(acpi_gbl_FADT->
333 pm1_evt_len),
334 (acpi_physical_address)
335 (local_fadt->xpm1a_evt_blk.address +
336 ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len)));
337
338 /* PM1B is optional; leave null if not present */
339
340 if (local_fadt->xpm1b_evt_blk.address) {
341 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
342 (u8) ACPI_DIV_2(acpi_gbl_FADT->
343 pm1_evt_len),
344 (acpi_physical_address)
345 (local_fadt->xpm1b_evt_blk.
346 address +
347 ACPI_DIV_2(acpi_gbl_FADT->
348 pm1_evt_len)));
349 }
350}
351
352/*******************************************************************************
353 *
354 * FUNCTION: acpi_tb_convert_fadt2
355 *
356 * PARAMETERS: local_fadt - Pointer to new FADT
357 * original_fadt - Pointer to old FADT
358 *
359 * RETURN: None, populates local_fadt
360 *
361 * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
362 * Handles optional "X" fields.
363 *
364 ******************************************************************************/
365
366static void
367acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt,
368 struct fadt_descriptor *original_fadt)
369{
370
371 /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
372
373 ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor));
374
375 /*
376 * "X" fields are optional extensions to the original V1.0 fields, so
377 * we must selectively expand V1.0 fields if the corresponding X field
378 * is zero.
379 */
380 if (!(local_fadt->xfirmware_ctrl)) {
381 ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl,
382 local_fadt->V1_firmware_ctrl);
383 }
384
385 if (!(local_fadt->Xdsdt)) {
386 ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt);
387 }
388
389 if (!(local_fadt->xpm1a_evt_blk.address)) {
390 acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk,
391 local_fadt->pm1_evt_len,
392 (acpi_physical_address)
393 local_fadt->V1_pm1a_evt_blk);
394 }
395
396 if (!(local_fadt->xpm1b_evt_blk.address)) {
397 acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk,
398 local_fadt->pm1_evt_len,
399 (acpi_physical_address)
400 local_fadt->V1_pm1b_evt_blk);
401 }
402
403 if (!(local_fadt->xpm1a_cnt_blk.address)) {
404 acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk,
405 local_fadt->pm1_cnt_len,
406 (acpi_physical_address)
407 local_fadt->V1_pm1a_cnt_blk);
408 }
409
410 if (!(local_fadt->xpm1b_cnt_blk.address)) {
411 acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk,
412 local_fadt->pm1_cnt_len,
413 (acpi_physical_address)
414 local_fadt->V1_pm1b_cnt_blk);
415 }
416
417 if (!(local_fadt->xpm2_cnt_blk.address)) {
418 acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk,
419 local_fadt->pm2_cnt_len,
420 (acpi_physical_address)
421 local_fadt->V1_pm2_cnt_blk);
422 }
423
424 if (!(local_fadt->xpm_tmr_blk.address)) {
425 acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk,
426 local_fadt->pm_tm_len,
427 (acpi_physical_address)
428 local_fadt->V1_pm_tmr_blk);
429 }
430
431 if (!(local_fadt->xgpe0_blk.address)) {
432 acpi_tb_init_generic_address(&local_fadt->xgpe0_blk,
433 0,
434 (acpi_physical_address)
435 local_fadt->V1_gpe0_blk);
436 }
437
438 if (!(local_fadt->xgpe1_blk.address)) {
439 acpi_tb_init_generic_address(&local_fadt->xgpe1_blk,
440 0,
441 (acpi_physical_address)
442 local_fadt->V1_gpe1_blk);
443 }
444
445 /* Create separate GAS structs for the PM1 Enable registers */
446
447 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
448 (u8) ACPI_DIV_2(acpi_gbl_FADT->
449 pm1_evt_len),
450 (acpi_physical_address)
451 (local_fadt->xpm1a_evt_blk.address +
452 ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len)));
453
454 acpi_gbl_xpm1a_enable.address_space_id =
455 local_fadt->xpm1a_evt_blk.address_space_id;
456
457 /* PM1B is optional; leave null if not present */
458
459 if (local_fadt->xpm1b_evt_blk.address) {
460 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
461 (u8) ACPI_DIV_2(acpi_gbl_FADT->
462 pm1_evt_len),
463 (acpi_physical_address)
464 (local_fadt->xpm1b_evt_blk.
465 address +
466 ACPI_DIV_2(acpi_gbl_FADT->
467 pm1_evt_len)));
468
469 acpi_gbl_xpm1b_enable.address_space_id =
470 local_fadt->xpm1b_evt_blk.address_space_id;
471 }
472}
473
474/*******************************************************************************
475 *
476 * FUNCTION: acpi_tb_convert_table_fadt
477 *
478 * PARAMETERS: None
479 *
480 * RETURN: Status
481 *
482 * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local
483 * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
484 * copied to the local FADT. The ACPI CA software uses this
485 * local FADT. Thus a significant amount of special #ifdef
486 * type codeing is saved.
487 *
488 ******************************************************************************/
489
490acpi_status acpi_tb_convert_table_fadt(void)
491{
492 struct fadt_descriptor *local_fadt;
493 struct acpi_table_desc *table_desc;
494
495 ACPI_FUNCTION_TRACE(tb_convert_table_fadt);
496
497 /*
498 * acpi_gbl_FADT is valid. Validate the FADT length. The table must be
499 * at least as long as the version 1.0 FADT
500 */
501 if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) {
502 ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X",
503 acpi_gbl_FADT->length));
504 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
505 }
506
507 /* Allocate buffer for the ACPI 2.0(+) FADT */
508
509 local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor));
510 if (!local_fadt) {
511 return_ACPI_STATUS(AE_NO_MEMORY);
512 }
513
514 if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
515 if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) {
516
517 /* Length is too short to be a V2.0 table */
518
519 ACPI_WARNING((AE_INFO,
520 "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table",
521 acpi_gbl_FADT->length,
522 acpi_gbl_FADT->revision));
523
524 acpi_tb_convert_fadt1(local_fadt,
525 (void *)acpi_gbl_FADT);
526 } else {
527 /* Valid V2.0 table */
528
529 acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT);
530 }
531 } else {
532 /* Valid V1.0 table */
533
534 acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT);
535 }
536
537 /* Global FADT pointer will point to the new common V2.0 FADT */
538
539 acpi_gbl_FADT = local_fadt;
540 acpi_gbl_FADT->length = sizeof(struct fadt_descriptor);
541
542 /* Free the original table */
543
544 table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next;
545 acpi_tb_delete_single_table(table_desc);
546
547 /* Install the new table */
548
549 table_desc->pointer =
550 ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT);
551 table_desc->allocation = ACPI_MEM_ALLOCATED;
552 table_desc->length = sizeof(struct fadt_descriptor);
553
554 /* Dump the entire FADT */
555
556 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
557 "Hex dump of common internal FADT, size %d (%X)\n",
558 acpi_gbl_FADT->length, acpi_gbl_FADT->length));
559
560 ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT),
561 acpi_gbl_FADT->length);
562
563 return_ACPI_STATUS(AE_OK);
564}
565
566/*******************************************************************************
567 *
568 * FUNCTION: acpi_tb_build_common_facs
569 *
570 * PARAMETERS: table_info - Info for currently installed FACS
571 *
572 * RETURN: Status
573 *
574 * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal
575 * table format.
576 *
577 ******************************************************************************/
578
579acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info)
580{
581
582 ACPI_FUNCTION_TRACE(tb_build_common_facs);
583
584 /* Absolute minimum length is 24, but the ACPI spec says 64 */
585
586 if (acpi_gbl_FACS->length < 24) {
587 ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X",
588 acpi_gbl_FACS->length));
589 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
590 }
591
592 if (acpi_gbl_FACS->length < 64) {
593 ACPI_WARNING((AE_INFO,
594 "FACS is shorter than the ACPI specification allows: 0x%X, using anyway",
595 acpi_gbl_FACS->length));
596 }
597
598 /* Copy fields to the new FACS */
599
600 acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock);
601
602 if ((acpi_gbl_RSDP->revision < 2) ||
603 (acpi_gbl_FACS->length < 32) ||
604 (!(acpi_gbl_FACS->xfirmware_waking_vector))) {
605
606 /* ACPI 1.0 FACS or short table or optional X_ field is zero */
607
608 acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64,
609 &
610 (acpi_gbl_FACS->
611 firmware_waking_vector));
612 acpi_gbl_common_fACS.vector_width = 32;
613 } else {
614 /* ACPI 2.0 FACS with valid X_ field */
615
616 acpi_gbl_common_fACS.firmware_waking_vector =
617 &acpi_gbl_FACS->xfirmware_waking_vector;
618 acpi_gbl_common_fACS.vector_width = 64;
619 }
620
621 return_ACPI_STATUS(AE_OK);
622}
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
new file mode 100644
index 000000000000..807c7116e94b
--- /dev/null
+++ b/drivers/acpi/tables/tbfadt.c
@@ -0,0 +1,434 @@
1/******************************************************************************
2 *
3 * Module Name: tbfadt - FADT table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbfadt")
49
50/* Local prototypes */
51static void inline
52acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
53 u8 bit_width, u64 address);
54
55static void acpi_tb_convert_fadt(void);
56
57static void acpi_tb_validate_fadt(void);
58
59/* Table for conversion of FADT to common internal format and FADT validation */
60
61typedef struct acpi_fadt_info {
62 char *name;
63 u8 target;
64 u8 source;
65 u8 length;
66 u8 type;
67
68} acpi_fadt_info;
69
70#define ACPI_FADT_REQUIRED 1
71#define ACPI_FADT_SEPARATE_LENGTH 2
72
73static struct acpi_fadt_info fadt_info_table[] = {
74 {"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block),
75 ACPI_FADT_OFFSET(pm1a_event_block),
76 ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED},
77
78 {"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block),
79 ACPI_FADT_OFFSET(pm1b_event_block),
80 ACPI_FADT_OFFSET(pm1_event_length), 0},
81
82 {"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block),
83 ACPI_FADT_OFFSET(pm1a_control_block),
84 ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED},
85
86 {"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block),
87 ACPI_FADT_OFFSET(pm1b_control_block),
88 ACPI_FADT_OFFSET(pm1_control_length), 0},
89
90 {"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block),
91 ACPI_FADT_OFFSET(pm2_control_block),
92 ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH},
93
94 {"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block),
95 ACPI_FADT_OFFSET(pm_timer_block),
96 ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED},
97
98 {"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block),
99 ACPI_FADT_OFFSET(gpe0_block),
100 ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH},
101
102 {"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block),
103 ACPI_FADT_OFFSET(gpe1_block),
104 ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH}
105};
106
107#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
108
109/*******************************************************************************
110 *
111 * FUNCTION: acpi_tb_init_generic_address
112 *
113 * PARAMETERS: generic_address - GAS struct to be initialized
114 * bit_width - Width of this register
115 * Address - Address of the register
116 *
117 * RETURN: None
118 *
119 * DESCRIPTION: Initialize a Generic Address Structure (GAS)
120 * See the ACPI specification for a full description and
121 * definition of this structure.
122 *
123 ******************************************************************************/
124
125static void inline
126acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
127 u8 bit_width, u64 address)
128{
129
130 /*
131 * The 64-bit Address field is non-aligned in the byte packed
132 * GAS struct.
133 */
134 ACPI_MOVE_64_TO_64(&generic_address->address, &address);
135
136 /* All other fields are byte-wide */
137
138 generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO;
139 generic_address->bit_width = bit_width;
140 generic_address->bit_offset = 0;
141 generic_address->access_width = 0;
142}
143
144/*******************************************************************************
145 *
146 * FUNCTION: acpi_tb_parse_fadt
147 *
148 * PARAMETERS: table_index - Index for the FADT
149 * Flags - Flags
150 *
151 * RETURN: None
152 *
153 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
154 * (FADT contains the addresses of the DSDT and FACS)
155 *
156 ******************************************************************************/
157
158void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
159{
160 u32 length;
161 struct acpi_table_header *table;
162
163 /*
164 * The FADT has multiple versions with different lengths,
165 * and it contains pointers to both the DSDT and FACS tables.
166 *
167 * Get a local copy of the FADT and convert it to a common format
168 * Map entire FADT, assumed to be smaller than one page.
169 */
170 length = acpi_gbl_root_table_list.tables[table_index].length;
171
172 table =
173 acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
174 address, length);
175 if (!table) {
176 return;
177 }
178
179 /*
180 * Validate the FADT checksum before we copy the table. Ignore
181 * checksum error as we want to try to get the DSDT and FACS.
182 */
183 (void)acpi_tb_verify_checksum(table, length);
184
185 /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
186
187 acpi_tb_create_local_fadt(table, length);
188
189 /* All done with the real FADT, unmap it */
190
191 acpi_os_unmap_memory(table, length);
192
193 /* Obtain the DSDT and FACS tables via their addresses within the FADT */
194
195 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
196 flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
197
198 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
199 flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
200}
201
202/*******************************************************************************
203 *
204 * FUNCTION: acpi_tb_create_local_fadt
205 *
206 * PARAMETERS: Table - Pointer to BIOS FADT
207 * Length - Length of the table
208 *
209 * RETURN: None
210 *
211 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
212 * Performs validation on some important FADT fields.
213 *
214 ******************************************************************************/
215
216void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
217{
218
219 /*
220 * Check if the FADT is larger than what we know about (ACPI 2.0 version).
221 * Truncate the table, but make some noise.
222 */
223 if (length > sizeof(struct acpi_table_fadt)) {
224 ACPI_WARNING((AE_INFO,
225 "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX",
226 table->revision, (unsigned)length,
227 sizeof(struct acpi_table_fadt)));
228 }
229
230 /* Copy the entire FADT locally. Zero first for tb_convert_fadt */
231
232 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
233
234 ACPI_MEMCPY(&acpi_gbl_FADT, table,
235 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
236
237 /*
238 * 1) Convert the local copy of the FADT to the common internal format
239 * 2) Validate some of the important values within the FADT
240 */
241 acpi_tb_convert_fadt();
242 acpi_tb_validate_fadt();
243}
244
245/*******************************************************************************
246 *
247 * FUNCTION: acpi_tb_convert_fadt
248 *
249 * PARAMETERS: None, uses acpi_gbl_FADT
250 *
251 * RETURN: None
252 *
253 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
254 * -> Expand all 32-bit addresses to 64-bit.
255 *
256 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
257 * and must contain a copy of the actual FADT.
258 *
259 * ACPICA will use the "X" fields of the FADT for all addresses.
260 *
261 * "X" fields are optional extensions to the original V1.0 fields. Even if
262 * they are present in the structure, they can be optionally not used by
263 * setting them to zero. Therefore, we must selectively expand V1.0 fields
264 * if the corresponding X field is zero.
265 *
266 * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
267 * "X" fields.
268 *
269 * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
270 * expanding the corresponding ACPI 1.0 field.
271 *
272 ******************************************************************************/
273
274static void acpi_tb_convert_fadt(void)
275{
276 u8 pm1_register_length;
277 struct acpi_generic_address *target;
278 acpi_native_uint i;
279
280 /* Update the local FADT table header length */
281
282 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
283
284 /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */
285
286 if (!acpi_gbl_FADT.Xfacs) {
287 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
288 }
289
290 if (!acpi_gbl_FADT.Xdsdt) {
291 acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
292 }
293
294 /*
295 * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address
296 * structures as necessary.
297 */
298 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
299 target =
300 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
301 fadt_info_table[i].target);
302
303 /* Expand only if the X target is null */
304
305 if (!target->address) {
306 acpi_tb_init_generic_address(target,
307 *ACPI_ADD_PTR(u8,
308 &acpi_gbl_FADT,
309 fadt_info_table
310 [i].length),
311 (u64) * ACPI_ADD_PTR(u32,
312 &acpi_gbl_FADT,
313 fadt_info_table
314 [i].
315 source));
316 }
317 }
318
319 /*
320 * Calculate separate GAS structs for the PM1 Enable registers.
321 * These addresses do not appear (directly) in the FADT, so it is
322 * useful to calculate them once, here.
323 *
324 * The PM event blocks are split into two register blocks, first is the
325 * PM Status Register block, followed immediately by the PM Enable Register
326 * block. Each is of length (pm1_event_length/2)
327 */
328 pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length);
329
330 /* The PM1A register block is required */
331
332 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
333 pm1_register_length,
334 (acpi_gbl_FADT.xpm1a_event_block.address +
335 pm1_register_length));
336 /* Don't forget to copy space_id of the GAS */
337 acpi_gbl_xpm1a_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
338
339 /* The PM1B register block is optional, ignore if not present */
340
341 if (acpi_gbl_FADT.xpm1b_event_block.address) {
342 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
343 pm1_register_length,
344 (acpi_gbl_FADT.xpm1b_event_block.
345 address + pm1_register_length));
346 /* Don't forget to copy space_id of the GAS */
347 acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
348
349 }
350}
351
352/******************************************************************************
353 *
354 * FUNCTION: acpi_tb_validate_fadt
355 *
356 * PARAMETERS: Table - Pointer to the FADT to be validated
357 *
358 * RETURN: None
359 *
360 * DESCRIPTION: Validate various important fields within the FADT. If a problem
361 * is found, issue a message, but no status is returned.
362 * Used by both the table manager and the disassembler.
363 *
364 * Possible additional checks:
365 * (acpi_gbl_FADT.pm1_event_length >= 4)
366 * (acpi_gbl_FADT.pm1_control_length >= 2)
367 * (acpi_gbl_FADT.pm_timer_length >= 4)
368 * Gpe block lengths must be multiple of 2
369 *
370 ******************************************************************************/
371
372static void acpi_tb_validate_fadt(void)
373{
374 u32 *address32;
375 struct acpi_generic_address *address64;
376 u8 length;
377 acpi_native_uint i;
378
379 /* Examine all of the 64-bit extended address fields (X fields) */
380
381 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
382
383 /* Generate pointers to the 32-bit and 64-bit addresses and get the length */
384
385 address64 =
386 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
387 fadt_info_table[i].target);
388 address32 =
389 ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
390 fadt_info_table[i].source);
391 length =
392 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
393 fadt_info_table[i].length);
394
395 if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
396 /*
397 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
398 * Both the address and length must be non-zero.
399 */
400 if (!address64->address || !length) {
401 ACPI_ERROR((AE_INFO,
402 "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X",
403 fadt_info_table[i].name,
404 ACPI_FORMAT_UINT64(address64->
405 address),
406 length));
407 }
408 } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
409 /*
410 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
411 * length field. If present, both the address and length must be valid.
412 */
413 if ((address64->address && !length)
414 || (!address64->address && length)) {
415 ACPI_WARNING((AE_INFO,
416 "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X",
417 fadt_info_table[i].name,
418 ACPI_FORMAT_UINT64(address64->
419 address),
420 length));
421 }
422 }
423
424 /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
425
426 if (address64->address && *address32 &&
427 (address64->address != (u64) * address32)) {
428 ACPI_ERROR((AE_INFO,
429 "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X",
430 fadt_info_table[i].name, *address32,
431 ACPI_FORMAT_UINT64(address64->address)));
432 }
433 }
434}
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c
new file mode 100644
index 000000000000..058c064948e1
--- /dev/null
+++ b/drivers/acpi/tables/tbfind.c
@@ -0,0 +1,126 @@
1/******************************************************************************
2 *
3 * Module Name: tbfind - find table
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbfind")
49
50/*******************************************************************************
51 *
52 * FUNCTION: acpi_tb_find_table
53 *
54 * PARAMETERS: Signature - String with ACPI table signature
55 * oem_id - String with the table OEM ID
56 * oem_table_id - String with the OEM Table ID
57 * table_index - Where the table index is returned
58 *
59 * RETURN: Status and table index
60 *
61 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
62 * Signature, OEM ID and OEM Table ID. Returns an index that can
63 * be used to get the table header or entire table.
64 *
65 ******************************************************************************/
66acpi_status
67acpi_tb_find_table(char *signature,
68 char *oem_id,
69 char *oem_table_id, acpi_native_uint * table_index)
70{
71 acpi_native_uint i;
72 acpi_status status;
73
74 ACPI_FUNCTION_TRACE(tb_find_table);
75
76 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
77 if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature),
78 signature, ACPI_NAME_SIZE)) {
79
80 /* Not the requested table */
81
82 continue;
83 }
84
85 /* Table with matching signature has been found */
86
87 if (!acpi_gbl_root_table_list.tables[i].pointer) {
88
89 /* Table is not currently mapped, map it */
90
91 status =
92 acpi_tb_verify_table(&acpi_gbl_root_table_list.
93 tables[i]);
94 if (ACPI_FAILURE(status)) {
95 return_ACPI_STATUS(status);
96 }
97
98 if (!acpi_gbl_root_table_list.tables[i].pointer) {
99 continue;
100 }
101 }
102
103 /* Check for table match on all IDs */
104
105 if (!ACPI_MEMCMP
106 (acpi_gbl_root_table_list.tables[i].pointer->signature,
107 signature, ACPI_NAME_SIZE) && (!oem_id[0]
108 ||
109 !ACPI_MEMCMP
110 (acpi_gbl_root_table_list.
111 tables[i].pointer->oem_id,
112 oem_id, ACPI_OEM_ID_SIZE))
113 && (!oem_table_id[0]
114 || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i].
115 pointer->oem_table_id, oem_table_id,
116 ACPI_OEM_TABLE_ID_SIZE))) {
117 *table_index = i;
118
119 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
120 "Found table [%4.4s]\n", signature));
121 return_ACPI_STATUS(AE_OK);
122 }
123 }
124
125 return_ACPI_STATUS(AE_NOT_FOUND);
126}
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
deleted file mode 100644
index 11e2d4454e05..000000000000
--- a/drivers/acpi/tables/tbget.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/******************************************************************************
2 *
3 * Module Name: tbget - ACPI Table get* routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbget")
49
50/* Local prototypes */
51static acpi_status
52acpi_tb_get_this_table(struct acpi_pointer *address,
53 struct acpi_table_header *header,
54 struct acpi_table_desc *table_info);
55
56static acpi_status
57acpi_tb_table_override(struct acpi_table_header *header,
58 struct acpi_table_desc *table_info);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_tb_get_table
63 *
64 * PARAMETERS: Address - Address of table to retrieve. Can be
65 * Logical or Physical
66 * table_info - Where table info is returned
67 *
68 * RETURN: None
69 *
70 * DESCRIPTION: Get entire table of unknown size.
71 *
72 ******************************************************************************/
73
74acpi_status
75acpi_tb_get_table(struct acpi_pointer *address,
76 struct acpi_table_desc *table_info)
77{
78 acpi_status status;
79 struct acpi_table_header header;
80
81 ACPI_FUNCTION_TRACE(tb_get_table);
82
83 /* Get the header in order to get signature and table size */
84
85 status = acpi_tb_get_table_header(address, &header);
86 if (ACPI_FAILURE(status)) {
87 return_ACPI_STATUS(status);
88 }
89
90 /* Get the entire table */
91
92 status = acpi_tb_get_table_body(address, &header, table_info);
93 if (ACPI_FAILURE(status)) {
94 ACPI_EXCEPTION((AE_INFO, status,
95 "Could not get ACPI table (size %X)",
96 header.length));
97 return_ACPI_STATUS(status);
98 }
99
100 return_ACPI_STATUS(AE_OK);
101}
102
103/*******************************************************************************
104 *
105 * FUNCTION: acpi_tb_get_table_header
106 *
107 * PARAMETERS: Address - Address of table to retrieve. Can be
108 * Logical or Physical
109 * return_header - Where the table header is returned
110 *
111 * RETURN: Status
112 *
113 * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual
114 * addressing mode. Works with both physical or logical pointers.
115 * Table is either copied or mapped, depending on the pointer
116 * type and mode of the processor.
117 *
118 ******************************************************************************/
119
120acpi_status
121acpi_tb_get_table_header(struct acpi_pointer *address,
122 struct acpi_table_header *return_header)
123{
124 acpi_status status = AE_OK;
125 struct acpi_table_header *header = NULL;
126
127 ACPI_FUNCTION_TRACE(tb_get_table_header);
128
129 /*
130 * Flags contains the current processor mode (Virtual or Physical
131 * addressing) The pointer_type is either Logical or Physical
132 */
133 switch (address->pointer_type) {
134 case ACPI_PHYSMODE_PHYSPTR:
135 case ACPI_LOGMODE_LOGPTR:
136
137 /* Pointer matches processor mode, copy the header */
138
139 ACPI_MEMCPY(return_header, address->pointer.logical,
140 sizeof(struct acpi_table_header));
141 break;
142
143 case ACPI_LOGMODE_PHYSPTR:
144
145 /* Create a logical address for the physical pointer */
146
147 status = acpi_os_map_memory(address->pointer.physical,
148 sizeof(struct acpi_table_header),
149 (void *)&header);
150 if (ACPI_FAILURE(status)) {
151 ACPI_ERROR((AE_INFO,
152 "Could not map memory at %8.8X%8.8X for table header",
153 ACPI_FORMAT_UINT64(address->pointer.
154 physical)));
155 return_ACPI_STATUS(status);
156 }
157
158 /* Copy header and delete mapping */
159
160 ACPI_MEMCPY(return_header, header,
161 sizeof(struct acpi_table_header));
162 acpi_os_unmap_memory(header, sizeof(struct acpi_table_header));
163 break;
164
165 default:
166
167 ACPI_ERROR((AE_INFO, "Invalid address flags %X",
168 address->pointer_type));
169 return_ACPI_STATUS(AE_BAD_PARAMETER);
170 }
171
172 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
173 return_header->signature));
174
175 return_ACPI_STATUS(AE_OK);
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_tb_get_table_body
181 *
182 * PARAMETERS: Address - Address of table to retrieve. Can be
183 * Logical or Physical
184 * Header - Header of the table to retrieve
185 * table_info - Where the table info is returned
186 *
187 * RETURN: Status
188 *
189 * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
190 * replace the table with a newer version (table override.)
191 * Works in both physical or virtual
192 * addressing mode. Works with both physical or logical pointers.
193 * Table is either copied or mapped, depending on the pointer
194 * type and mode of the processor.
195 *
196 ******************************************************************************/
197
198acpi_status
199acpi_tb_get_table_body(struct acpi_pointer *address,
200 struct acpi_table_header *header,
201 struct acpi_table_desc *table_info)
202{
203 acpi_status status;
204
205 ACPI_FUNCTION_TRACE(tb_get_table_body);
206
207 if (!table_info || !address) {
208 return_ACPI_STATUS(AE_BAD_PARAMETER);
209 }
210
211 /* Attempt table override. */
212
213 status = acpi_tb_table_override(header, table_info);
214 if (ACPI_SUCCESS(status)) {
215
216 /* Table was overridden by the host OS */
217
218 return_ACPI_STATUS(status);
219 }
220
221 /* No override, get the original table */
222
223 status = acpi_tb_get_this_table(address, header, table_info);
224 return_ACPI_STATUS(status);
225}
226
227/*******************************************************************************
228 *
229 * FUNCTION: acpi_tb_table_override
230 *
231 * PARAMETERS: Header - Pointer to table header
232 * table_info - Return info if table is overridden
233 *
234 * RETURN: None
235 *
236 * DESCRIPTION: Attempts override of current table with a new one if provided
237 * by the host OS.
238 *
239 ******************************************************************************/
240
241static acpi_status
242acpi_tb_table_override(struct acpi_table_header *header,
243 struct acpi_table_desc *table_info)
244{
245 struct acpi_table_header *new_table;
246 acpi_status status;
247 struct acpi_pointer address;
248
249 ACPI_FUNCTION_TRACE(tb_table_override);
250
251 /*
252 * The OSL will examine the header and decide whether to override this
253 * table. If it decides to override, a table will be returned in new_table,
254 * which we will then copy.
255 */
256 status = acpi_os_table_override(header, &new_table);
257 if (ACPI_FAILURE(status)) {
258
259 /* Some severe error from the OSL, but we basically ignore it */
260
261 ACPI_EXCEPTION((AE_INFO, status,
262 "Could not override ACPI table"));
263 return_ACPI_STATUS(status);
264 }
265
266 if (!new_table) {
267
268 /* No table override */
269
270 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
271 }
272
273 /*
274 * We have a new table to override the old one. Get a copy of
275 * the new one. We know that the new table has a logical pointer.
276 */
277 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
278 address.pointer.logical = new_table;
279
280 status = acpi_tb_get_this_table(&address, new_table, table_info);
281 if (ACPI_FAILURE(status)) {
282 ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table"));
283 return_ACPI_STATUS(status);
284 }
285
286 /* Copy the table info */
287
288 ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS",
289 table_info->pointer->signature));
290
291 return_ACPI_STATUS(AE_OK);
292}
293
294/*******************************************************************************
295 *
296 * FUNCTION: acpi_tb_get_this_table
297 *
298 * PARAMETERS: Address - Address of table to retrieve. Can be
299 * Logical or Physical
300 * Header - Header of the table to retrieve
301 * table_info - Where the table info is returned
302 *
303 * RETURN: Status
304 *
305 * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual
306 * addressing mode. Works with both physical or logical pointers.
307 * Table is either copied or mapped, depending on the pointer
308 * type and mode of the processor.
309 *
310 ******************************************************************************/
311
312static acpi_status
313acpi_tb_get_this_table(struct acpi_pointer *address,
314 struct acpi_table_header *header,
315 struct acpi_table_desc *table_info)
316{
317 struct acpi_table_header *full_table = NULL;
318 u8 allocation;
319 acpi_status status = AE_OK;
320
321 ACPI_FUNCTION_TRACE(tb_get_this_table);
322
323 /* Validate minimum length */
324
325 if (header->length < sizeof(struct acpi_table_header)) {
326 ACPI_ERROR((AE_INFO,
327 "Table length (%X) is smaller than minimum (%zX)",
328 header->length, sizeof(struct acpi_table_header)));
329
330 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
331 }
332
333 /*
334 * Flags contains the current processor mode (Virtual or Physical
335 * addressing) The pointer_type is either Logical or Physical
336 */
337 switch (address->pointer_type) {
338 case ACPI_PHYSMODE_PHYSPTR:
339 case ACPI_LOGMODE_LOGPTR:
340
341 /* Pointer matches processor mode, copy the table to a new buffer */
342
343 full_table = ACPI_ALLOCATE(header->length);
344 if (!full_table) {
345 ACPI_ERROR((AE_INFO,
346 "Could not allocate table memory for [%4.4s] length %X",
347 header->signature, header->length));
348 return_ACPI_STATUS(AE_NO_MEMORY);
349 }
350
351 /* Copy the entire table (including header) to the local buffer */
352
353 ACPI_MEMCPY(full_table, address->pointer.logical,
354 header->length);
355
356 /* Save allocation type */
357
358 allocation = ACPI_MEM_ALLOCATED;
359 break;
360
361 case ACPI_LOGMODE_PHYSPTR:
362
363 /*
364 * Just map the table's physical memory
365 * into our address space.
366 */
367 status = acpi_os_map_memory(address->pointer.physical,
368 (acpi_size) header->length,
369 ACPI_CAST_PTR(void, &full_table));
370 if (ACPI_FAILURE(status)) {
371 ACPI_ERROR((AE_INFO,
372 "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X",
373 header->signature,
374 ACPI_FORMAT_UINT64(address->pointer.
375 physical),
376 header->length));
377 return (status);
378 }
379
380 /* Save allocation type */
381
382 allocation = ACPI_MEM_MAPPED;
383 break;
384
385 default:
386
387 ACPI_ERROR((AE_INFO, "Invalid address flags %X",
388 address->pointer_type));
389 return_ACPI_STATUS(AE_BAD_PARAMETER);
390 }
391
392 /*
393 * Validate checksum for _most_ tables,
394 * even the ones whose signature we don't recognize
395 */
396 if (table_info->type != ACPI_TABLE_ID_FACS) {
397 status = acpi_tb_verify_table_checksum(full_table);
398
399#if (!ACPI_CHECKSUM_ABORT)
400 if (ACPI_FAILURE(status)) {
401
402 /* Ignore the error if configuration says so */
403
404 status = AE_OK;
405 }
406#endif
407 }
408
409 /* Return values */
410
411 table_info->pointer = full_table;
412 table_info->length = (acpi_size) header->length;
413 table_info->allocation = allocation;
414
415 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
416 "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
417 full_table->signature,
418 ACPI_FORMAT_UINT64(address->pointer.physical),
419 full_table));
420
421 return_ACPI_STATUS(status);
422}
423
424/*******************************************************************************
425 *
426 * FUNCTION: acpi_tb_get_table_ptr
427 *
428 * PARAMETERS: table_type - one of the defined table types
429 * Instance - Which table of this type
430 * return_table - pointer to location to place the pointer for
431 * return
432 *
433 * RETURN: Status
434 *
435 * DESCRIPTION: This function is called to get the pointer to an ACPI table.
436 *
437 ******************************************************************************/
438
439acpi_status
440acpi_tb_get_table_ptr(acpi_table_type table_type,
441 u32 instance, struct acpi_table_header **return_table)
442{
443 struct acpi_table_desc *table_desc;
444 u32 i;
445
446 ACPI_FUNCTION_TRACE(tb_get_table_ptr);
447
448 if (table_type > ACPI_TABLE_ID_MAX) {
449 return_ACPI_STATUS(AE_BAD_PARAMETER);
450 }
451
452 /* Check for instance out of range of the current table count */
453
454 if (instance > acpi_gbl_table_lists[table_type].count) {
455 return_ACPI_STATUS(AE_NOT_EXIST);
456 }
457
458 /*
459 * Walk the list to get the desired table
460 * Note: Instance is one-based
461 */
462 table_desc = acpi_gbl_table_lists[table_type].next;
463 for (i = 1; i < instance; i++) {
464 table_desc = table_desc->next;
465 }
466
467 /* We are now pointing to the requested table's descriptor */
468
469 *return_table = table_desc->pointer;
470 return_ACPI_STATUS(AE_OK);
471}
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
deleted file mode 100644
index ad982112e4c6..000000000000
--- a/drivers/acpi/tables/tbgetall.c
+++ /dev/null
@@ -1,311 +0,0 @@
1/******************************************************************************
2 *
3 * Module Name: tbgetall - Get all required ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbgetall")
49
50/* Local prototypes */
51static acpi_status
52acpi_tb_get_primary_table(struct acpi_pointer *address,
53 struct acpi_table_desc *table_info);
54
55static acpi_status
56acpi_tb_get_secondary_table(struct acpi_pointer *address,
57 acpi_string signature,
58 struct acpi_table_desc *table_info);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_tb_get_primary_table
63 *
64 * PARAMETERS: Address - Physical address of table to retrieve
65 * *table_info - Where the table info is returned
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Maps the physical address of table into a logical address
70 *
71 ******************************************************************************/
72
73static acpi_status
74acpi_tb_get_primary_table(struct acpi_pointer *address,
75 struct acpi_table_desc *table_info)
76{
77 acpi_status status;
78 struct acpi_table_header header;
79
80 ACPI_FUNCTION_TRACE(tb_get_primary_table);
81
82 /* Ignore a NULL address in the RSDT */
83
84 if (!address->pointer.value) {
85 return_ACPI_STATUS(AE_OK);
86 }
87
88 /* Get the header in order to get signature and table size */
89
90 status = acpi_tb_get_table_header(address, &header);
91 if (ACPI_FAILURE(status)) {
92 return_ACPI_STATUS(status);
93 }
94
95 /* Clear the table_info */
96
97 ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc));
98
99 /*
100 * Check the table signature and make sure it is recognized.
101 * Also checks the header checksum
102 */
103 table_info->pointer = &header;
104 status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY);
105 if (ACPI_FAILURE(status)) {
106 return_ACPI_STATUS(status);
107 }
108
109 /* Get the entire table */
110
111 status = acpi_tb_get_table_body(address, &header, table_info);
112 if (ACPI_FAILURE(status)) {
113 return_ACPI_STATUS(status);
114 }
115
116 /* Install the table */
117
118 status = acpi_tb_install_table(table_info);
119 return_ACPI_STATUS(status);
120}
121
122/*******************************************************************************
123 *
124 * FUNCTION: acpi_tb_get_secondary_table
125 *
126 * PARAMETERS: Address - Physical address of table to retrieve
127 * *table_info - Where the table info is returned
128 *
129 * RETURN: Status
130 *
131 * DESCRIPTION: Maps the physical address of table into a logical address
132 *
133 ******************************************************************************/
134
135static acpi_status
136acpi_tb_get_secondary_table(struct acpi_pointer *address,
137 acpi_string signature,
138 struct acpi_table_desc *table_info)
139{
140 acpi_status status;
141 struct acpi_table_header header;
142
143 ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature);
144
145 /* Get the header in order to match the signature */
146
147 status = acpi_tb_get_table_header(address, &header);
148 if (ACPI_FAILURE(status)) {
149 return_ACPI_STATUS(status);
150 }
151
152 /* Signature must match request */
153
154 if (!ACPI_COMPARE_NAME(header.signature, signature)) {
155 ACPI_ERROR((AE_INFO,
156 "Incorrect table signature - wanted [%s] found [%4.4s]",
157 signature, header.signature));
158 return_ACPI_STATUS(AE_BAD_SIGNATURE);
159 }
160
161 /*
162 * Check the table signature and make sure it is recognized.
163 * Also checks the header checksum
164 */
165 table_info->pointer = &header;
166 status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY);
167 if (ACPI_FAILURE(status)) {
168 return_ACPI_STATUS(status);
169 }
170
171 /* Get the entire table */
172
173 status = acpi_tb_get_table_body(address, &header, table_info);
174 if (ACPI_FAILURE(status)) {
175 return_ACPI_STATUS(status);
176 }
177
178 /* Install the table */
179
180 status = acpi_tb_install_table(table_info);
181 return_ACPI_STATUS(status);
182}
183
184/*******************************************************************************
185 *
186 * FUNCTION: acpi_tb_get_required_tables
187 *
188 * PARAMETERS: None
189 *
190 * RETURN: Status
191 *
192 * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
193 * already be loaded and validated.
194 *
195 * Get the minimum set of ACPI tables, namely:
196 *
197 * 1) FADT (via RSDT in loop below)
198 * 2) FACS (via FADT)
199 * 3) DSDT (via FADT)
200 *
201 ******************************************************************************/
202
203acpi_status acpi_tb_get_required_tables(void)
204{
205 acpi_status status = AE_OK;
206 u32 i;
207 struct acpi_table_desc table_info;
208 struct acpi_pointer address;
209
210 ACPI_FUNCTION_TRACE(tb_get_required_tables);
211
212 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
213 acpi_gbl_rsdt_table_count));
214
215 address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
216
217 /*
218 * Loop through all table pointers found in RSDT.
219 * This will NOT include the FACS and DSDT - we must get
220 * them after the loop.
221 *
222 * The only tables we are interested in getting here is the FADT and
223 * any SSDTs.
224 */
225 for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
226
227 /* Get the table address from the common internal XSDT */
228
229 address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
230
231 /*
232 * Get the tables needed by this subsystem (FADT and any SSDTs).
233 * NOTE: All other tables are completely ignored at this time.
234 */
235 status = acpi_tb_get_primary_table(&address, &table_info);
236 if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
237 ACPI_WARNING((AE_INFO,
238 "%s, while getting table at %8.8X%8.8X",
239 acpi_format_exception(status),
240 ACPI_FORMAT_UINT64(address.pointer.
241 value)));
242 }
243 }
244
245 /* We must have a FADT to continue */
246
247 if (!acpi_gbl_FADT) {
248 ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT"));
249 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
250 }
251
252 /*
253 * Convert the FADT to a common format. This allows earlier revisions of
254 * the table to coexist with newer versions, using common access code.
255 */
256 status = acpi_tb_convert_table_fadt();
257 if (ACPI_FAILURE(status)) {
258 ACPI_ERROR((AE_INFO,
259 "Could not convert FADT to internal common format"));
260 return_ACPI_STATUS(status);
261 }
262
263 /* Get the FACS (Pointed to by the FADT) */
264
265 address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
266
267 status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info);
268 if (ACPI_FAILURE(status)) {
269 ACPI_EXCEPTION((AE_INFO, status,
270 "Could not get/install the FACS"));
271 return_ACPI_STATUS(status);
272 }
273
274 /*
275 * Create the common FACS pointer table
276 * (Contains pointers to the original table)
277 */
278 status = acpi_tb_build_common_facs(&table_info);
279 if (ACPI_FAILURE(status)) {
280 return_ACPI_STATUS(status);
281 }
282
283 /* Get/install the DSDT (Pointed to by the FADT) */
284
285 address.pointer.value = acpi_gbl_FADT->Xdsdt;
286
287 status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info);
288 if (ACPI_FAILURE(status)) {
289 ACPI_ERROR((AE_INFO, "Could not get/install the DSDT"));
290 return_ACPI_STATUS(status);
291 }
292
293 /* Set Integer Width (32/64) based upon DSDT revision */
294
295 acpi_ut_set_integer_width(acpi_gbl_DSDT->revision);
296
297 /* Dump the entire DSDT */
298
299 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
300 "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
301 acpi_gbl_DSDT->length, acpi_gbl_DSDT->length,
302 acpi_gbl_integer_bit_width));
303
304 ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT),
305 acpi_gbl_DSDT->length);
306
307 /* Always delete the RSDP mapping, we are done with it */
308
309 acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP);
310 return_ACPI_STATUS(status);
311}
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 1668a232fb67..0e7b121a99ce 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -42,510 +42,498 @@
42 */ 42 */
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acnamesp.h>
45#include <acpi/actables.h> 46#include <acpi/actables.h>
46 47
47#define _COMPONENT ACPI_TABLES 48#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbinstal") 49ACPI_MODULE_NAME("tbinstal")
49 50
50/* Local prototypes */ 51/******************************************************************************
51static acpi_status
52acpi_tb_match_signature(char *signature,
53 struct acpi_table_desc *table_info, u8 search_type);
54
55/*******************************************************************************
56 * 52 *
57 * FUNCTION: acpi_tb_match_signature 53 * FUNCTION: acpi_tb_verify_table
58 * 54 *
59 * PARAMETERS: Signature - Table signature to match 55 * PARAMETERS: table_desc - table
60 * table_info - Return data
61 * search_type - Table type to match (primary/secondary)
62 * 56 *
63 * RETURN: Status 57 * RETURN: Status
64 * 58 *
65 * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" 59 * DESCRIPTION: this function is called to verify and map table
66 * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
67 * 60 *
68 ******************************************************************************/ 61 *****************************************************************************/
69 62acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
70static acpi_status
71acpi_tb_match_signature(char *signature,
72 struct acpi_table_desc *table_info, u8 search_type)
73{ 63{
74 acpi_native_uint i; 64 acpi_status status = AE_OK;
75 65
76 ACPI_FUNCTION_TRACE(tb_match_signature); 66 ACPI_FUNCTION_TRACE(tb_verify_table);
77 67
78 /* Search for a signature match among the known table types */ 68 /* Map the table if necessary */
79 69
80 for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { 70 if (!table_desc->pointer) {
81 if (!(acpi_gbl_table_data[i].flags & search_type)) { 71 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
82 continue; 72 ACPI_TABLE_ORIGIN_MAPPED) {
73 table_desc->pointer =
74 acpi_os_map_memory(table_desc->address,
75 table_desc->length);
83 } 76 }
77 if (!table_desc->pointer) {
78 return_ACPI_STATUS(AE_NO_MEMORY);
79 }
80 }
84 81
85 if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, 82 /* FACS is the odd table, has no standard ACPI header and no checksum */
86 acpi_gbl_table_data[i].sig_length)) {
87
88 /* Found a signature match, return index if requested */
89 83
90 if (table_info) { 84 if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
91 table_info->type = (u8) i;
92 }
93 85
94 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 86 /* Always calculate checksum, ignore bad checksum if requested */
95 "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
96 (char *)acpi_gbl_table_data[i].
97 signature));
98 87
99 return_ACPI_STATUS(AE_OK); 88 status =
100 } 89 acpi_tb_verify_checksum(table_desc->pointer,
90 table_desc->length);
101 } 91 }
102 92
103 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 93 return_ACPI_STATUS(status);
104 "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
105 (char *)signature));
106
107 return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED);
108} 94}
109 95
110/******************************************************************************* 96/*******************************************************************************
111 * 97 *
112 * FUNCTION: acpi_tb_install_table 98 * FUNCTION: acpi_tb_add_table
113 * 99 *
114 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body 100 * PARAMETERS: table_desc - Table descriptor
101 * table_index - Where the table index is returned
115 * 102 *
116 * RETURN: Status 103 * RETURN: Status
117 * 104 *
118 * DESCRIPTION: Install the table into the global data structures. 105 * DESCRIPTION: This function is called to add the ACPI table
119 * 106 *
120 ******************************************************************************/ 107 ******************************************************************************/
121 108
122acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) 109acpi_status
110acpi_tb_add_table(struct acpi_table_desc *table_desc,
111 acpi_native_uint * table_index)
123{ 112{
124 acpi_status status; 113 acpi_native_uint i;
125 114 acpi_native_uint length;
126 ACPI_FUNCTION_TRACE(tb_install_table); 115 acpi_status status = AE_OK;
127 116
128 /* Lock tables while installing */ 117 ACPI_FUNCTION_TRACE(tb_add_table);
129 118
130 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 119 if (!table_desc->pointer) {
131 if (ACPI_FAILURE(status)) { 120 status = acpi_tb_verify_table(table_desc);
132 ACPI_EXCEPTION((AE_INFO, status, 121 if (ACPI_FAILURE(status) || !table_desc->pointer) {
133 "Could not acquire table mutex")); 122 return_ACPI_STATUS(status);
134 return_ACPI_STATUS(status); 123 }
135 } 124 }
136 125
137 /* 126 /* The table must be either an SSDT or a PSDT */
138 * Ignore a table that is already installed. For example, some BIOS 127
139 * ASL code will repeatedly attempt to load the same SSDT. 128 if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
140 */ 129 &&
141 status = acpi_tb_is_table_installed(table_info); 130 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
142 if (ACPI_FAILURE(status)) { 131 {
143 goto unlock_and_exit; 132 ACPI_ERROR((AE_INFO,
133 "Table has invalid signature [%4.4s], must be SSDT or PSDT",
134 table_desc->pointer->signature));
135 return_ACPI_STATUS(AE_BAD_SIGNATURE);
144 } 136 }
145 137
146 /* Install the table into the global data structure */ 138 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
139
140 /* Check if table is already registered */
141
142 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
143 if (!acpi_gbl_root_table_list.tables[i].pointer) {
144 status =
145 acpi_tb_verify_table(&acpi_gbl_root_table_list.
146 tables[i]);
147 if (ACPI_FAILURE(status)
148 || !acpi_gbl_root_table_list.tables[i].pointer) {
149 continue;
150 }
151 }
152
153 length = ACPI_MIN(table_desc->length,
154 acpi_gbl_root_table_list.tables[i].length);
155 if (ACPI_MEMCMP(table_desc->pointer,
156 acpi_gbl_root_table_list.tables[i].pointer,
157 length)) {
158 continue;
159 }
160
161 /* Table is already registered */
162
163 acpi_tb_delete_table(table_desc);
164 *table_index = i;
165 goto release;
166 }
147 167
148 status = acpi_tb_init_table_descriptor(table_info->type, table_info); 168 /*
169 * Add the table to the global table list
170 */
171 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
172 table_desc->length, table_desc->flags,
173 table_index);
149 if (ACPI_FAILURE(status)) { 174 if (ACPI_FAILURE(status)) {
150 ACPI_EXCEPTION((AE_INFO, status, 175 goto release;
151 "Could not install table [%4.4s]",
152 table_info->pointer->signature));
153 } 176 }
154 177
155 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", 178 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
156 acpi_gbl_table_data[table_info->type].name,
157 table_info->pointer));
158 179
159 unlock_and_exit: 180 release:
160 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 181 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
161 return_ACPI_STATUS(status); 182 return_ACPI_STATUS(status);
162} 183}
163 184
164/******************************************************************************* 185/*******************************************************************************
165 * 186 *
166 * FUNCTION: acpi_tb_recognize_table 187 * FUNCTION: acpi_tb_resize_root_table_list
167 * 188 *
168 * PARAMETERS: table_info - Return value from acpi_tb_get_table_body 189 * PARAMETERS: None
169 * search_type - Table type to match (primary/secondary)
170 * 190 *
171 * RETURN: Status 191 * RETURN: Status
172 * 192 *
173 * DESCRIPTION: Check a table signature for a match against known table types 193 * DESCRIPTION: Expand the size of global table array
174 *
175 * NOTE: All table pointers are validated as follows:
176 * 1) Table pointer must point to valid physical memory
177 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
178 * name
179 * 3) Table must be readable for length specified in the header
180 * 4) Table checksum must be valid (with the exception of the FACS
181 * which has no checksum for some odd reason)
182 * 194 *
183 ******************************************************************************/ 195 ******************************************************************************/
184 196
185acpi_status 197acpi_status acpi_tb_resize_root_table_list(void)
186acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type)
187{ 198{
188 struct acpi_table_header *table_header; 199 struct acpi_table_desc *tables;
189 acpi_status status;
190 200
191 ACPI_FUNCTION_TRACE(tb_recognize_table); 201 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
192 202
193 /* Ensure that we have a valid table pointer */ 203 /* allow_resize flag is a parameter to acpi_initialize_tables */
194 204
195 table_header = (struct acpi_table_header *)table_info->pointer; 205 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
196 if (!table_header) { 206 ACPI_ERROR((AE_INFO,
197 return_ACPI_STATUS(AE_BAD_PARAMETER); 207 "Resize of Root Table Array is not allowed"));
208 return_ACPI_STATUS(AE_SUPPORT);
198 } 209 }
199 210
200 /* 211 /* Increase the Table Array size */
201 * We only "recognize" a limited number of ACPI tables -- namely, the 212
202 * ones that are used by the subsystem (DSDT, FADT, etc.) 213 tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
203 * 214 ACPI_ROOT_TABLE_SIZE_INCREMENT)
204 * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. 215 * sizeof(struct acpi_table_desc));
205 * This can be any one of many valid ACPI tables, it just isn't one of 216 if (!tables) {
206 * the tables that is consumed by the core subsystem 217 ACPI_ERROR((AE_INFO,
207 */ 218 "Could not allocate new root table array"));
208 status = acpi_tb_match_signature(table_header->signature, 219 return_ACPI_STATUS(AE_NO_MEMORY);
209 table_info, search_type);
210 if (ACPI_FAILURE(status)) {
211 return_ACPI_STATUS(status);
212 } 220 }
213 221
214 status = acpi_tb_validate_table_header(table_header); 222 /* Copy and free the previous table array */
215 if (ACPI_FAILURE(status)) { 223
216 return_ACPI_STATUS(status); 224 if (acpi_gbl_root_table_list.tables) {
225 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
226 acpi_gbl_root_table_list.size *
227 sizeof(struct acpi_table_desc));
228
229 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
230 ACPI_FREE(acpi_gbl_root_table_list.tables);
231 }
217 } 232 }
218 233
219 /* Return the table type and length via the info struct */ 234 acpi_gbl_root_table_list.tables = tables;
235 acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
236 acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
220 237
221 table_info->length = (acpi_size) table_header->length; 238 return_ACPI_STATUS(AE_OK);
222 return_ACPI_STATUS(status);
223} 239}
224 240
225/******************************************************************************* 241/*******************************************************************************
226 * 242 *
227 * FUNCTION: acpi_tb_init_table_descriptor 243 * FUNCTION: acpi_tb_store_table
228 * 244 *
229 * PARAMETERS: table_type - The type of the table 245 * PARAMETERS: Address - Table address
230 * table_info - A table info struct 246 * Table - Table header
247 * Length - Table length
248 * Flags - flags
231 * 249 *
232 * RETURN: None. 250 * RETURN: Status and table index.
233 * 251 *
234 * DESCRIPTION: Install a table into the global data structs. 252 * DESCRIPTION: Add an ACPI table to the global table list
235 * 253 *
236 ******************************************************************************/ 254 ******************************************************************************/
237 255
238acpi_status 256acpi_status
239acpi_tb_init_table_descriptor(acpi_table_type table_type, 257acpi_tb_store_table(acpi_physical_address address,
240 struct acpi_table_desc *table_info) 258 struct acpi_table_header *table,
259 u32 length, u8 flags, acpi_native_uint * table_index)
241{ 260{
242 struct acpi_table_list *list_head; 261 acpi_status status = AE_OK;
243 struct acpi_table_desc *table_desc;
244 acpi_status status;
245
246 ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type);
247 262
248 /* Allocate a descriptor for this table */ 263 /* Ensure that there is room for the table in the Root Table List */
249 264
250 table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); 265 if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
251 if (!table_desc) { 266 status = acpi_tb_resize_root_table_list();
252 return_ACPI_STATUS(AE_NO_MEMORY); 267 if (ACPI_FAILURE(status)) {
268 return (status);
269 }
253 } 270 }
254 271
255 /* Get a new owner ID for the table */ 272 /* Initialize added table */
273
274 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
275 address = address;
276 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
277 pointer = table;
278 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
279 length;
280 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
281 owner_id = 0;
282 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
283 flags;
284
285 ACPI_MOVE_32_TO_32(&
286 (acpi_gbl_root_table_list.
287 tables[acpi_gbl_root_table_list.count].signature),
288 table->signature);
289
290 *table_index = acpi_gbl_root_table_list.count;
291 acpi_gbl_root_table_list.count++;
292 return (status);
293}
256 294
257 status = acpi_ut_allocate_owner_id(&table_desc->owner_id); 295/*******************************************************************************
258 if (ACPI_FAILURE(status)) { 296 *
259 goto error_exit1; 297 * FUNCTION: acpi_tb_delete_table
260 } 298 *
299 * PARAMETERS: table_index - Table index
300 *
301 * RETURN: None
302 *
303 * DESCRIPTION: Delete one internal ACPI table
304 *
305 ******************************************************************************/
261 306
262 /* Install the table into the global data structure */ 307void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
308{
309 /* Table must be mapped or allocated */
310 if (!table_desc->pointer) {
311 return;
312 }
313 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
314 case ACPI_TABLE_ORIGIN_MAPPED:
315 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
316 break;
317 case ACPI_TABLE_ORIGIN_ALLOCATED:
318 ACPI_FREE(table_desc->pointer);
319 break;
320 default:;
321 }
263 322
264 list_head = &acpi_gbl_table_lists[table_type]; 323 table_desc->pointer = NULL;
324}
265 325
266 /* 326/*******************************************************************************
267 * Two major types of tables: 1) Only one instance is allowed. This 327 *
268 * includes most ACPI tables such as the DSDT. 2) Multiple instances of 328 * FUNCTION: acpi_tb_terminate
269 * the table are allowed. This includes SSDT and PSDTs. 329 *
270 */ 330 * PARAMETERS: None
271 if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { 331 *
272 /* 332 * RETURN: None
273 * Only one table allowed, and a table has alread been installed 333 *
274 * at this location, so return an error. 334 * DESCRIPTION: Delete all internal ACPI tables
275 */ 335 *
276 if (list_head->next) { 336 ******************************************************************************/
277 status = AE_ALREADY_EXISTS;
278 goto error_exit2;
279 }
280 337
281 table_desc->next = list_head->next; 338void acpi_tb_terminate(void)
282 list_head->next = table_desc; 339{
340 acpi_native_uint i;
283 341
284 if (table_desc->next) { 342 ACPI_FUNCTION_TRACE(tb_terminate);
285 table_desc->next->prev = table_desc;
286 }
287 343
288 list_head->count++; 344 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
289 } else {
290 /*
291 * Link the new table in to the list of tables of this type.
292 * Insert at the end of the list, order IS IMPORTANT.
293 *
294 * table_desc->Prev & Next are already NULL from calloc()
295 */
296 list_head->count++;
297
298 if (!list_head->next) {
299 list_head->next = table_desc;
300 } else {
301 table_desc->next = list_head->next;
302 345
303 while (table_desc->next->next) { 346 /* Delete the individual tables */
304 table_desc->next = table_desc->next->next;
305 }
306 347
307 table_desc->next->next = table_desc; 348 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
308 table_desc->prev = table_desc->next; 349 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
309 table_desc->next = NULL;
310 }
311 } 350 }
312 351
313 /* Finish initialization of the table descriptor */
314
315 table_desc->loaded_into_namespace = FALSE;
316 table_desc->type = (u8) table_type;
317 table_desc->pointer = table_info->pointer;
318 table_desc->length = table_info->length;
319 table_desc->allocation = table_info->allocation;
320 table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
321 table_desc->aml_length = (u32)
322 (table_desc->length - (u32) sizeof(struct acpi_table_header));
323
324 /* 352 /*
325 * Set the appropriate global pointer (if there is one) to point to the 353 * Delete the root table array if allocated locally. Array cannot be
326 * newly installed table 354 * mapped, so we don't need to check for that flag.
327 */ 355 */
328 if (acpi_gbl_table_data[table_type].global_ptr) { 356 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
329 *(acpi_gbl_table_data[table_type].global_ptr) = 357 ACPI_FREE(acpi_gbl_root_table_list.tables);
330 table_info->pointer;
331 } 358 }
332 359
333 /* Return Data */ 360 acpi_gbl_root_table_list.tables = NULL;
334 361 acpi_gbl_root_table_list.flags = 0;
335 table_info->owner_id = table_desc->owner_id; 362 acpi_gbl_root_table_list.count = 0;
336 table_info->installed_desc = table_desc;
337 return_ACPI_STATUS(AE_OK);
338
339 /* Error exit with cleanup */
340
341 error_exit2:
342
343 acpi_ut_release_owner_id(&table_desc->owner_id);
344 363
345 error_exit1: 364 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
346 365 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
347 ACPI_FREE(table_desc);
348 return_ACPI_STATUS(status);
349} 366}
350 367
351/******************************************************************************* 368/*******************************************************************************
352 * 369 *
353 * FUNCTION: acpi_tb_delete_all_tables 370 * FUNCTION: acpi_tb_delete_namespace_by_owner
354 * 371 *
355 * PARAMETERS: None. 372 * PARAMETERS: table_index - Table index
356 * 373 *
357 * RETURN: None. 374 * RETURN: None
358 * 375 *
359 * DESCRIPTION: Delete all internal ACPI tables 376 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
360 * 377 *
361 ******************************************************************************/ 378 ******************************************************************************/
362 379
363void acpi_tb_delete_all_tables(void) 380void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
364{ 381{
365 acpi_table_type type; 382 acpi_owner_id owner_id;
366 383
367 /* 384 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
368 * Free memory allocated for ACPI tables 385 if (table_index < acpi_gbl_root_table_list.count) {
369 * Memory can either be mapped or allocated 386 owner_id =
370 */ 387 acpi_gbl_root_table_list.tables[table_index].owner_id;
371 for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { 388 } else {
372 acpi_tb_delete_tables_by_type(type); 389 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
390 return;
373 } 391 }
392
393 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
394 acpi_ns_delete_namespace_by_owner(owner_id);
374} 395}
375 396
376/******************************************************************************* 397/*******************************************************************************
377 * 398 *
378 * FUNCTION: acpi_tb_delete_tables_by_type 399 * FUNCTION: acpi_tb_allocate_owner_id
379 * 400 *
380 * PARAMETERS: Type - The table type to be deleted 401 * PARAMETERS: table_index - Table index
381 * 402 *
382 * RETURN: None. 403 * RETURN: Status
383 * 404 *
384 * DESCRIPTION: Delete an internal ACPI table 405 * DESCRIPTION: Allocates owner_id in table_desc
385 * Locks the ACPI table mutex
386 * 406 *
387 ******************************************************************************/ 407 ******************************************************************************/
388 408
389void acpi_tb_delete_tables_by_type(acpi_table_type type) 409acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
390{ 410{
391 struct acpi_table_desc *table_desc; 411 acpi_status status = AE_BAD_PARAMETER;
392 u32 count;
393 u32 i;
394 412
395 ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); 413 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
396 414
397 if (type > ACPI_TABLE_ID_MAX) { 415 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
398 return_VOID; 416 if (table_index < acpi_gbl_root_table_list.count) {
399 } 417 status = acpi_ut_allocate_owner_id
400 418 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
401 if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) {
402 return;
403 }
404
405 /* Clear the appropriate "typed" global table pointer */
406
407 switch (type) {
408 case ACPI_TABLE_ID_RSDP:
409 acpi_gbl_RSDP = NULL;
410 break;
411
412 case ACPI_TABLE_ID_DSDT:
413 acpi_gbl_DSDT = NULL;
414 break;
415
416 case ACPI_TABLE_ID_FADT:
417 acpi_gbl_FADT = NULL;
418 break;
419
420 case ACPI_TABLE_ID_FACS:
421 acpi_gbl_FACS = NULL;
422 break;
423
424 case ACPI_TABLE_ID_XSDT:
425 acpi_gbl_XSDT = NULL;
426 break;
427
428 case ACPI_TABLE_ID_SSDT:
429 case ACPI_TABLE_ID_PSDT:
430 default:
431 break;
432 }
433
434 /*
435 * Free the table
436 * 1) Get the head of the list
437 */
438 table_desc = acpi_gbl_table_lists[type].next;
439 count = acpi_gbl_table_lists[type].count;
440
441 /*
442 * 2) Walk the entire list, deleting both the allocated tables
443 * and the table descriptors
444 */
445 for (i = 0; i < count; i++) {
446 table_desc = acpi_tb_uninstall_table(table_desc);
447 } 419 }
448 420
449 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 421 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
450 return_VOID; 422 return_ACPI_STATUS(status);
451} 423}
452 424
453/******************************************************************************* 425/*******************************************************************************
454 * 426 *
455 * FUNCTION: acpi_tb_delete_single_table 427 * FUNCTION: acpi_tb_release_owner_id
456 * 428 *
457 * PARAMETERS: table_info - A table info struct 429 * PARAMETERS: table_index - Table index
458 * 430 *
459 * RETURN: None. 431 * RETURN: Status
460 * 432 *
461 * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where 433 * DESCRIPTION: Releases owner_id in table_desc
462 * the table was allocated a buffer or was mapped.
463 * 434 *
464 ******************************************************************************/ 435 ******************************************************************************/
465 436
466void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) 437acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
467{ 438{
439 acpi_status status = AE_BAD_PARAMETER;
468 440
469 /* Must have a valid table descriptor and pointer */ 441 ACPI_FUNCTION_TRACE(tb_release_owner_id);
470 442
471 if ((!table_desc) || (!table_desc->pointer)) { 443 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
472 return; 444 if (table_index < acpi_gbl_root_table_list.count) {
445 acpi_ut_release_owner_id(&
446 (acpi_gbl_root_table_list.
447 tables[table_index].owner_id));
448 status = AE_OK;
473 } 449 }
474 450
475 /* Valid table, determine type of memory allocation */ 451 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
476 452 return_ACPI_STATUS(status);
477 switch (table_desc->allocation) {
478 case ACPI_MEM_NOT_ALLOCATED:
479 break;
480
481 case ACPI_MEM_ALLOCATED:
482
483 ACPI_FREE(table_desc->pointer);
484 break;
485
486 case ACPI_MEM_MAPPED:
487
488 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
489 break;
490
491 default:
492 break;
493 }
494} 453}
495 454
496/******************************************************************************* 455/*******************************************************************************
497 * 456 *
498 * FUNCTION: acpi_tb_uninstall_table 457 * FUNCTION: acpi_tb_get_owner_id
499 * 458 *
500 * PARAMETERS: table_info - A table info struct 459 * PARAMETERS: table_index - Table index
460 * owner_id - Where the table owner_id is returned
501 * 461 *
502 * RETURN: Pointer to the next table in the list (of same type) 462 * RETURN: Status
503 * 463 *
504 * DESCRIPTION: Free the memory associated with an internal ACPI table that 464 * DESCRIPTION: returns owner_id for the ACPI table
505 * is either installed or has never been installed.
506 * Table mutex should be locked.
507 * 465 *
508 ******************************************************************************/ 466 ******************************************************************************/
509 467
510struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc 468acpi_status
511 *table_desc) 469acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
512{ 470{
513 struct acpi_table_desc *next_desc; 471 acpi_status status = AE_BAD_PARAMETER;
514 472
515 ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); 473 ACPI_FUNCTION_TRACE(tb_get_owner_id);
516 474
517 if (!table_desc) { 475 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
518 return_PTR(NULL); 476 if (table_index < acpi_gbl_root_table_list.count) {
477 *owner_id =
478 acpi_gbl_root_table_list.tables[table_index].owner_id;
479 status = AE_OK;
519 } 480 }
520 481
521 /* Unlink the descriptor from the doubly linked list */ 482 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
483 return_ACPI_STATUS(status);
484}
522 485
523 if (table_desc->prev) { 486/*******************************************************************************
524 table_desc->prev->next = table_desc->next; 487 *
525 } else { 488 * FUNCTION: acpi_tb_is_table_loaded
526 /* Is first on list, update list head */ 489 *
490 * PARAMETERS: table_index - Table index
491 *
492 * RETURN: Table Loaded Flag
493 *
494 ******************************************************************************/
527 495
528 acpi_gbl_table_lists[table_desc->type].next = table_desc->next; 496u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
529 } 497{
498 u8 is_loaded = FALSE;
530 499
531 if (table_desc->next) { 500 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
532 table_desc->next->prev = table_desc->prev; 501 if (table_index < acpi_gbl_root_table_list.count) {
502 is_loaded = (u8)
503 (acpi_gbl_root_table_list.tables[table_index].
504 flags & ACPI_TABLE_IS_LOADED);
533 } 505 }
534 506
535 /* Free the memory allocated for the table itself */ 507 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
536 508 return (is_loaded);
537 acpi_tb_delete_single_table(table_desc); 509}
538
539 /* Free the owner ID associated with this table */
540
541 acpi_ut_release_owner_id(&table_desc->owner_id);
542 510
543 /* Free the table descriptor */ 511/*******************************************************************************
512 *
513 * FUNCTION: acpi_tb_set_table_loaded_flag
514 *
515 * PARAMETERS: table_index - Table index
516 * is_loaded - TRUE if table is loaded, FALSE otherwise
517 *
518 * RETURN: None
519 *
520 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
521 *
522 ******************************************************************************/
544 523
545 next_desc = table_desc->next; 524void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
546 ACPI_FREE(table_desc); 525{
547 526
548 /* Return pointer to the next descriptor */ 527 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
528 if (table_index < acpi_gbl_root_table_list.count) {
529 if (is_loaded) {
530 acpi_gbl_root_table_list.tables[table_index].flags |=
531 ACPI_TABLE_IS_LOADED;
532 } else {
533 acpi_gbl_root_table_list.tables[table_index].flags &=
534 ~ACPI_TABLE_IS_LOADED;
535 }
536 }
549 537
550 return_PTR(next_desc); 538 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
551} 539}
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
deleted file mode 100644
index 86a5fca9b739..000000000000
--- a/drivers/acpi/tables/tbrsdt.c
+++ /dev/null
@@ -1,307 +0,0 @@
1/******************************************************************************
2 *
3 * Module Name: tbrsdt - ACPI RSDT table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include <acpi/actables.h>
46
47#define _COMPONENT ACPI_TABLES
48ACPI_MODULE_NAME("tbrsdt")
49
50/*******************************************************************************
51 *
52 * FUNCTION: acpi_tb_verify_rsdp
53 *
54 * PARAMETERS: Address - RSDP (Pointer to RSDT)
55 *
56 * RETURN: Status
57 *
58 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
59 *
60 ******************************************************************************/
61acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address)
62{
63 struct acpi_table_desc table_info;
64 acpi_status status;
65 struct rsdp_descriptor *rsdp;
66
67 ACPI_FUNCTION_TRACE(tb_verify_rsdp);
68
69 switch (address->pointer_type) {
70 case ACPI_LOGICAL_POINTER:
71
72 rsdp = address->pointer.logical;
73 break;
74
75 case ACPI_PHYSICAL_POINTER:
76 /*
77 * Obtain access to the RSDP structure
78 */
79 status = acpi_os_map_memory(address->pointer.physical,
80 sizeof(struct rsdp_descriptor),
81 ACPI_CAST_PTR(void, &rsdp));
82 if (ACPI_FAILURE(status)) {
83 return_ACPI_STATUS(status);
84 }
85 break;
86
87 default:
88 return_ACPI_STATUS(AE_BAD_PARAMETER);
89 }
90
91 /* Verify RSDP signature and checksum */
92
93 status = acpi_tb_validate_rsdp(rsdp);
94 if (ACPI_FAILURE(status)) {
95 goto cleanup;
96 }
97
98 /* RSDP is ok. Init the table info */
99
100 table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp);
101 table_info.length = sizeof(struct rsdp_descriptor);
102
103 if (address->pointer_type == ACPI_PHYSICAL_POINTER) {
104 table_info.allocation = ACPI_MEM_MAPPED;
105 } else {
106 table_info.allocation = ACPI_MEM_NOT_ALLOCATED;
107 }
108
109 /* Save the table pointers and allocation info */
110
111 status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info);
112 if (ACPI_FAILURE(status)) {
113 goto cleanup;
114 }
115
116 /* Save the RSDP in a global for easy access */
117
118 acpi_gbl_RSDP =
119 ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer);
120 return_ACPI_STATUS(status);
121
122 /* Error exit */
123 cleanup:
124
125 if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
126 acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor));
127 }
128 return_ACPI_STATUS(status);
129}
130
131/*******************************************************************************
132 *
133 * FUNCTION: acpi_tb_get_rsdt_address
134 *
135 * PARAMETERS: out_address - Where the address is returned
136 *
137 * RETURN: None, Address
138 *
139 * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the
140 * version of the RSDP and whether the XSDT pointer is valid
141 *
142 ******************************************************************************/
143
144void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address)
145{
146
147 ACPI_FUNCTION_ENTRY();
148
149 out_address->pointer_type =
150 acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
151
152 /* Use XSDT if it is present */
153
154 if ((acpi_gbl_RSDP->revision >= 2) &&
155 acpi_gbl_RSDP->xsdt_physical_address) {
156 out_address->pointer.value =
157 acpi_gbl_RSDP->xsdt_physical_address;
158 acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT;
159 } else {
160 /* No XSDT, use the RSDT */
161
162 out_address->pointer.value =
163 acpi_gbl_RSDP->rsdt_physical_address;
164 acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT;
165 }
166}
167
168/*******************************************************************************
169 *
170 * FUNCTION: acpi_tb_validate_rsdt
171 *
172 * PARAMETERS: table_ptr - Addressable pointer to the RSDT.
173 *
174 * RETURN: Status
175 *
176 * DESCRIPTION: Validate signature for the RSDT or XSDT
177 *
178 ******************************************************************************/
179
180acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
181{
182 char *signature;
183
184 ACPI_FUNCTION_ENTRY();
185
186 /* Validate minimum length */
187
188 if (table_ptr->length < sizeof(struct acpi_table_header)) {
189 ACPI_ERROR((AE_INFO,
190 "RSDT/XSDT length (%X) is smaller than minimum (%zX)",
191 table_ptr->length,
192 sizeof(struct acpi_table_header)));
193
194 return (AE_INVALID_TABLE_LENGTH);
195 }
196
197 /* Search for appropriate signature, RSDT or XSDT */
198
199 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
200 signature = RSDT_SIG;
201 } else {
202 signature = XSDT_SIG;
203 }
204
205 if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) {
206
207 /* Invalid RSDT or XSDT signature */
208
209 ACPI_ERROR((AE_INFO,
210 "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:"));
211
212 ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);
213
214 ACPI_ERROR((AE_INFO,
215 "RSDT/XSDT signature at %X is invalid",
216 acpi_gbl_RSDP->rsdt_physical_address));
217
218 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
219 ACPI_ERROR((AE_INFO, "Looking for RSDT"));
220 } else {
221 ACPI_ERROR((AE_INFO, "Looking for XSDT"));
222 }
223
224 ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48);
225 return (AE_BAD_SIGNATURE);
226 }
227
228 return (AE_OK);
229}
230
231/*******************************************************************************
232 *
233 * FUNCTION: acpi_tb_get_table_rsdt
234 *
235 * PARAMETERS: None
236 *
237 * RETURN: Status
238 *
239 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
240 *
241 ******************************************************************************/
242
243acpi_status acpi_tb_get_table_rsdt(void)
244{
245 struct acpi_table_desc table_info;
246 acpi_status status;
247 struct acpi_pointer address;
248
249 ACPI_FUNCTION_TRACE(tb_get_table_rsdt);
250
251 /* Get the RSDT/XSDT via the RSDP */
252
253 acpi_tb_get_rsdt_address(&address);
254
255 table_info.type = ACPI_TABLE_ID_XSDT;
256 status = acpi_tb_get_table(&address, &table_info);
257 if (ACPI_FAILURE(status)) {
258 ACPI_EXCEPTION((AE_INFO, status,
259 "Could not get the RSDT/XSDT"));
260 return_ACPI_STATUS(status);
261 }
262
263 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
264 "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n",
265 acpi_gbl_RSDP,
266 ACPI_FORMAT_UINT64(address.pointer.value)));
267
268 /* Check the RSDT or XSDT signature */
269
270 status = acpi_tb_validate_rsdt(table_info.pointer);
271 if (ACPI_FAILURE(status)) {
272 goto error_cleanup;
273 }
274
275 /* Get the number of tables defined in the RSDT or XSDT */
276
277 acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP,
278 table_info.pointer);
279
280 /* Convert and/or copy to an XSDT structure */
281
282 status = acpi_tb_convert_to_xsdt(&table_info);
283 if (ACPI_FAILURE(status)) {
284 goto error_cleanup;
285 }
286
287 /* Save the table pointers and allocation info */
288
289 status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info);
290 if (ACPI_FAILURE(status)) {
291 goto error_cleanup;
292 }
293
294 acpi_gbl_XSDT =
295 ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer);
296
297 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
298 return_ACPI_STATUS(status);
299
300 error_cleanup:
301
302 /* Free table allocated by acpi_tb_get_table */
303
304 acpi_tb_delete_single_table(&table_info);
305
306 return_ACPI_STATUS(status);
307}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 209a401801e3..1da64b4518c0 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -1,11 +1,11 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Module Name: tbutils - Table manipulation utilities 3 * Module Name: tbutils - table utilities
4 * 4 *
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,137 +48,119 @@
48ACPI_MODULE_NAME("tbutils") 48ACPI_MODULE_NAME("tbutils")
49 49
50/* Local prototypes */ 50/* Local prototypes */
51#ifdef ACPI_OBSOLETE_FUNCTIONS 51static acpi_physical_address
52acpi_status 52acpi_tb_get_root_table_entry(u8 * table_entry,
53acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); 53 acpi_native_uint table_entry_size);
54#endif
55 54
56/******************************************************************************* 55/*******************************************************************************
57 * 56 *
58 * FUNCTION: acpi_tb_is_table_installed 57 * FUNCTION: acpi_tb_tables_loaded
59 *
60 * PARAMETERS: new_table_desc - Descriptor for new table being installed
61 * 58 *
62 * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed 59 * PARAMETERS: None
63 * 60 *
64 * DESCRIPTION: Determine if an ACPI table is already installed 61 * RETURN: TRUE if required ACPI tables are loaded
65 * 62 *
66 * MUTEX: Table data structures should be locked 63 * DESCRIPTION: Determine if the minimum required ACPI tables are present
64 * (FADT, FACS, DSDT)
67 * 65 *
68 ******************************************************************************/ 66 ******************************************************************************/
69 67
70acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) 68u8 acpi_tb_tables_loaded(void)
71{ 69{
72 struct acpi_table_desc *table_desc;
73
74 ACPI_FUNCTION_TRACE(tb_is_table_installed);
75 70
76 /* Get the list descriptor and first table descriptor */ 71 if (acpi_gbl_root_table_list.count >= 3) {
77 72 return (TRUE);
78 table_desc = acpi_gbl_table_lists[new_table_desc->type].next; 73 }
79 74
80 /* Examine all installed tables of this type */ 75 return (FALSE);
76}
81 77
82 while (table_desc) { 78/*******************************************************************************
83 /* 79 *
84 * If the table lengths match, perform a full bytewise compare. This 80 * FUNCTION: acpi_tb_print_table_header
85 * means that we will allow tables with duplicate oem_table_id(s), as 81 *
86 * long as the tables are different in some way. 82 * PARAMETERS: Address - Table physical address
87 * 83 * Header - Table header
88 * Checking if the table has been loaded into the namespace means that 84 *
89 * we don't check for duplicate tables during the initial installation 85 * RETURN: None
90 * of tables within the RSDT/XSDT. 86 *
91 */ 87 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
92 if ((table_desc->loaded_into_namespace) && 88 *
93 (table_desc->pointer->length == 89 ******************************************************************************/
94 new_table_desc->pointer->length)
95 &&
96 (!ACPI_MEMCMP
97 (table_desc->pointer, new_table_desc->pointer,
98 new_table_desc->pointer->length))) {
99
100 /* Match: this table is already installed */
101
102 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
103 "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n",
104 new_table_desc->pointer->signature,
105 new_table_desc->pointer->revision,
106 new_table_desc->pointer->
107 oem_table_id));
108
109 new_table_desc->owner_id = table_desc->owner_id;
110 new_table_desc->installed_desc = table_desc;
111
112 return_ACPI_STATUS(AE_ALREADY_EXISTS);
113 }
114 90
115 /* Get next table on the list */ 91void
92acpi_tb_print_table_header(acpi_physical_address address,
93 struct acpi_table_header *header)
94{
116 95
117 table_desc = table_desc->next; 96 if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
97
98 /* FACS only has signature and length fields of common table header */
99
100 ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
101 header->signature, (unsigned long)address,
102 header->length));
103 } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
104
105 /* RSDP has no common fields */
106
107 ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
108 (unsigned long)address,
109 (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
110 revision >
111 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
112 header)->length : 20,
113 ACPI_CAST_PTR(struct acpi_table_rsdp,
114 header)->revision,
115 ACPI_CAST_PTR(struct acpi_table_rsdp,
116 header)->oem_id));
117 } else {
118 /* Standard ACPI table with full common header */
119
120 ACPI_INFO((AE_INFO,
121 "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
122 header->signature, (unsigned long)address,
123 header->length, header->revision, header->oem_id,
124 header->oem_table_id, header->oem_revision,
125 header->asl_compiler_id,
126 header->asl_compiler_revision));
118 } 127 }
119
120 return_ACPI_STATUS(AE_OK);
121} 128}
122 129
123/******************************************************************************* 130/*******************************************************************************
124 * 131 *
125 * FUNCTION: acpi_tb_validate_table_header 132 * FUNCTION: acpi_tb_validate_checksum
126 * 133 *
127 * PARAMETERS: table_header - Logical pointer to the table 134 * PARAMETERS: Table - ACPI table to verify
135 * Length - Length of entire table
128 * 136 *
129 * RETURN: Status 137 * RETURN: Status
130 * 138 *
131 * DESCRIPTION: Check an ACPI table header for validity 139 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
132 * 140 * exception on bad checksum.
133 * NOTE: Table pointers are validated as follows:
134 * 1) Table pointer must point to valid physical memory
135 * 2) Signature must be 4 ASCII chars, even if we don't recognize the
136 * name
137 * 3) Table must be readable for length specified in the header
138 * 4) Table checksum must be valid (with the exception of the FACS
139 * which has no checksum because it contains variable fields)
140 * 141 *
141 ******************************************************************************/ 142 ******************************************************************************/
142 143
143acpi_status 144acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
144acpi_tb_validate_table_header(struct acpi_table_header *table_header)
145{ 145{
146 acpi_name signature; 146 u8 checksum;
147
148 ACPI_FUNCTION_ENTRY();
149
150 /* Verify that this is a valid address */
151
152 if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) {
153 ACPI_ERROR((AE_INFO,
154 "Cannot read table header at %p", table_header));
155
156 return (AE_BAD_ADDRESS);
157 }
158 147
159 /* Ensure that the signature is 4 ASCII characters */ 148 /* Compute the checksum on the table */
160 149
161 ACPI_MOVE_32_TO_32(&signature, table_header->signature); 150 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
162 if (!acpi_ut_valid_acpi_name(signature)) {
163 ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X",
164 signature));
165 151
166 ACPI_DUMP_BUFFER(table_header, 152 /* Checksum ok? (should be zero) */
167 sizeof(struct acpi_table_header));
168 return (AE_BAD_SIGNATURE);
169 }
170 153
171 /* Validate the table length */ 154 if (checksum) {
155 ACPI_WARNING((AE_INFO,
156 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
157 table->signature, table->checksum,
158 (u8) (table->checksum - checksum)));
172 159
173 if (table_header->length < sizeof(struct acpi_table_header)) { 160#if (ACPI_CHECKSUM_ABORT)
174 ACPI_ERROR((AE_INFO,
175 "Invalid length 0x%X in table with signature %4.4s",
176 (u32) table_header->length,
177 ACPI_CAST_PTR(char, &signature)));
178 161
179 ACPI_DUMP_BUFFER(table_header, 162 return (AE_BAD_CHECKSUM);
180 sizeof(struct acpi_table_header)); 163#endif
181 return (AE_BAD_HEADER);
182 } 164 }
183 165
184 return (AE_OK); 166 return (AE_OK);
@@ -186,157 +168,320 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header)
186 168
187/******************************************************************************* 169/*******************************************************************************
188 * 170 *
189 * FUNCTION: acpi_tb_sum_table 171 * FUNCTION: acpi_tb_checksum
190 * 172 *
191 * PARAMETERS: Buffer - Buffer to sum 173 * PARAMETERS: Buffer - Pointer to memory region to be checked
192 * Length - Size of the buffer 174 * Length - Length of this memory region
193 * 175 *
194 * RETURN: 8 bit sum of buffer 176 * RETURN: Checksum (u8)
195 * 177 *
196 * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. 178 * DESCRIPTION: Calculates circular checksum of memory region.
197 * 179 *
198 ******************************************************************************/ 180 ******************************************************************************/
199 181
200u8 acpi_tb_sum_table(void *buffer, u32 length) 182u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
201{ 183{
202 acpi_native_uint i;
203 u8 sum = 0; 184 u8 sum = 0;
185 u8 *end = buffer + length;
204 186
205 if (!buffer || !length) { 187 while (buffer < end) {
206 return (0); 188 sum = (u8) (sum + *(buffer++));
207 } 189 }
208 190
209 for (i = 0; i < length; i++) { 191 return sum;
210 sum = (u8) (sum + ((u8 *) buffer)[i]);
211 }
212 return (sum);
213} 192}
214 193
215/******************************************************************************* 194/*******************************************************************************
216 * 195 *
217 * FUNCTION: acpi_tb_generate_checksum 196 * FUNCTION: acpi_tb_install_table
218 * 197 *
219 * PARAMETERS: Table - Pointer to a valid ACPI table (with a 198 * PARAMETERS: Address - Physical address of DSDT or FACS
220 * standard ACPI header) 199 * Flags - Flags
200 * Signature - Table signature, NULL if no need to
201 * match
202 * table_index - Index into root table array
221 * 203 *
222 * RETURN: 8 bit checksum of buffer 204 * RETURN: None
223 * 205 *
224 * DESCRIPTION: Computes an 8 bit checksum of the table. 206 * DESCRIPTION: Install an ACPI table into the global data structure.
225 * 207 *
226 ******************************************************************************/ 208 ******************************************************************************/
227 209
228u8 acpi_tb_generate_checksum(struct acpi_table_header * table) 210void
211acpi_tb_install_table(acpi_physical_address address,
212 u8 flags, char *signature, acpi_native_uint table_index)
229{ 213{
230 u8 checksum; 214 struct acpi_table_header *table;
215
216 if (!address) {
217 ACPI_ERROR((AE_INFO,
218 "Null physical address for ACPI table [%s]",
219 signature));
220 return;
221 }
222
223 /* Map just the table header */
224
225 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
226 if (!table) {
227 return;
228 }
229
230 /* If a particular signature is expected, signature must match */
231
232 if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
233 ACPI_ERROR((AE_INFO,
234 "Invalid signature 0x%X for ACPI table [%s]",
235 *ACPI_CAST_PTR(u32, table->signature), signature));
236 goto unmap_and_exit;
237 }
231 238
232 /* Sum the entire table as-is */ 239 /* Initialize the table entry */
233 240
234 checksum = acpi_tb_sum_table(table, table->length); 241 acpi_gbl_root_table_list.tables[table_index].address = address;
242 acpi_gbl_root_table_list.tables[table_index].length = table->length;
243 acpi_gbl_root_table_list.tables[table_index].flags = flags;
235 244
236 /* Subtract off the existing checksum value in the table */ 245 ACPI_MOVE_32_TO_32(&
246 (acpi_gbl_root_table_list.tables[table_index].
247 signature), table->signature);
237 248
238 checksum = (u8) (checksum - table->checksum); 249 acpi_tb_print_table_header(address, table);
239 250
240 /* Compute the final checksum */ 251 if (table_index == ACPI_TABLE_INDEX_DSDT) {
241 252
242 checksum = (u8) (0 - checksum); 253 /* Global integer width is based upon revision of the DSDT */
243 return (checksum); 254
255 acpi_ut_set_integer_width(table->revision);
256 }
257
258 unmap_and_exit:
259 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
244} 260}
245 261
246/******************************************************************************* 262/*******************************************************************************
247 * 263 *
248 * FUNCTION: acpi_tb_set_checksum 264 * FUNCTION: acpi_tb_get_root_table_entry
249 * 265 *
250 * PARAMETERS: Table - Pointer to a valid ACPI table (with a 266 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry
251 * standard ACPI header) 267 * table_entry_size - sizeof 32 or 64 (RSDT or XSDT)
252 * 268 *
253 * RETURN: None. Sets the table checksum field 269 * RETURN: Physical address extracted from the root table
254 * 270 *
255 * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the 271 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
256 * checksum into the table header. 272 * both 32-bit and 64-bit platforms
273 *
274 * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
275 * 64-bit platforms.
257 * 276 *
258 ******************************************************************************/ 277 ******************************************************************************/
259 278
260void acpi_tb_set_checksum(struct acpi_table_header *table) 279static acpi_physical_address
280acpi_tb_get_root_table_entry(u8 * table_entry,
281 acpi_native_uint table_entry_size)
261{ 282{
283 u64 address64;
284
285 /*
286 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
287 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
288 */
289 if (table_entry_size == sizeof(u32)) {
290 /*
291 * 32-bit platform, RSDT: Return 32-bit table entry
292 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
293 */
294 return ((acpi_physical_address)
295 (*ACPI_CAST_PTR(u32, table_entry)));
296 } else {
297 /*
298 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
299 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
300 */
301 ACPI_MOVE_64_TO_64(&address64, table_entry);
262 302
263 table->checksum = acpi_tb_generate_checksum(table); 303#if ACPI_MACHINE_WIDTH == 32
304 if (address64 > ACPI_UINT32_MAX) {
305
306 /* Will truncate 64-bit address to 32 bits, issue warning */
307
308 ACPI_WARNING((AE_INFO,
309 "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
310 ACPI_FORMAT_UINT64(address64)));
311 }
312#endif
313 return ((acpi_physical_address) (address64));
314 }
264} 315}
265 316
266/******************************************************************************* 317/*******************************************************************************
267 * 318 *
268 * FUNCTION: acpi_tb_verify_table_checksum 319 * FUNCTION: acpi_tb_parse_root_table
320 *
321 * PARAMETERS: Rsdp - Pointer to the RSDP
322 * Flags - Flags
269 * 323 *
270 * PARAMETERS: *table_header - ACPI table to verify 324 * RETURN: Status
271 * 325 *
272 * RETURN: 8 bit checksum of table 326 * DESCRIPTION: This function is called to parse the Root System Description
327 * Table (RSDT or XSDT)
273 * 328 *
274 * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares 329 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
275 * it to the existing checksum value. 330 * be mapped and cannot be copied because it contains the actual
331 * memory location of the ACPI Global Lock.
276 * 332 *
277 ******************************************************************************/ 333 ******************************************************************************/
278 334
279acpi_status 335acpi_status __init
280acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) 336acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
281{ 337{
282 u8 checksum; 338 struct acpi_table_rsdp *rsdp;
339 acpi_native_uint table_entry_size;
340 acpi_native_uint i;
341 u32 table_count;
342 struct acpi_table_header *table;
343 acpi_physical_address address;
344 u32 length;
345 u8 *table_entry;
346 acpi_status status;
347
348 ACPI_FUNCTION_TRACE(tb_parse_root_table);
349
350 /*
351 * Map the entire RSDP and extract the address of the RSDT or XSDT
352 */
353 rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
354 if (!rsdp) {
355 return_ACPI_STATUS(AE_NO_MEMORY);
356 }
283 357
284 ACPI_FUNCTION_TRACE(tb_verify_table_checksum); 358 acpi_tb_print_table_header(rsdp_address,
359 ACPI_CAST_PTR(struct acpi_table_header,
360 rsdp));
285 361
286 /* Compute the checksum on the table */ 362 /* Differentiate between RSDT and XSDT root tables */
287 363
288 checksum = acpi_tb_generate_checksum(table_header); 364 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
365 /*
366 * Root table is an XSDT (64-bit physical addresses). We must use the
367 * XSDT if the revision is > 1 and the XSDT pointer is present, as per
368 * the ACPI specification.
369 */
370 address = (acpi_physical_address) rsdp->xsdt_physical_address;
371 table_entry_size = sizeof(u64);
372 } else {
373 /* Root table is an RSDT (32-bit physical addresses) */
289 374
290 /* Checksum ok? */ 375 address = (acpi_physical_address) rsdp->rsdt_physical_address;
376 table_entry_size = sizeof(u32);
377 }
291 378
292 if (checksum == table_header->checksum) { 379 /*
293 return_ACPI_STATUS(AE_OK); 380 * It is not possible to map more than one entry in some environments,
381 * so unmap the RSDP here before mapping other tables
382 */
383 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
384
385 /* Map the RSDT/XSDT table header to get the full table length */
386
387 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
388 if (!table) {
389 return_ACPI_STATUS(AE_NO_MEMORY);
294 } 390 }
295 391
296 ACPI_WARNING((AE_INFO, 392 acpi_tb_print_table_header(address, table);
297 "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X",
298 table_header->signature, table_header->checksum,
299 checksum));
300 393
301 return_ACPI_STATUS(AE_BAD_CHECKSUM); 394 /* Get the length of the full table, verify length and map entire table */
302}
303 395
304#ifdef ACPI_OBSOLETE_FUNCTIONS 396 length = table->length;
305/******************************************************************************* 397 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
306 *
307 * FUNCTION: acpi_tb_handle_to_object
308 *
309 * PARAMETERS: table_id - Id for which the function is searching
310 * table_desc - Pointer to return the matching table
311 * descriptor.
312 *
313 * RETURN: Search the tables to find one with a matching table_id and
314 * return a pointer to that table descriptor.
315 *
316 ******************************************************************************/
317 398
318acpi_status 399 if (length < sizeof(struct acpi_table_header)) {
319acpi_tb_handle_to_object(u16 table_id, 400 ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT",
320 struct acpi_table_desc **return_table_desc) 401 length));
321{ 402 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
322 u32 i; 403 }
323 struct acpi_table_desc *table_desc;
324 404
325 ACPI_FUNCTION_NAME(tb_handle_to_object); 405 table = acpi_os_map_memory(address, length);
406 if (!table) {
407 return_ACPI_STATUS(AE_NO_MEMORY);
408 }
409
410 /* Validate the root table checksum */
411
412 status = acpi_tb_verify_checksum(table, length);
413 if (ACPI_FAILURE(status)) {
414 acpi_os_unmap_memory(table, length);
415 return_ACPI_STATUS(status);
416 }
326 417
327 for (i = 0; i < ACPI_TABLE_MAX; i++) { 418 /* Calculate the number of tables described in the root table */
328 table_desc = acpi_gbl_table_lists[i].next; 419
329 while (table_desc) { 420 table_count =
330 if (table_desc->table_id == table_id) { 421 (u32) ((table->length -
331 *return_table_desc = table_desc; 422 sizeof(struct acpi_table_header)) / table_entry_size);
332 return (AE_OK); 423
424 /*
425 * First two entries in the table array are reserved for the DSDT and FACS,
426 * which are not actually present in the RSDT/XSDT - they come from the FADT
427 */
428 table_entry =
429 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
430 acpi_gbl_root_table_list.count = 2;
431
432 /*
433 * Initialize the root table array from the RSDT/XSDT
434 */
435 for (i = 0; i < table_count; i++) {
436 if (acpi_gbl_root_table_list.count >=
437 acpi_gbl_root_table_list.size) {
438
439 /* There is no more room in the root table array, attempt resize */
440
441 status = acpi_tb_resize_root_table_list();
442 if (ACPI_FAILURE(status)) {
443 ACPI_WARNING((AE_INFO,
444 "Truncating %u table entries!",
445 (unsigned)
446 (acpi_gbl_root_table_list.size -
447 acpi_gbl_root_table_list.
448 count)));
449 break;
333 } 450 }
451 }
452
453 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
334 454
335 table_desc = table_desc->next; 455 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
456 address =
457 acpi_tb_get_root_table_entry(table_entry, table_entry_size);
458
459 table_entry += table_entry_size;
460 acpi_gbl_root_table_list.count++;
461 }
462
463 /*
464 * It is not possible to map more than one entry in some environments,
465 * so unmap the root table here before mapping other tables
466 */
467 acpi_os_unmap_memory(table, length);
468
469 /*
470 * Complete the initialization of the root table array by examining
471 * the header of each table
472 */
473 for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
474 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
475 address, flags, NULL, i);
476
477 /* Special case for FADT - get the DSDT and FACS */
478
479 if (ACPI_COMPARE_NAME
480 (&acpi_gbl_root_table_list.tables[i].signature,
481 ACPI_SIG_FADT)) {
482 acpi_tb_parse_fadt(i, flags);
336 } 483 }
337 } 484 }
338 485
339 ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); 486 return_ACPI_STATUS(AE_OK);
340 return (AE_BAD_PARAMETER);
341} 487}
342#endif
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5ba9303293ad..807978d5381a 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * Copyright (C) 2000 - 2007, R. Byron Moore
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -49,80 +49,158 @@
49#define _COMPONENT ACPI_TABLES 49#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbxface") 50ACPI_MODULE_NAME("tbxface")
51 51
52/* Local prototypes */
53static acpi_status acpi_tb_load_namespace(void);
54
52/******************************************************************************* 55/*******************************************************************************
53 * 56 *
54 * FUNCTION: acpi_load_tables 57 * FUNCTION: acpi_allocate_root_table
55 * 58 *
56 * PARAMETERS: None 59 * PARAMETERS: initial_table_count - Size of initial_table_array, in number of
60 * struct acpi_table_desc structures
57 * 61 *
58 * RETURN: Status 62 * RETURN: Status
59 * 63 *
60 * DESCRIPTION: This function is called to load the ACPI tables from the 64 * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and
61 * provided RSDT 65 * acpi_initialize_tables.
62 * 66 *
63 ******************************************************************************/ 67 ******************************************************************************/
64acpi_status acpi_load_tables(void) 68
69acpi_status acpi_allocate_root_table(u32 initial_table_count)
65{ 70{
66 struct acpi_pointer rsdp_address;
67 acpi_status status;
68 71
69 ACPI_FUNCTION_TRACE(acpi_load_tables); 72 acpi_gbl_root_table_list.size = initial_table_count;
73 acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
70 74
71 /* Get the RSDP */ 75 return (acpi_tb_resize_root_table_list());
76}
72 77
73 status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, 78/*******************************************************************************
74 &rsdp_address); 79 *
75 if (ACPI_FAILURE(status)) { 80 * FUNCTION: acpi_initialize_tables
76 ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); 81 *
77 goto error_exit; 82 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated
78 } 83 * struct acpi_table_desc structures. If NULL, the
84 * array is dynamically allocated.
85 * initial_table_count - Size of initial_table_array, in number of
86 * struct acpi_table_desc structures
87 * allow_realloc - Flag to tell Table Manager if resize of
88 * pre-allocated array is allowed. Ignored
89 * if initial_table_array is NULL.
90 *
91 * RETURN: Status
92 *
93 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
94 *
95 * NOTE: Allows static allocation of the initial table array in order
96 * to avoid the use of dynamic memory in confined environments
97 * such as the kernel boot sequence where it may not be available.
98 *
99 * If the host OS memory managers are initialized, use NULL for
100 * initial_table_array, and the table will be dynamically allocated.
101 *
102 ******************************************************************************/
79 103
80 /* Map and validate the RSDP */ 104acpi_status __init
105acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
106 u32 initial_table_count, u8 allow_resize)
107{
108 acpi_physical_address rsdp_address;
109 acpi_status status;
81 110
82 acpi_gbl_table_flags = rsdp_address.pointer_type; 111 ACPI_FUNCTION_TRACE(acpi_initialize_tables);
83 112
84 status = acpi_tb_verify_rsdp(&rsdp_address); 113 /*
85 if (ACPI_FAILURE(status)) { 114 * Set up the Root Table Array
86 ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); 115 * Allocate the table array if requested
87 goto error_exit; 116 */
117 if (!initial_table_array) {
118 status = acpi_allocate_root_table(initial_table_count);
119 if (ACPI_FAILURE(status)) {
120 return_ACPI_STATUS(status);
121 }
122 } else {
123 /* Root Table Array has been statically allocated by the host */
124
125 ACPI_MEMSET(initial_table_array, 0,
126 initial_table_count *
127 sizeof(struct acpi_table_desc));
128
129 acpi_gbl_root_table_list.tables = initial_table_array;
130 acpi_gbl_root_table_list.size = initial_table_count;
131 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
132 if (allow_resize) {
133 acpi_gbl_root_table_list.flags |=
134 ACPI_ROOT_ALLOW_RESIZE;
135 }
88 } 136 }
89 137
90 /* Get the RSDT via the RSDP */ 138 /* Get the address of the RSDP */
91 139
92 status = acpi_tb_get_table_rsdt(); 140 rsdp_address = acpi_os_get_root_pointer();
93 if (ACPI_FAILURE(status)) { 141 if (!rsdp_address) {
94 ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); 142 return_ACPI_STATUS(AE_NOT_FOUND);
95 goto error_exit;
96 } 143 }
97 144
98 /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ 145 /*
146 * Get the root table (RSDT or XSDT) and extract all entries to the local
147 * Root Table Array. This array contains the information of the RSDT/XSDT
148 * in a common, more useable format.
149 */
150 status =
151 acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
152 return_ACPI_STATUS(status);
153}
99 154
100 status = acpi_tb_get_required_tables(); 155/*******************************************************************************
101 if (ACPI_FAILURE(status)) { 156 *
102 ACPI_EXCEPTION((AE_INFO, status, 157 * FUNCTION: acpi_reallocate_root_table
103 "Could not get all required tables (DSDT/FADT/FACS)")); 158 *
104 goto error_exit; 159 * PARAMETERS: None
160 *
161 * RETURN: Status
162 *
163 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
164 * root list from the previously provided scratch area. Should
165 * be called once dynamic memory allocation is available in the
166 * kernel
167 *
168 ******************************************************************************/
169acpi_status acpi_reallocate_root_table(void)
170{
171 struct acpi_table_desc *tables;
172 acpi_size new_size;
173
174 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
175
176 /*
177 * Only reallocate the root table if the host provided a static buffer
178 * for the table array in the call to acpi_initialize_tables.
179 */
180 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
181 return_ACPI_STATUS(AE_SUPPORT);
105 } 182 }
106 183
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 184 new_size =
185 (acpi_gbl_root_table_list.count +
186 ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
108 187
109 /* Load the namespace from the tables */ 188 /* Create new array and copy the old array */
110 189
111 status = acpi_ns_load_namespace(); 190 tables = ACPI_ALLOCATE_ZEROED(new_size);
112 if (ACPI_FAILURE(status)) { 191 if (!tables) {
113 ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); 192 return_ACPI_STATUS(AE_NO_MEMORY);
114 goto error_exit;
115 } 193 }
116 194
117 return_ACPI_STATUS(AE_OK); 195 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
118 196
119 error_exit: 197 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
120 ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); 198 acpi_gbl_root_table_list.tables = tables;
121 return_ACPI_STATUS(status); 199 acpi_gbl_root_table_list.flags =
122} 200 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
123
124ACPI_EXPORT_SYMBOL(acpi_load_tables)
125 201
202 return_ACPI_STATUS(AE_OK);
203}
126/******************************************************************************* 204/*******************************************************************************
127 * 205 *
128 * FUNCTION: acpi_load_table 206 * FUNCTION: acpi_load_table
@@ -141,342 +219,405 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
141acpi_status acpi_load_table(struct acpi_table_header *table_ptr) 219acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
142{ 220{
143 acpi_status status; 221 acpi_status status;
144 struct acpi_table_desc table_info; 222 acpi_native_uint table_index;
145 struct acpi_pointer address; 223 struct acpi_table_desc table_desc;
146
147 ACPI_FUNCTION_TRACE(acpi_load_table);
148
149 if (!table_ptr) {
150 return_ACPI_STATUS(AE_BAD_PARAMETER);
151 }
152
153 /* Copy the table to a local buffer */
154 224
155 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; 225 if (!table_ptr)
156 address.pointer.logical = table_ptr; 226 return AE_BAD_PARAMETER;
157
158 status = acpi_tb_get_table_body(&address, table_ptr, &table_info);
159 if (ACPI_FAILURE(status)) {
160 return_ACPI_STATUS(status);
161 }
162
163 /* Check signature for a valid table type */
164
165 status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
166 if (ACPI_FAILURE(status)) {
167 return_ACPI_STATUS(status);
168 }
169 227
170 /* Install the new table into the local data structures */ 228 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
229 table_desc.pointer = table_ptr;
230 table_desc.length = table_ptr->length;
231 table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
171 232
172 status = acpi_tb_install_table(&table_info); 233 /*
234 * Install the new table into the local data structures
235 */
236 status = acpi_tb_add_table(&table_desc, &table_index);
173 if (ACPI_FAILURE(status)) { 237 if (ACPI_FAILURE(status)) {
174 if (status == AE_ALREADY_EXISTS) { 238 return status;
175
176 /* Table already exists, no error */
177
178 status = AE_OK;
179 }
180
181 /* Free table allocated by acpi_tb_get_table_body */
182
183 acpi_tb_delete_single_table(&table_info);
184 return_ACPI_STATUS(status);
185 } 239 }
240 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
241 return status;
242}
186 243
187 /* Convert the table to common format if necessary */ 244ACPI_EXPORT_SYMBOL(acpi_load_table)
188
189 switch (table_info.type) {
190 case ACPI_TABLE_ID_FADT:
191
192 status = acpi_tb_convert_table_fadt();
193 break;
194
195 case ACPI_TABLE_ID_FACS:
196 245
197 status = acpi_tb_build_common_facs(&table_info); 246/******************************************************************************
198 break; 247 *
248 * FUNCTION: acpi_get_table_header
249 *
250 * PARAMETERS: Signature - ACPI signature of needed table
251 * Instance - Which instance (for SSDTs)
252 * out_table_header - The pointer to the table header to fill
253 *
254 * RETURN: Status and pointer to mapped table header
255 *
256 * DESCRIPTION: Finds an ACPI table header.
257 *
258 * NOTE: Caller is responsible in unmapping the header with
259 * acpi_os_unmap_memory
260 *
261 *****************************************************************************/
262acpi_status
263acpi_get_table_header(char *signature,
264 acpi_native_uint instance,
265 struct acpi_table_header *out_table_header)
266{
267 acpi_native_uint i;
268 acpi_native_uint j;
269 struct acpi_table_header *header;
199 270
200 default: 271 /* Parameter validation */
201 /* Load table into namespace if it contains executable AML */
202 272
203 status = 273 if (!signature || !out_table_header) {
204 acpi_ns_load_table(table_info.installed_desc, 274 return (AE_BAD_PARAMETER);
205 acpi_gbl_root_node);
206 break;
207 } 275 }
208 276
209 if (ACPI_FAILURE(status)) { 277 /*
278 * Walk the root table list
279 */
280 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
281 if (!ACPI_COMPARE_NAME
282 (&(acpi_gbl_root_table_list.tables[i].signature),
283 signature)) {
284 continue;
285 }
210 286
211 /* Uninstall table and free the buffer */ 287 if (++j < instance) {
288 continue;
289 }
212 290
213 (void)acpi_tb_uninstall_table(table_info.installed_desc); 291 if (!acpi_gbl_root_table_list.tables[i].pointer) {
292 if ((acpi_gbl_root_table_list.tables[i].
293 flags & ACPI_TABLE_ORIGIN_MASK) ==
294 ACPI_TABLE_ORIGIN_MAPPED) {
295 header =
296 acpi_os_map_memory(acpi_gbl_root_table_list.
297 tables[i].address,
298 sizeof(struct
299 acpi_table_header));
300 if (!header) {
301 return AE_NO_MEMORY;
302 }
303 ACPI_MEMCPY(out_table_header, header,
304 sizeof(struct acpi_table_header));
305 acpi_os_unmap_memory(header,
306 sizeof(struct
307 acpi_table_header));
308 } else {
309 return AE_NOT_FOUND;
310 }
311 } else {
312 ACPI_MEMCPY(out_table_header,
313 acpi_gbl_root_table_list.tables[i].pointer,
314 sizeof(struct acpi_table_header));
315 }
316 return (AE_OK);
214 } 317 }
215 318
216 return_ACPI_STATUS(status); 319 return (AE_NOT_FOUND);
217} 320}
218 321
219ACPI_EXPORT_SYMBOL(acpi_load_table) 322ACPI_EXPORT_SYMBOL(acpi_get_table_header)
220 323
221/******************************************************************************* 324
325/******************************************************************************
222 * 326 *
223 * FUNCTION: acpi_unload_table_id 327 * FUNCTION: acpi_unload_table_id
224 * 328 *
225 * PARAMETERS: table_type - Type of table to be unloaded 329 * PARAMETERS: id - Owner ID of the table to be removed.
226 * id - Owner ID of the table to be removed.
227 * 330 *
228 * RETURN: Status 331 * RETURN: Status
229 * 332 *
230 * DESCRIPTION: This routine is used to force the unload of a table (by id) 333 * DESCRIPTION: This routine is used to force the unload of a table (by id)
231 * 334 *
232 ******************************************************************************/ 335 ******************************************************************************/
233acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) 336acpi_status acpi_unload_table_id(acpi_owner_id id)
234{ 337{
235 struct acpi_table_desc *table_desc; 338 int i;
236 acpi_status status; 339 acpi_status status = AE_NOT_EXIST;
237 340
238 ACPI_FUNCTION_TRACE(acpi_unload_table); 341 ACPI_FUNCTION_TRACE(acpi_unload_table);
239 342
240 /* Parameter validation */
241 if (table_type > ACPI_TABLE_ID_MAX)
242 return_ACPI_STATUS(AE_BAD_PARAMETER);
243
244 /* Find table from the requested type list */ 343 /* Find table from the requested type list */
245 table_desc = acpi_gbl_table_lists[table_type].next; 344 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
246 while (table_desc && table_desc->owner_id != id) 345 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
247 table_desc = table_desc->next; 346 continue;
248 347 }
249 if (!table_desc) 348 /*
250 return_ACPI_STATUS(AE_NOT_EXIST); 349 * Delete all namespace objects owned by this table. Note that these
251 350 * objects can appear anywhere in the namespace by virtue of the AML
252 /* 351 * "Scope" operator. Thus, we need to track ownership by an ID, not
253 * Delete all namespace objects owned by this table. Note that these 352 * simply a position within the hierarchy
254 * objects can appear anywhere in the namespace by virtue of the AML 353 */
255 * "Scope" operator. Thus, we need to track ownership by an ID, not 354 acpi_tb_delete_namespace_by_owner(i);
256 * simply a position within the hierarchy 355 acpi_tb_release_owner_id(i);
257 */ 356 acpi_tb_set_table_loaded_flag(i, FALSE);
258 acpi_ns_delete_namespace_by_owner(table_desc->owner_id); 357 }
259 358 return_ACPI_STATUS(status);
260 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
261 if (ACPI_FAILURE(status))
262 return_ACPI_STATUS(status);
263
264 (void)acpi_tb_uninstall_table(table_desc);
265
266 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
267
268 return_ACPI_STATUS(AE_OK);
269} 359}
270 360
271ACPI_EXPORT_SYMBOL(acpi_unload_table_id) 361ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
272 362
273#ifdef ACPI_FUTURE_USAGE
274/******************************************************************************* 363/*******************************************************************************
275 * 364 *
276 * FUNCTION: acpi_unload_table 365 * FUNCTION: acpi_get_table
277 * 366 *
278 * PARAMETERS: table_type - Type of table to be unloaded 367 * PARAMETERS: Signature - ACPI signature of needed table
368 * Instance - Which instance (for SSDTs)
369 * out_table - Where the pointer to the table is returned
279 * 370 *
280 * RETURN: Status 371 * RETURN: Status and pointer to table
281 * 372 *
282 * DESCRIPTION: This routine is used to force the unload of a table 373 * DESCRIPTION: Finds and verifies an ACPI table.
283 * 374 *
284 ******************************************************************************/ 375 *****************************************************************************/
285acpi_status acpi_unload_table(acpi_table_type table_type) 376acpi_status
377acpi_get_table(char *signature,
378 acpi_native_uint instance, struct acpi_table_header ** out_table)
286{ 379{
287 struct acpi_table_desc *table_desc; 380 acpi_native_uint i;
288 381 acpi_native_uint j;
289 ACPI_FUNCTION_TRACE(acpi_unload_table); 382 acpi_status status;
290 383
291 /* Parameter validation */ 384 /* Parameter validation */
292 385
293 if (table_type > ACPI_TABLE_ID_MAX) { 386 if (!signature || !out_table) {
294 return_ACPI_STATUS(AE_BAD_PARAMETER); 387 return (AE_BAD_PARAMETER);
295 } 388 }
296 389
297 /* Find all tables of the requested type */ 390 /*
391 * Walk the root table list
392 */
393 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
394 if (!ACPI_COMPARE_NAME
395 (&(acpi_gbl_root_table_list.tables[i].signature),
396 signature)) {
397 continue;
398 }
298 399
299 table_desc = acpi_gbl_table_lists[table_type].next; 400 if (++j < instance) {
300 if (!table_desc) { 401 continue;
301 return_ACPI_STATUS(AE_NOT_EXIST); 402 }
302 }
303 403
304 while (table_desc) { 404 status =
305 /* 405 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
306 * Delete all namespace objects owned by this table. Note that these 406 if (ACPI_SUCCESS(status)) {
307 * objects can appear anywhere in the namespace by virtue of the AML 407 *out_table = acpi_gbl_root_table_list.tables[i].pointer;
308 * "Scope" operator. Thus, we need to track ownership by an ID, not 408 }
309 * simply a position within the hierarchy
310 */
311 acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
312 table_desc = table_desc->next;
313 }
314 409
315 /* Delete (or unmap) all tables of this type */ 410 if (!acpi_gbl_permanent_mmap) {
411 acpi_gbl_root_table_list.tables[i].pointer = 0;
412 }
316 413
317 acpi_tb_delete_tables_by_type(table_type); 414 return (status);
318 return_ACPI_STATUS(AE_OK); 415 }
416
417 return (AE_NOT_FOUND);
319} 418}
320 419
321ACPI_EXPORT_SYMBOL(acpi_unload_table) 420ACPI_EXPORT_SYMBOL(acpi_get_table)
322 421
323/******************************************************************************* 422/*******************************************************************************
324 * 423 *
325 * FUNCTION: acpi_get_table_header 424 * FUNCTION: acpi_get_table_by_index
326 * 425 *
327 * PARAMETERS: table_type - one of the defined table types 426 * PARAMETERS: table_index - Table index
328 * Instance - the non zero instance of the table, allows 427 * Table - Where the pointer to the table is returned
329 * support for multiple tables of the same type
330 * see acpi_gbl_acpi_table_flag
331 * out_table_header - pointer to the struct acpi_table_header if successful
332 * 428 *
333 * DESCRIPTION: This function is called to get an ACPI table header. The caller 429 * RETURN: Status and pointer to the table
334 * supplies an pointer to a data area sufficient to contain an ACPI
335 * struct acpi_table_header structure.
336 * 430 *
337 * The header contains a length field that can be used to determine 431 * DESCRIPTION: Obtain a table by an index into the global table list.
338 * the size of the buffer needed to contain the entire table. This
339 * function is not valid for the RSD PTR table since it does not
340 * have a standard header and is fixed length.
341 * 432 *
342 ******************************************************************************/ 433 ******************************************************************************/
343acpi_status 434acpi_status
344acpi_get_table_header(acpi_table_type table_type, 435acpi_get_table_by_index(acpi_native_uint table_index,
345 u32 instance, struct acpi_table_header *out_table_header) 436 struct acpi_table_header ** table)
346{ 437{
347 struct acpi_table_header *tbl_ptr;
348 acpi_status status; 438 acpi_status status;
349 439
350 ACPI_FUNCTION_TRACE(acpi_get_table_header); 440 ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
441
442 /* Parameter validation */
351 443
352 if ((instance == 0) || 444 if (!table) {
353 (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) {
354 return_ACPI_STATUS(AE_BAD_PARAMETER); 445 return_ACPI_STATUS(AE_BAD_PARAMETER);
355 } 446 }
356 447
357 /* Check the table type and instance */ 448 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
449
450 /* Validate index */
358 451
359 if ((table_type > ACPI_TABLE_ID_MAX) || 452 if (table_index >= acpi_gbl_root_table_list.count) {
360 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 453 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
361 instance > 1)) {
362 return_ACPI_STATUS(AE_BAD_PARAMETER); 454 return_ACPI_STATUS(AE_BAD_PARAMETER);
363 } 455 }
364 456
365 /* Get a pointer to the entire table */ 457 if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
366 458
367 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 459 /* Table is not mapped, map it */
368 if (ACPI_FAILURE(status)) {
369 return_ACPI_STATUS(status);
370 }
371 460
372 /* The function will return a NULL pointer if the table is not loaded */ 461 status =
373 462 acpi_tb_verify_table(&acpi_gbl_root_table_list.
374 if (tbl_ptr == NULL) { 463 tables[table_index]);
375 return_ACPI_STATUS(AE_NOT_EXIST); 464 if (ACPI_FAILURE(status)) {
465 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
466 return_ACPI_STATUS(status);
467 }
376 } 468 }
377 469
378 /* Copy the header to the caller's buffer */ 470 *table = acpi_gbl_root_table_list.tables[table_index].pointer;
379 471 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
380 ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), 472 return_ACPI_STATUS(AE_OK);
381 ACPI_CAST_PTR(void, tbl_ptr),
382 sizeof(struct acpi_table_header));
383
384 return_ACPI_STATUS(status);
385} 473}
386 474
387ACPI_EXPORT_SYMBOL(acpi_get_table_header) 475ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
388#endif /* ACPI_FUTURE_USAGE */
389 476
390/******************************************************************************* 477/*******************************************************************************
391 * 478 *
392 * FUNCTION: acpi_get_table 479 * FUNCTION: acpi_tb_load_namespace
393 * 480 *
394 * PARAMETERS: table_type - one of the defined table types 481 * PARAMETERS: None
395 * Instance - the non zero instance of the table, allows
396 * support for multiple tables of the same type
397 * see acpi_gbl_acpi_table_flag
398 * ret_buffer - pointer to a structure containing a buffer to
399 * receive the table
400 * 482 *
401 * RETURN: Status 483 * RETURN: Status
402 * 484 *
403 * DESCRIPTION: This function is called to get an ACPI table. The caller 485 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
404 * supplies an out_buffer large enough to contain the entire ACPI 486 * the RSDT/XSDT.
405 * table. The caller should call the acpi_get_table_header function
406 * first to determine the buffer size needed. Upon completion
407 * the out_buffer->Length field will indicate the number of bytes
408 * copied into the out_buffer->buf_ptr buffer. This table will be
409 * a complete table including the header.
410 * 487 *
411 ******************************************************************************/ 488 ******************************************************************************/
412acpi_status 489static acpi_status acpi_tb_load_namespace(void)
413acpi_get_table(acpi_table_type table_type,
414 u32 instance, struct acpi_buffer *ret_buffer)
415{ 490{
416 struct acpi_table_header *tbl_ptr;
417 acpi_status status; 491 acpi_status status;
418 acpi_size table_length; 492 struct acpi_table_header *table;
493 acpi_native_uint i;
419 494
420 ACPI_FUNCTION_TRACE(acpi_get_table); 495 ACPI_FUNCTION_TRACE(tb_load_namespace);
421 496
422 /* Parameter validation */ 497 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
423 498
424 if (instance == 0) { 499 /*
425 return_ACPI_STATUS(AE_BAD_PARAMETER); 500 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
501 * are optional.
502 */
503 if (!acpi_gbl_root_table_list.count ||
504 !ACPI_COMPARE_NAME(&
505 (acpi_gbl_root_table_list.
506 tables[ACPI_TABLE_INDEX_DSDT].signature),
507 ACPI_SIG_DSDT)
508 ||
509 ACPI_FAILURE(acpi_tb_verify_table
510 (&acpi_gbl_root_table_list.
511 tables[ACPI_TABLE_INDEX_DSDT]))) {
512 status = AE_NO_ACPI_TABLES;
513 goto unlock_and_exit;
426 } 514 }
427 515
428 status = acpi_ut_validate_buffer(ret_buffer); 516 /*
429 if (ACPI_FAILURE(status)) { 517 * Find DSDT table
430 return_ACPI_STATUS(status); 518 */
519 status =
520 acpi_os_table_override(acpi_gbl_root_table_list.
521 tables[ACPI_TABLE_INDEX_DSDT].pointer,
522 &table);
523 if (ACPI_SUCCESS(status) && table) {
524 /*
525 * DSDT table has been found
526 */
527 acpi_tb_delete_table(&acpi_gbl_root_table_list.
528 tables[ACPI_TABLE_INDEX_DSDT]);
529 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
530 table;
531 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
532 table->length;
533 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
534 ACPI_TABLE_ORIGIN_UNKNOWN;
535
536 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
537 acpi_tb_print_table_header(0, table);
431 } 538 }
432 539
433 /* Check the table type and instance */ 540 status =
541 acpi_tb_verify_table(&acpi_gbl_root_table_list.
542 tables[ACPI_TABLE_INDEX_DSDT]);
543 if (ACPI_FAILURE(status)) {
434 544
435 if ((table_type > ACPI_TABLE_ID_MAX) || 545 /* A valid DSDT is required */
436 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 546
437 instance > 1)) { 547 status = AE_NO_ACPI_TABLES;
438 return_ACPI_STATUS(AE_BAD_PARAMETER); 548 goto unlock_and_exit;
439 } 549 }
440 550
441 /* Get a pointer to the entire table */ 551 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
442 552
443 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 553 /*
554 * Load and parse tables.
555 */
556 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
444 if (ACPI_FAILURE(status)) { 557 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status); 558 return_ACPI_STATUS(status);
446 } 559 }
447 560
448 /* 561 /*
449 * acpi_tb_get_table_ptr will return a NULL pointer if the 562 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
450 * table is not loaded.
451 */ 563 */
452 if (tbl_ptr == NULL) { 564 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
453 return_ACPI_STATUS(AE_NOT_EXIST); 565 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
566 if ((!ACPI_COMPARE_NAME
567 (&(acpi_gbl_root_table_list.tables[i].signature),
568 ACPI_SIG_SSDT)
569 &&
570 !ACPI_COMPARE_NAME(&
571 (acpi_gbl_root_table_list.tables[i].
572 signature), ACPI_SIG_PSDT))
573 ||
574 ACPI_FAILURE(acpi_tb_verify_table
575 (&acpi_gbl_root_table_list.tables[i]))) {
576 continue;
577 }
578
579 /* Ignore errors while loading tables, get as many as possible */
580
581 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
582 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
583 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
454 } 584 }
455 585
456 /* Get the table length */ 586 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
457 587
458 if (table_type == ACPI_TABLE_ID_RSDP) { 588 unlock_and_exit:
589 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
590 return_ACPI_STATUS(status);
591}
459 592
460 /* RSD PTR is the only "table" without a header */ 593/*******************************************************************************
594 *
595 * FUNCTION: acpi_load_tables
596 *
597 * PARAMETERS: None
598 *
599 * RETURN: Status
600 *
601 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
602 *
603 ******************************************************************************/
461 604
462 table_length = sizeof(struct rsdp_descriptor); 605acpi_status acpi_load_tables(void)
463 } else { 606{
464 table_length = (acpi_size) tbl_ptr->length; 607 acpi_status status;
465 }
466 608
467 /* Validate/Allocate/Clear caller buffer */ 609 ACPI_FUNCTION_TRACE(acpi_load_tables);
468 610
469 status = acpi_ut_initialize_buffer(ret_buffer, table_length); 611 /*
612 * Load the namespace from the tables
613 */
614 status = acpi_tb_load_namespace();
470 if (ACPI_FAILURE(status)) { 615 if (ACPI_FAILURE(status)) {
471 return_ACPI_STATUS(status); 616 ACPI_EXCEPTION((AE_INFO, status,
617 "While loading namespace from ACPI tables"));
472 } 618 }
473 619
474 /* Copy the table to the buffer */ 620 return_ACPI_STATUS(status);
475
476 ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
477 ACPI_CAST_PTR(void, tbl_ptr), table_length);
478
479 return_ACPI_STATUS(AE_OK);
480} 621}
481 622
482ACPI_EXPORT_SYMBOL(acpi_get_table) 623ACPI_EXPORT_SYMBOL(acpi_load_tables)
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index da2648bbdbc0..cf8fa514189f 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,16 +48,15 @@
48ACPI_MODULE_NAME("tbxfroot") 48ACPI_MODULE_NAME("tbxfroot")
49 49
50/* Local prototypes */ 50/* Local prototypes */
51static acpi_status
52acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags);
53
54static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); 51static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
55 52
53static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
54
56/******************************************************************************* 55/*******************************************************************************
57 * 56 *
58 * FUNCTION: acpi_tb_validate_rsdp 57 * FUNCTION: acpi_tb_validate_rsdp
59 * 58 *
60 * PARAMETERS: Rsdp - Pointer to unvalidated RSDP 59 * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
61 * 60 *
62 * RETURN: Status 61 * RETURN: Status
63 * 62 *
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
65 * 64 *
66 ******************************************************************************/ 65 ******************************************************************************/
67 66
68acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) 67static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
69{ 68{
70 ACPI_FUNCTION_ENTRY(); 69 ACPI_FUNCTION_ENTRY();
71 70
72 /* 71 /*
73 * The signature and checksum must both be correct 72 * The signature and checksum must both be correct
73 *
74 * Note: Sometimes there exists more than one RSDP in memory; the valid
75 * RSDP has a valid checksum, all others have an invalid checksum.
74 */ 76 */
75 if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { 77 if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
78 != 0) {
76 79
77 /* Nope, BAD Signature */ 80 /* Nope, BAD Signature */
78 81
@@ -81,14 +84,14 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
81 84
82 /* Check the standard checksum */ 85 /* Check the standard checksum */
83 86
84 if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { 87 if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
85 return (AE_BAD_CHECKSUM); 88 return (AE_BAD_CHECKSUM);
86 } 89 }
87 90
88 /* Check extended checksum if table version >= 2 */ 91 /* Check extended checksum if table version >= 2 */
89 92
90 if ((rsdp->revision >= 2) && 93 if ((rsdp->revision >= 2) &&
91 (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { 94 (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
92 return (AE_BAD_CHECKSUM); 95 return (AE_BAD_CHECKSUM);
93 } 96 }
94 97
@@ -97,314 +100,123 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
97 100
98/******************************************************************************* 101/*******************************************************************************
99 * 102 *
100 * FUNCTION: acpi_tb_find_table 103 * FUNCTION: acpi_tb_find_rsdp
101 *
102 * PARAMETERS: Signature - String with ACPI table signature
103 * oem_id - String with the table OEM ID
104 * oem_table_id - String with the OEM Table ID
105 * table_ptr - Where the table pointer is returned
106 *
107 * RETURN: Status
108 * 104 *
109 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the 105 * PARAMETERS: table_address - Where the table pointer is returned
110 * Signature, OEM ID and OEM Table ID.
111 * 106 *
112 ******************************************************************************/ 107 * RETURN: Status, RSDP physical address
113
114acpi_status
115acpi_tb_find_table(char *signature,
116 char *oem_id,
117 char *oem_table_id, struct acpi_table_header ** table_ptr)
118{
119 acpi_status status;
120 struct acpi_table_header *table;
121
122 ACPI_FUNCTION_TRACE(tb_find_table);
123
124 /* Validate string lengths */
125
126 if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) ||
127 (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) ||
128 (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) {
129 return_ACPI_STATUS(AE_AML_STRING_LIMIT);
130 }
131
132 if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) {
133 /*
134 * The DSDT pointer is contained in the FADT, not the RSDT.
135 * This code should suffice, because the only code that would perform
136 * a "find" on the DSDT is the data_table_region() AML opcode -- in
137 * which case, the DSDT is guaranteed to be already loaded.
138 * If this becomes insufficient, the FADT will have to be found first.
139 */
140 if (!acpi_gbl_DSDT) {
141 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
142 }
143 table = acpi_gbl_DSDT;
144 } else {
145 /* Find the table */
146
147 status = acpi_get_firmware_table(signature, 1,
148 ACPI_LOGICAL_ADDRESSING,
149 &table);
150 if (ACPI_FAILURE(status)) {
151 return_ACPI_STATUS(status);
152 }
153 }
154
155 /* Check oem_id and oem_table_id */
156
157 if ((oem_id[0] &&
158 ACPI_STRNCMP(oem_id, table->oem_id,
159 sizeof(table->oem_id))) ||
160 (oem_table_id[0] &&
161 ACPI_STRNCMP(oem_table_id, table->oem_table_id,
162 sizeof(table->oem_table_id)))) {
163 return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND);
164 }
165
166 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n",
167 table->signature));
168
169 *table_ptr = table;
170 return_ACPI_STATUS(AE_OK);
171}
172
173/*******************************************************************************
174 *
175 * FUNCTION: acpi_get_firmware_table
176 * 108 *
177 * PARAMETERS: Signature - Any ACPI table signature 109 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
178 * Instance - the non zero instance of the table, allows 110 * pointer structure. If it is found, set *RSDP to point to it.
179 * support for multiple tables of the same type
180 * Flags - Physical/Virtual support
181 * table_pointer - Where a buffer containing the table is
182 * returned
183 * 111 *
184 * RETURN: Status 112 * NOTE1: The RSDP must be either in the first 1_k of the Extended
113 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
114 * Only a 32-bit physical address is necessary.
185 * 115 *
186 * DESCRIPTION: This function is called to get an ACPI table. A buffer is 116 * NOTE2: This function is always available, regardless of the
187 * allocated for the table and returned in table_pointer. 117 * initialization state of the rest of ACPI.
188 * This table will be a complete table including the header.
189 * 118 *
190 ******************************************************************************/ 119 ******************************************************************************/
191 120
192acpi_status 121acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
193acpi_get_firmware_table(acpi_string signature,
194 u32 instance,
195 u32 flags, struct acpi_table_header **table_pointer)
196{ 122{
197 acpi_status status; 123 u8 *table_ptr;
198 struct acpi_pointer address; 124 u8 *mem_rover;
199 struct acpi_table_header *header = NULL; 125 u32 physical_address;
200 struct acpi_table_desc *table_info = NULL;
201 struct acpi_table_desc *rsdt_info;
202 u32 table_count;
203 u32 i;
204 u32 j;
205
206 ACPI_FUNCTION_TRACE(acpi_get_firmware_table);
207
208 /*
209 * Ensure that at least the table manager is initialized. We don't
210 * require that the entire ACPI subsystem is up for this interface.
211 * If we have a buffer, we must have a length too
212 */
213 if ((instance == 0) || (!signature) || (!table_pointer)) {
214 return_ACPI_STATUS(AE_BAD_PARAMETER);
215 }
216
217 /* Ensure that we have a RSDP */
218
219 if (!acpi_gbl_RSDP) {
220
221 /* Get the RSDP */
222
223 status = acpi_os_get_root_pointer(flags, &address);
224 if (ACPI_FAILURE(status)) {
225 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n"));
226 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
227 }
228
229 /* Map and validate the RSDP */
230
231 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
232 status = acpi_os_map_memory(address.pointer.physical,
233 sizeof(struct
234 rsdp_descriptor),
235 (void *)&acpi_gbl_RSDP);
236 if (ACPI_FAILURE(status)) {
237 return_ACPI_STATUS(status);
238 }
239 } else {
240 acpi_gbl_RSDP = address.pointer.logical;
241 }
242
243 /* The RDSP signature and checksum must both be correct */
244
245 status = acpi_tb_validate_rsdp(acpi_gbl_RSDP);
246 if (ACPI_FAILURE(status)) {
247 return_ACPI_STATUS(status);
248 }
249 }
250
251 /* Get the RSDT address via the RSDP */
252
253 acpi_tb_get_rsdt_address(&address);
254 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
255 "RSDP located at %p, RSDT physical=%8.8X%8.8X\n",
256 acpi_gbl_RSDP,
257 ACPI_FORMAT_UINT64(address.pointer.value)));
258 126
259 /* Insert processor_mode flags */ 127 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
260 128
261 address.pointer_type |= flags; 129 /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
262 130
263 /* Get and validate the RSDT */ 131 table_ptr = acpi_os_map_memory((acpi_physical_address)
132 ACPI_EBDA_PTR_LOCATION,
133 ACPI_EBDA_PTR_LENGTH);
134 if (!table_ptr) {
135 ACPI_ERROR((AE_INFO,
136 "Could not map memory at %8.8X for length %X",
137 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
264 138
265 rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc));
266 if (!rsdt_info) {
267 return_ACPI_STATUS(AE_NO_MEMORY); 139 return_ACPI_STATUS(AE_NO_MEMORY);
268 } 140 }
269 141
270 status = acpi_tb_get_table(&address, rsdt_info); 142 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
271 if (ACPI_FAILURE(status)) {
272 goto cleanup;
273 }
274
275 status = acpi_tb_validate_rsdt(rsdt_info->pointer);
276 if (ACPI_FAILURE(status)) {
277 goto cleanup;
278 }
279 143
280 /* Allocate a scratch table header and table descriptor */ 144 /* Convert segment part to physical address */
281 145
282 header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); 146 physical_address <<= 4;
283 if (!header) { 147 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
284 status = AE_NO_MEMORY;
285 goto cleanup;
286 }
287 148
288 table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); 149 /* EBDA present? */
289 if (!table_info) {
290 status = AE_NO_MEMORY;
291 goto cleanup;
292 }
293 150
294 /* Get the number of table pointers within the RSDT */ 151 if (physical_address > 0x400) {
295
296 table_count =
297 acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer);
298 address.pointer_type = acpi_gbl_table_flags | flags;
299
300 /*
301 * Search the RSDT/XSDT for the correct instance of the
302 * requested table
303 */
304 for (i = 0, j = 0; i < table_count; i++) {
305 /* 152 /*
306 * Get the next table pointer, handle RSDT vs. XSDT 153 * 1b) Search EBDA paragraphs (EBDA is required to be a
307 * RSDT pointers are 32 bits, XSDT pointers are 64 bits 154 * minimum of 1_k length)
308 */ 155 */
309 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { 156 table_ptr = acpi_os_map_memory((acpi_native_uint)
310 address.pointer.value = 157 physical_address,
311 (ACPI_CAST_PTR 158 ACPI_EBDA_WINDOW_SIZE);
312 (struct rsdt_descriptor, 159 if (!table_ptr) {
313 rsdt_info->pointer))->table_offset_entry[i]; 160 ACPI_ERROR((AE_INFO,
314 } else { 161 "Could not map memory at %8.8X for length %X",
315 address.pointer.value = 162 physical_address, ACPI_EBDA_WINDOW_SIZE));
316 (ACPI_CAST_PTR
317 (struct xsdt_descriptor,
318 rsdt_info->pointer))->table_offset_entry[i];
319 }
320
321 /* Get the table header */
322 163
323 status = acpi_tb_get_table_header(&address, header); 164 return_ACPI_STATUS(AE_NO_MEMORY);
324 if (ACPI_FAILURE(status)) {
325 goto cleanup;
326 } 165 }
327 166
328 /* Compare table signatures and table instance */ 167 mem_rover =
329 168 acpi_tb_scan_memory_for_rsdp(table_ptr,
330 if (ACPI_COMPARE_NAME(header->signature, signature)) { 169 ACPI_EBDA_WINDOW_SIZE);
331 170 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
332 /* An instance of the table was found */
333 171
334 j++; 172 if (mem_rover) {
335 if (j >= instance) {
336 173
337 /* Found the correct instance, get the entire table */ 174 /* Return the physical address */
338 175
339 status = 176 physical_address +=
340 acpi_tb_get_table_body(&address, header, 177 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
341 table_info);
342 if (ACPI_FAILURE(status)) {
343 goto cleanup;
344 }
345 178
346 *table_pointer = table_info->pointer; 179 *table_address = physical_address;
347 goto cleanup; 180 return_ACPI_STATUS(AE_OK);
348 }
349 } 181 }
350 } 182 }
351 183
352 /* Did not find the table */ 184 /*
185 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
186 */
187 table_ptr = acpi_os_map_memory((acpi_physical_address)
188 ACPI_HI_RSDP_WINDOW_BASE,
189 ACPI_HI_RSDP_WINDOW_SIZE);
353 190
354 status = AE_NOT_EXIST; 191 if (!table_ptr) {
192 ACPI_ERROR((AE_INFO,
193 "Could not map memory at %8.8X for length %X",
194 ACPI_HI_RSDP_WINDOW_BASE,
195 ACPI_HI_RSDP_WINDOW_SIZE));
355 196
356 cleanup: 197 return_ACPI_STATUS(AE_NO_MEMORY);
357 if (rsdt_info->pointer) {
358 acpi_os_unmap_memory(rsdt_info->pointer,
359 (acpi_size) rsdt_info->pointer->length);
360 } 198 }
361 ACPI_FREE(rsdt_info);
362 199
363 if (header) { 200 mem_rover =
364 ACPI_FREE(header); 201 acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
365 } 202 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
366 if (table_info) {
367 ACPI_FREE(table_info);
368 }
369 return_ACPI_STATUS(status);
370}
371 203
372ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) 204 if (mem_rover) {
373 205
374/* TBD: Move to a new file */ 206 /* Return the physical address */
375#if ACPI_MACHINE_WIDTH != 16
376/*******************************************************************************
377 *
378 * FUNCTION: acpi_find_root_pointer
379 *
380 * PARAMETERS: Flags - Logical/Physical addressing
381 * rsdp_address - Where to place the RSDP address
382 *
383 * RETURN: Status, Physical address of the RSDP
384 *
385 * DESCRIPTION: Find the RSDP
386 *
387 ******************************************************************************/
388acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address)
389{
390 struct acpi_table_desc table_info;
391 acpi_status status;
392
393 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
394
395 /* Get the RSDP */
396 207
397 status = acpi_tb_find_rsdp(&table_info, flags); 208 physical_address = (u32)
398 if (ACPI_FAILURE(status)) { 209 (ACPI_HI_RSDP_WINDOW_BASE +
399 ACPI_EXCEPTION((AE_INFO, status, 210 ACPI_PTR_DIFF(mem_rover, table_ptr));
400 "RSDP structure not found - Flags=%X", flags));
401 211
402 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 212 *table_address = physical_address;
213 return_ACPI_STATUS(AE_OK);
403 } 214 }
404 215
405 rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; 216 /* A valid RSDP was not found */
406 rsdp_address->pointer.physical = table_info.physical_address; 217
407 return_ACPI_STATUS(AE_OK); 218 ACPI_ERROR((AE_INFO, "A valid RSDP was not found"));
219 return_ACPI_STATUS(AE_NOT_FOUND);
408} 220}
409 221
410ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) 222ACPI_EXPORT_SYMBOL(acpi_find_root_pointer)
@@ -440,7 +252,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
440 252
441 status = 253 status =
442 acpi_tb_validate_rsdp(ACPI_CAST_PTR 254 acpi_tb_validate_rsdp(ACPI_CAST_PTR
443 (struct rsdp_descriptor, mem_rover)); 255 (struct acpi_table_rsdp, mem_rover));
444 if (ACPI_SUCCESS(status)) { 256 if (ACPI_SUCCESS(status)) {
445 257
446 /* Sig and checksum valid, we have found a real RSDP */ 258 /* Sig and checksum valid, we have found a real RSDP */
@@ -461,189 +273,3 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
461 start_address)); 273 start_address));
462 return_PTR(NULL); 274 return_PTR(NULL);
463} 275}
464
465/*******************************************************************************
466 *
467 * FUNCTION: acpi_tb_find_rsdp
468 *
469 * PARAMETERS: table_info - Where the table info is returned
470 * Flags - Current memory mode (logical vs.
471 * physical addressing)
472 *
473 * RETURN: Status, RSDP physical address
474 *
475 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
476 * pointer structure. If it is found, set *RSDP to point to it.
477 *
478 * NOTE1: The RSDP must be either in the first 1_k of the Extended
479 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
480 * Only a 32-bit physical address is necessary.
481 *
482 * NOTE2: This function is always available, regardless of the
483 * initialization state of the rest of ACPI.
484 *
485 ******************************************************************************/
486
487static acpi_status
488acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags)
489{
490 u8 *table_ptr;
491 u8 *mem_rover;
492 u32 physical_address;
493 acpi_status status;
494
495 ACPI_FUNCTION_TRACE(tb_find_rsdp);
496
497 /*
498 * Scan supports either logical addressing or physical addressing
499 */
500 if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
501
502 /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
503
504 status = acpi_os_map_memory((acpi_physical_address)
505 ACPI_EBDA_PTR_LOCATION,
506 ACPI_EBDA_PTR_LENGTH,
507 (void *)&table_ptr);
508 if (ACPI_FAILURE(status)) {
509 ACPI_ERROR((AE_INFO,
510 "Could not map memory at %8.8X for length %X",
511 ACPI_EBDA_PTR_LOCATION,
512 ACPI_EBDA_PTR_LENGTH));
513
514 return_ACPI_STATUS(status);
515 }
516
517 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
518
519 /* Convert segment part to physical address */
520
521 physical_address <<= 4;
522 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
523
524 /* EBDA present? */
525
526 if (physical_address > 0x400) {
527 /*
528 * 1b) Search EBDA paragraphs (EBDA is required to be a
529 * minimum of 1_k length)
530 */
531 status = acpi_os_map_memory((acpi_physical_address)
532 physical_address,
533 ACPI_EBDA_WINDOW_SIZE,
534 (void *)&table_ptr);
535 if (ACPI_FAILURE(status)) {
536 ACPI_ERROR((AE_INFO,
537 "Could not map memory at %8.8X for length %X",
538 physical_address,
539 ACPI_EBDA_WINDOW_SIZE));
540
541 return_ACPI_STATUS(status);
542 }
543
544 mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr,
545 ACPI_EBDA_WINDOW_SIZE);
546 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
547
548 if (mem_rover) {
549
550 /* Return the physical address */
551
552 physical_address +=
553 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
554
555 table_info->physical_address =
556 (acpi_physical_address) physical_address;
557 return_ACPI_STATUS(AE_OK);
558 }
559 }
560
561 /*
562 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
563 */
564 status = acpi_os_map_memory((acpi_physical_address)
565 ACPI_HI_RSDP_WINDOW_BASE,
566 ACPI_HI_RSDP_WINDOW_SIZE,
567 (void *)&table_ptr);
568
569 if (ACPI_FAILURE(status)) {
570 ACPI_ERROR((AE_INFO,
571 "Could not map memory at %8.8X for length %X",
572 ACPI_HI_RSDP_WINDOW_BASE,
573 ACPI_HI_RSDP_WINDOW_SIZE));
574
575 return_ACPI_STATUS(status);
576 }
577
578 mem_rover =
579 acpi_tb_scan_memory_for_rsdp(table_ptr,
580 ACPI_HI_RSDP_WINDOW_SIZE);
581 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
582
583 if (mem_rover) {
584
585 /* Return the physical address */
586
587 physical_address = (u32)
588 (ACPI_HI_RSDP_WINDOW_BASE +
589 ACPI_PTR_DIFF(mem_rover, table_ptr));
590
591 table_info->physical_address =
592 (acpi_physical_address) physical_address;
593 return_ACPI_STATUS(AE_OK);
594 }
595 }
596
597 /*
598 * Physical addressing
599 */
600 else {
601 /* 1a) Get the location of the EBDA */
602
603 ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION);
604 physical_address <<= 4; /* Convert segment to physical address */
605
606 /* EBDA present? */
607
608 if (physical_address > 0x400) {
609 /*
610 * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of
611 * 1_k length)
612 */
613 mem_rover =
614 acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
615 (physical_address),
616 ACPI_EBDA_WINDOW_SIZE);
617 if (mem_rover) {
618
619 /* Return the physical address */
620
621 table_info->physical_address =
622 ACPI_TO_INTEGER(mem_rover);
623 return_ACPI_STATUS(AE_OK);
624 }
625 }
626
627 /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
628
629 mem_rover =
630 acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR
631 (ACPI_HI_RSDP_WINDOW_BASE),
632 ACPI_HI_RSDP_WINDOW_SIZE);
633 if (mem_rover) {
634
635 /* Found it, return the physical address */
636
637 table_info->physical_address =
638 ACPI_TO_INTEGER(mem_rover);
639 return_ACPI_STATUS(AE_OK);
640 }
641 }
642
643 /* A valid RSDP was not found */
644
645 ACPI_ERROR((AE_INFO, "No valid RSDP was found"));
646 return_ACPI_STATUS(AE_NOT_FOUND);
647}
648
649#endif
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 40ddb4dd9631..f76d3168c2b2 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
82 82
83static int acpi_thermal_add(struct acpi_device *device); 83static int acpi_thermal_add(struct acpi_device *device);
84static int acpi_thermal_remove(struct acpi_device *device, int type); 84static int acpi_thermal_remove(struct acpi_device *device, int type);
85static int acpi_thermal_resume(struct acpi_device *device, int state); 85static int acpi_thermal_resume(struct acpi_device *device);
86static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 86static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
87static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 87static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
88static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 88static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -1353,7 +1353,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1353 return 0; 1353 return 0;
1354} 1354}
1355 1355
1356static int acpi_thermal_resume(struct acpi_device *device, int state) 1356static int acpi_thermal_resume(struct acpi_device *device)
1357{ 1357{
1358 struct acpi_thermal *tz = NULL; 1358 struct acpi_thermal *tz = NULL;
1359 int i; 1359 int i;
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index f6cbc0b1bfd0..55a764807499 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
42 */ 42 */
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acdebug.h>
45 46
46#define _COMPONENT ACPI_UTILITIES 47#define _COMPONENT ACPI_UTILITIES
47ACPI_MODULE_NAME("utalloc") 48ACPI_MODULE_NAME("utalloc")
@@ -142,6 +143,14 @@ acpi_status acpi_ut_create_caches(void)
142 143
143acpi_status acpi_ut_delete_caches(void) 144acpi_status acpi_ut_delete_caches(void)
144{ 145{
146#ifdef ACPI_DBG_TRACK_ALLOCATIONS
147 char buffer[7];
148
149 if (acpi_gbl_display_final_mem_stats) {
150 ACPI_STRCPY(buffer, "MEMORY");
151 acpi_db_display_statistics(buffer);
152 }
153#endif
145 154
146 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); 155 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
147 acpi_gbl_namespace_cache = NULL; 156 acpi_gbl_namespace_cache = NULL;
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c
index 1a1f8109159c..870f6edeb5f2 100644
--- a/drivers/acpi/utilities/utcache.c
+++ b/drivers/acpi/utilities/utcache.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -289,6 +289,14 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache)
289 289
290 ACPI_MEM_TRACKING(cache->total_allocated++); 290 ACPI_MEM_TRACKING(cache->total_allocated++);
291 291
292#ifdef ACPI_DBG_TRACK_ALLOCATIONS
293 if ((cache->total_allocated - cache->total_freed) >
294 cache->max_occupied) {
295 cache->max_occupied =
296 cache->total_allocated - cache->total_freed;
297 }
298#endif
299
292 /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ 300 /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
293 301
294 status = acpi_ut_release_mutex(ACPI_MTX_CACHES); 302 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 5e1a80d1bc36..84d529db0a66 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -719,6 +719,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
719 acpi_ut_add_reference(source_desc->reference.object); 719 acpi_ut_add_reference(source_desc->reference.object);
720 break; 720 break;
721 721
722 case ACPI_TYPE_REGION:
723 /*
724 * We copied the Region Handler, so we now must add a reference
725 */
726 if (dest_desc->region.handler) {
727 acpi_ut_add_reference(dest_desc->region.handler);
728 }
729 break;
730
722 default: 731 default:
723 /* Nothing to do for other simple objects */ 732 /* Nothing to do for other simple objects */
724 break; 733 break;
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 9e9054e155c1..61ad4f2daee2 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -181,8 +181,7 @@ acpi_ut_debug_print(u32 requested_debug_level,
181 if (ACPI_LV_THREADS & acpi_dbg_level) { 181 if (ACPI_LV_THREADS & acpi_dbg_level) {
182 acpi_os_printf 182 acpi_os_printf
183 ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", 183 ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
184 (unsigned long) acpi_gbl_prev_thread_id, 184 (unsigned long)acpi_gbl_prev_thread_id, (unsigned long)thread_id);
185 (unsigned long) thread_id);
186 } 185 }
187 186
188 acpi_gbl_prev_thread_id = thread_id; 187 acpi_gbl_prev_thread_id = thread_id;
@@ -195,7 +194,7 @@ acpi_ut_debug_print(u32 requested_debug_level,
195 acpi_os_printf("%8s-%04ld ", module_name, line_number); 194 acpi_os_printf("%8s-%04ld ", module_name, line_number);
196 195
197 if (ACPI_LV_THREADS & acpi_dbg_level) { 196 if (ACPI_LV_THREADS & acpi_dbg_level) {
198 acpi_os_printf("[%04lX] ", thread_id); 197 acpi_os_printf("[%04lX] ", (unsigned long)thread_id);
199 } 198 }
200 199
201 acpi_os_printf("[%02ld] %-22.22s: ", 200 acpi_os_printf("[%02ld] %-22.22s: ",
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 9d3f1149ba21..f777cebdc46d 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -158,16 +158,20 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
158 "***** Mutex %p, OS Mutex %p\n", 158 "***** Mutex %p, OS Mutex %p\n",
159 object, object->mutex.os_mutex)); 159 object, object->mutex.os_mutex));
160 160
161 if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) { 161 if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
162 acpi_ex_unlink_mutex(object); 162
163 acpi_os_delete_mutex(object->mutex.os_mutex); 163 /* Global Lock has extra semaphore */
164 } else {
165 /* Global Lock "mutex" is actually a counting semaphore */
166 164
167 (void) 165 (void)
168 acpi_os_delete_semaphore 166 acpi_os_delete_semaphore
169 (acpi_gbl_global_lock_semaphore); 167 (acpi_gbl_global_lock_semaphore);
170 acpi_gbl_global_lock_semaphore = NULL; 168 acpi_gbl_global_lock_semaphore = NULL;
169
170 acpi_os_delete_mutex(object->mutex.os_mutex);
171 acpi_gbl_global_lock_mutex = NULL;
172 } else {
173 acpi_ex_unlink_mutex(object);
174 acpi_os_delete_mutex(object->mutex.os_mutex);
171 } 175 }
172 break; 176 break;
173 177
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index d6d7121583c0..13d5879cd98b 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 014030af8b50..af33358a964b 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -46,89 +46,9 @@
46#include <acpi/acpi.h> 46#include <acpi/acpi.h>
47#include <acpi/acnamesp.h> 47#include <acpi/acnamesp.h>
48 48
49ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
49#define _COMPONENT ACPI_UTILITIES 50#define _COMPONENT ACPI_UTILITIES
50ACPI_MODULE_NAME("utglobal") 51 ACPI_MODULE_NAME("utglobal")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_format_exception
55 *
56 * PARAMETERS: Status - The acpi_status code to be formatted
57 *
58 * RETURN: A string containing the exception text. A valid pointer is
59 * always returned.
60 *
61 * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
62 *
63 ******************************************************************************/
64const char *acpi_format_exception(acpi_status status)
65{
66 acpi_status sub_status;
67 const char *exception = NULL;
68
69 ACPI_FUNCTION_ENTRY();
70
71 /*
72 * Status is composed of two parts, a "type" and an actual code
73 */
74 sub_status = (status & ~AE_CODE_MASK);
75
76 switch (status & AE_CODE_MASK) {
77 case AE_CODE_ENVIRONMENTAL:
78
79 if (sub_status <= AE_CODE_ENV_MAX) {
80 exception = acpi_gbl_exception_names_env[sub_status];
81 }
82 break;
83
84 case AE_CODE_PROGRAMMER:
85
86 if (sub_status <= AE_CODE_PGM_MAX) {
87 exception =
88 acpi_gbl_exception_names_pgm[sub_status - 1];
89 }
90 break;
91
92 case AE_CODE_ACPI_TABLES:
93
94 if (sub_status <= AE_CODE_TBL_MAX) {
95 exception =
96 acpi_gbl_exception_names_tbl[sub_status - 1];
97 }
98 break;
99
100 case AE_CODE_AML:
101
102 if (sub_status <= AE_CODE_AML_MAX) {
103 exception =
104 acpi_gbl_exception_names_aml[sub_status - 1];
105 }
106 break;
107
108 case AE_CODE_CONTROL:
109
110 if (sub_status <= AE_CODE_CTRL_MAX) {
111 exception =
112 acpi_gbl_exception_names_ctrl[sub_status - 1];
113 }
114 break;
115
116 default:
117 break;
118 }
119
120 if (!exception) {
121
122 /* Exception code was not recognized */
123
124 ACPI_ERROR((AE_INFO,
125 "Unknown exception code: 0x%8.8X", status));
126
127 exception = "UNKNOWN_STATUS_CODE";
128 }
129
130 return (ACPI_CAST_PTR(const char, exception));
131}
132 52
133/******************************************************************************* 53/*******************************************************************************
134 * 54 *
@@ -163,8 +83,6 @@ u32 acpi_gbl_startup_flags = 0;
163 83
164u8 acpi_gbl_shutdown = TRUE; 84u8 acpi_gbl_shutdown = TRUE;
165 85
166const u8 acpi_gbl_decode_to8bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
167
168const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { 86const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
169 "\\_S0_", 87 "\\_S0_",
170 "\\_S1_", 88 "\\_S1_",
@@ -183,10 +101,45 @@ const char *acpi_gbl_highest_dstate_names[4] = {
183 101
184/******************************************************************************* 102/*******************************************************************************
185 * 103 *
186 * Namespace globals 104 * FUNCTION: acpi_format_exception
105 *
106 * PARAMETERS: Status - The acpi_status code to be formatted
107 *
108 * RETURN: A string containing the exception text. A valid pointer is
109 * always returned.
110 *
111 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
112 * It is here instead of utxface.c so it is always present.
187 * 113 *
188 ******************************************************************************/ 114 ******************************************************************************/
189 115
116const char *acpi_format_exception(acpi_status status)
117{
118 const char *exception = NULL;
119
120 ACPI_FUNCTION_ENTRY();
121
122 exception = acpi_ut_validate_exception(status);
123 if (!exception) {
124
125 /* Exception code was not recognized */
126
127 ACPI_ERROR((AE_INFO,
128 "Unknown exception code: 0x%8.8X", status));
129
130 exception = "UNKNOWN_STATUS_CODE";
131 }
132
133 return (ACPI_CAST_PTR(const char, exception));
134}
135
136ACPI_EXPORT_SYMBOL(acpi_format_exception)
137
138/*******************************************************************************
139 *
140 * Namespace globals
141 *
142 ******************************************************************************/
190/* 143/*
191 * Predefined ACPI Names (Built-in to the Interpreter) 144 * Predefined ACPI Names (Built-in to the Interpreter)
192 * 145 *
@@ -280,53 +233,6 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position)
280 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); 233 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
281} 234}
282 235
283/*******************************************************************************
284 *
285 * Table name globals
286 *
287 * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
288 * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables
289 * that are not used by the subsystem are simply ignored.
290 *
291 * Do NOT add any table to this list that is not consumed directly by this
292 * subsystem (No MADT, ECDT, SBST, etc.)
293 *
294 ******************************************************************************/
295
296struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1];
297
298struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = {
299 /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
300
301 /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1,
302 ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}
303 ,
304 /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT,
305 sizeof(DSDT_SIG) - 1,
306 ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE |
307 ACPI_TABLE_EXECUTABLE}
308 ,
309 /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT,
310 sizeof(FADT_SIG) - 1,
311 ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}
312 ,
313 /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS,
314 sizeof(FACS_SIG) - 1,
315 ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE}
316 ,
317 /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1,
318 ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE |
319 ACPI_TABLE_EXECUTABLE}
320 ,
321 /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1,
322 ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE |
323 ACPI_TABLE_EXECUTABLE}
324 ,
325 /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1,
326 ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}
327 ,
328};
329
330/****************************************************************************** 236/******************************************************************************
331 * 237 *
332 * Event and Hardware globals 238 * Event and Hardware globals
@@ -612,7 +518,7 @@ char *acpi_ut_get_node_name(void *object)
612 /* Name must be a valid ACPI name */ 518 /* Name must be a valid ACPI name */
613 519
614 if (!acpi_ut_valid_acpi_name(node->name.integer)) { 520 if (!acpi_ut_valid_acpi_name(node->name.integer)) {
615 node->name.integer = acpi_ut_repair_name(node->name.integer); 521 node->name.integer = acpi_ut_repair_name(node->name.ascii);
616 } 522 }
617 523
618 /* Return the name */ 524 /* Return the name */
@@ -751,13 +657,6 @@ void acpi_ut_init_globals(void)
751 return; 657 return;
752 } 658 }
753 659
754 /* ACPI table structure */
755
756 for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
757 acpi_gbl_table_lists[i].next = NULL;
758 acpi_gbl_table_lists[i].count = 0;
759 }
760
761 /* Mutex locked flags */ 660 /* Mutex locked flags */
762 661
763 for (i = 0; i < ACPI_NUM_MUTEX; i++) { 662 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
@@ -773,6 +672,7 @@ void acpi_ut_init_globals(void)
773 672
774 /* GPE support */ 673 /* GPE support */
775 674
675 acpi_gpe_count = 0;
776 acpi_gbl_gpe_xrupt_list_head = NULL; 676 acpi_gbl_gpe_xrupt_list_head = NULL;
777 acpi_gbl_gpe_fadt_blocks[0] = NULL; 677 acpi_gbl_gpe_fadt_blocks[0] = NULL;
778 acpi_gbl_gpe_fadt_blocks[1] = NULL; 678 acpi_gbl_gpe_fadt_blocks[1] = NULL;
@@ -784,25 +684,15 @@ void acpi_ut_init_globals(void)
784 acpi_gbl_exception_handler = NULL; 684 acpi_gbl_exception_handler = NULL;
785 acpi_gbl_init_handler = NULL; 685 acpi_gbl_init_handler = NULL;
786 686
787 /* Global "typed" ACPI table pointers */
788
789 acpi_gbl_RSDP = NULL;
790 acpi_gbl_XSDT = NULL;
791 acpi_gbl_FACS = NULL;
792 acpi_gbl_FADT = NULL;
793 acpi_gbl_DSDT = NULL;
794
795 /* Global Lock support */ 687 /* Global Lock support */
796 688
797 acpi_gbl_global_lock_semaphore = NULL; 689 acpi_gbl_global_lock_semaphore = NULL;
690 acpi_gbl_global_lock_mutex = NULL;
798 acpi_gbl_global_lock_acquired = FALSE; 691 acpi_gbl_global_lock_acquired = FALSE;
799 acpi_gbl_global_lock_thread_count = 0;
800 acpi_gbl_global_lock_handle = 0; 692 acpi_gbl_global_lock_handle = 0;
801 693
802 /* Miscellaneous variables */ 694 /* Miscellaneous variables */
803 695
804 acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER;
805 acpi_gbl_rsdp_original_location = 0;
806 acpi_gbl_cm_single_step = FALSE; 696 acpi_gbl_cm_single_step = FALSE;
807 acpi_gbl_db_terminate_threads = FALSE; 697 acpi_gbl_db_terminate_threads = FALSE;
808 acpi_gbl_shutdown = FALSE; 698 acpi_gbl_shutdown = FALSE;
@@ -837,8 +727,13 @@ void acpi_ut_init_globals(void)
837 acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; 727 acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX;
838#endif 728#endif
839 729
730#ifdef ACPI_DBG_TRACK_ALLOCATIONS
731 acpi_gbl_display_final_mem_stats = FALSE;
732#endif
733
840 return_VOID; 734 return_VOID;
841} 735}
842 736
843ACPI_EXPORT_SYMBOL(acpi_dbg_level) 737ACPI_EXPORT_SYMBOL(acpi_dbg_level)
844ACPI_EXPORT_SYMBOL(acpi_dbg_layer) 738ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
739ACPI_EXPORT_SYMBOL(acpi_gpe_count)
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index ff76055eb7d6..ad3c0d0a5cf8 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -44,119 +44,14 @@
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acnamesp.h> 45#include <acpi/acnamesp.h>
46#include <acpi/acevents.h> 46#include <acpi/acevents.h>
47#include <acpi/actables.h>
47 48
48#define _COMPONENT ACPI_UTILITIES 49#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utinit") 50ACPI_MODULE_NAME("utinit")
50 51
51/* Local prototypes */ 52/* Local prototypes */
52static void
53acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset);
54
55static void acpi_ut_terminate(void); 53static void acpi_ut_terminate(void);
56 54
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ut_fadt_register_error
60 *
61 * PARAMETERS: register_name - Pointer to string identifying register
62 * Value - Actual register contents value
63 * Offset - Byte offset in the FADT
64 *
65 * RETURN: AE_BAD_VALUE
66 *
67 * DESCRIPTION: Display failure message
68 *
69 ******************************************************************************/
70
71static void
72acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset)
73{
74
75 ACPI_WARNING((AE_INFO,
76 "Invalid FADT value %s=%X at offset %X FADT=%p",
77 register_name, value, offset, acpi_gbl_FADT));
78}
79
80/******************************************************************************
81 *
82 * FUNCTION: acpi_ut_validate_fadt
83 *
84 * PARAMETERS: None
85 *
86 * RETURN: Status
87 *
88 * DESCRIPTION: Validate various ACPI registers in the FADT
89 *
90 ******************************************************************************/
91
92acpi_status acpi_ut_validate_fadt(void)
93{
94
95 /*
96 * Verify Fixed ACPI Description Table fields,
97 * but don't abort on any problems, just display error
98 */
99 if (acpi_gbl_FADT->pm1_evt_len < 4) {
100 acpi_ut_fadt_register_error("PM1_EVT_LEN",
101 (u32) acpi_gbl_FADT->pm1_evt_len,
102 ACPI_FADT_OFFSET(pm1_evt_len));
103 }
104
105 if (!acpi_gbl_FADT->pm1_cnt_len) {
106 acpi_ut_fadt_register_error("PM1_CNT_LEN", 0,
107 ACPI_FADT_OFFSET(pm1_cnt_len));
108 }
109
110 if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
111 acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0,
112 ACPI_FADT_OFFSET(xpm1a_evt_blk.
113 address));
114 }
115
116 if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
117 acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0,
118 ACPI_FADT_OFFSET(xpm1a_cnt_blk.
119 address));
120 }
121
122 if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
123 acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0,
124 ACPI_FADT_OFFSET(xpm_tmr_blk.
125 address));
126 }
127
128 if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
129 !acpi_gbl_FADT->pm2_cnt_len)) {
130 acpi_ut_fadt_register_error("PM2_CNT_LEN",
131 (u32) acpi_gbl_FADT->pm2_cnt_len,
132 ACPI_FADT_OFFSET(pm2_cnt_len));
133 }
134
135 if (acpi_gbl_FADT->pm_tm_len < 4) {
136 acpi_ut_fadt_register_error("PM_TM_LEN",
137 (u32) acpi_gbl_FADT->pm_tm_len,
138 ACPI_FADT_OFFSET(pm_tm_len));
139 }
140
141 /* Length of GPE blocks must be a multiple of 2 */
142
143 if (acpi_gbl_FADT->xgpe0_blk.address &&
144 (acpi_gbl_FADT->gpe0_blk_len & 1)) {
145 acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN",
146 (u32) acpi_gbl_FADT->gpe0_blk_len,
147 ACPI_FADT_OFFSET(gpe0_blk_len));
148 }
149
150 if (acpi_gbl_FADT->xgpe1_blk.address &&
151 (acpi_gbl_FADT->gpe1_blk_len & 1)) {
152 acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN",
153 (u32) acpi_gbl_FADT->gpe1_blk_len,
154 ACPI_FADT_OFFSET(gpe1_blk_len));
155 }
156
157 return (AE_OK);
158}
159
160/****************************************************************************** 55/******************************************************************************
161 * 56 *
162 * FUNCTION: acpi_ut_terminate 57 * FUNCTION: acpi_ut_terminate
@@ -178,7 +73,6 @@ static void acpi_ut_terminate(void)
178 73
179 ACPI_FUNCTION_TRACE(ut_terminate); 74 ACPI_FUNCTION_TRACE(ut_terminate);
180 75
181 /* Free global tables, etc. */
182 /* Free global GPE blocks and related info structures */ 76 /* Free global GPE blocks and related info structures */
183 77
184 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; 78 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
@@ -239,6 +133,10 @@ void acpi_ut_subsystem_shutdown(void)
239 133
240 acpi_ns_terminate(); 134 acpi_ns_terminate();
241 135
136 /* Delete the ACPI tables */
137
138 acpi_tb_terminate();
139
242 /* Close the globals */ 140 /* Close the globals */
243 141
244 acpi_ut_terminate(); 142 acpi_ut_terminate();
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 19d74bedce27..0c56a0d20b29 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 6d8a8211be90..50133fffe420 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,78 @@ ACPI_MODULE_NAME("utmisc")
51 51
52/******************************************************************************* 52/*******************************************************************************
53 * 53 *
54 * FUNCTION: acpi_ut_validate_exception
55 *
56 * PARAMETERS: Status - The acpi_status code to be formatted
57 *
58 * RETURN: A string containing the exception text. NULL if exception is
59 * not valid.
60 *
61 * DESCRIPTION: This function validates and translates an ACPI exception into
62 * an ASCII string.
63 *
64 ******************************************************************************/
65const char *acpi_ut_validate_exception(acpi_status status)
66{
67 acpi_status sub_status;
68 const char *exception = NULL;
69
70 ACPI_FUNCTION_ENTRY();
71
72 /*
73 * Status is composed of two parts, a "type" and an actual code
74 */
75 sub_status = (status & ~AE_CODE_MASK);
76
77 switch (status & AE_CODE_MASK) {
78 case AE_CODE_ENVIRONMENTAL:
79
80 if (sub_status <= AE_CODE_ENV_MAX) {
81 exception = acpi_gbl_exception_names_env[sub_status];
82 }
83 break;
84
85 case AE_CODE_PROGRAMMER:
86
87 if (sub_status <= AE_CODE_PGM_MAX) {
88 exception =
89 acpi_gbl_exception_names_pgm[sub_status - 1];
90 }
91 break;
92
93 case AE_CODE_ACPI_TABLES:
94
95 if (sub_status <= AE_CODE_TBL_MAX) {
96 exception =
97 acpi_gbl_exception_names_tbl[sub_status - 1];
98 }
99 break;
100
101 case AE_CODE_AML:
102
103 if (sub_status <= AE_CODE_AML_MAX) {
104 exception =
105 acpi_gbl_exception_names_aml[sub_status - 1];
106 }
107 break;
108
109 case AE_CODE_CONTROL:
110
111 if (sub_status <= AE_CODE_CTRL_MAX) {
112 exception =
113 acpi_gbl_exception_names_ctrl[sub_status - 1];
114 }
115 break;
116
117 default:
118 break;
119 }
120
121 return (ACPI_CAST_PTR(const char, exception));
122}
123
124/*******************************************************************************
125 *
54 * FUNCTION: acpi_ut_is_aml_table 126 * FUNCTION: acpi_ut_is_aml_table
55 * 127 *
56 * PARAMETERS: Table - An ACPI table 128 * PARAMETERS: Table - An ACPI table
@@ -62,14 +134,15 @@ ACPI_MODULE_NAME("utmisc")
62 * data tables that do not contain AML code. 134 * data tables that do not contain AML code.
63 * 135 *
64 ******************************************************************************/ 136 ******************************************************************************/
137
65u8 acpi_ut_is_aml_table(struct acpi_table_header *table) 138u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
66{ 139{
67 140
68 /* These are the only tables that contain executable AML */ 141 /* These are the only tables that contain executable AML */
69 142
70 if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || 143 if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
71 ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || 144 ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
72 ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { 145 ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
73 return (TRUE); 146 return (TRUE);
74 } 147 }
75 148
@@ -418,7 +491,7 @@ u32 acpi_ut_dword_byte_swap(u32 value)
418void acpi_ut_set_integer_width(u8 revision) 491void acpi_ut_set_integer_width(u8 revision)
419{ 492{
420 493
421 if (revision <= 1) { 494 if (revision < 2) {
422 495
423 /* 32-bit case */ 496 /* 32-bit case */
424 497
@@ -582,26 +655,25 @@ u8 acpi_ut_valid_acpi_name(u32 name)
582 * 655 *
583 ******************************************************************************/ 656 ******************************************************************************/
584 657
585acpi_name acpi_ut_repair_name(acpi_name name) 658acpi_name acpi_ut_repair_name(char *name)
586{ 659{
587 char *name_ptr = ACPI_CAST_PTR(char, &name);
588 char new_name[ACPI_NAME_SIZE];
589 acpi_native_uint i; 660 acpi_native_uint i;
661 char new_name[ACPI_NAME_SIZE];
590 662
591 for (i = 0; i < ACPI_NAME_SIZE; i++) { 663 for (i = 0; i < ACPI_NAME_SIZE; i++) {
592 new_name[i] = name_ptr[i]; 664 new_name[i] = name[i];
593 665
594 /* 666 /*
595 * Replace a bad character with something printable, yet technically 667 * Replace a bad character with something printable, yet technically
596 * still invalid. This prevents any collisions with existing "good" 668 * still invalid. This prevents any collisions with existing "good"
597 * names in the namespace. 669 * names in the namespace.
598 */ 670 */
599 if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { 671 if (!acpi_ut_valid_acpi_char(name[i], i)) {
600 new_name[i] = '*'; 672 new_name[i] = '*';
601 } 673 }
602 } 674 }
603 675
604 return (*ACPI_CAST_PTR(u32, new_name)); 676 return (*(u32 *) new_name);
605} 677}
606 678
607/******************************************************************************* 679/*******************************************************************************
@@ -996,9 +1068,13 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
996{ 1068{
997 va_list args; 1069 va_list args;
998 1070
999 acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); 1071 /*
1072 * Removed module_name, line_number, and acpica version, not needed
1073 * for info output
1074 */
1075 acpi_os_printf("ACPI: ");
1000 1076
1001 va_start(args, format); 1077 va_start(args, format);
1002 acpi_os_vprintf(format, args); 1078 acpi_os_vprintf(format, args);
1003 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1079 acpi_os_printf("\n");
1004} 1080}
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index 180e73ceb6e2..cbad2ef5987d 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index ba7d8ac702df..4696124759e1 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
index 5a2de92831d3..e8fe1ba6cc24 100644
--- a/drivers/acpi/utilities/utresrc.c
+++ b/drivers/acpi/utilities/utresrc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index eaa13d05c859..edcaafad0a31 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index 3538f69c82a1..de3276f4f468 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2006, R. Byron Moore 8 * Copyright (C) 2000 - 2007, R. Byron Moore
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,7 @@ acpi_status acpi_initialize_subsystem(void)
67 67
68 ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); 68 ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
69 69
70 acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
70 ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); 71 ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
71 72
72 /* Initialize the OS-Dependent layer */ 73 /* Initialize the OS-Dependent layer */
@@ -127,20 +128,6 @@ acpi_status acpi_enable_subsystem(u32 flags)
127 128
128 ACPI_FUNCTION_TRACE(acpi_enable_subsystem); 129 ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
129 130
130 /*
131 * We must initialize the hardware before we can enable ACPI.
132 * The values from the FADT are validated here.
133 */
134 if (!(flags & ACPI_NO_HARDWARE_INIT)) {
135 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
136 "[Init] Initializing ACPI hardware\n"));
137
138 status = acpi_hw_initialize();
139 if (ACPI_FAILURE(status)) {
140 return_ACPI_STATUS(status);
141 }
142 }
143
144 /* Enable ACPI mode */ 131 /* Enable ACPI mode */
145 132
146 if (!(flags & ACPI_NO_ACPI_ENABLE)) { 133 if (!(flags & ACPI_NO_ACPI_ENABLE)) {
@@ -398,7 +385,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
398{ 385{
399 struct acpi_system_info *info_ptr; 386 struct acpi_system_info *info_ptr;
400 acpi_status status; 387 acpi_status status;
401 u32 i;
402 388
403 ACPI_FUNCTION_TRACE(acpi_get_system_info); 389 ACPI_FUNCTION_TRACE(acpi_get_system_info);
404 390
@@ -431,9 +417,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
431 417
432 /* Timer resolution - 24 or 32 bits */ 418 /* Timer resolution - 24 or 32 bits */
433 419
434 if (!acpi_gbl_FADT) { 420 if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
435 info_ptr->timer_resolution = 0;
436 } else if (acpi_gbl_FADT->tmr_val_ext == 0) {
437 info_ptr->timer_resolution = 24; 421 info_ptr->timer_resolution = 24;
438 } else { 422 } else {
439 info_ptr->timer_resolution = 32; 423 info_ptr->timer_resolution = 32;
@@ -449,13 +433,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
449 info_ptr->debug_layer = acpi_dbg_layer; 433 info_ptr->debug_layer = acpi_dbg_layer;
450 info_ptr->debug_level = acpi_dbg_level; 434 info_ptr->debug_level = acpi_dbg_level;
451 435
452 /* Current status of the ACPI tables, per table type */
453
454 info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1;
455 for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
456 info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
457 }
458
459 return_ACPI_STATUS(AE_OK); 436 return_ACPI_STATUS(AE_OK);
460} 437}
461 438
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3d54680d0333..e0b97add8c63 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -32,6 +32,7 @@
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -56,6 +57,12 @@
56 57
57#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 58#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
58#define ACPI_VIDEO_HEAD_END (~0u) 59#define ACPI_VIDEO_HEAD_END (~0u)
60#define MAX_NAME_LEN 20
61
62#define ACPI_VIDEO_DISPLAY_CRT 1
63#define ACPI_VIDEO_DISPLAY_TV 2
64#define ACPI_VIDEO_DISPLAY_DVI 3
65#define ACPI_VIDEO_DISPLAY_LCD 4
59 66
60#define _COMPONENT ACPI_VIDEO_COMPONENT 67#define _COMPONENT ACPI_VIDEO_COMPONENT
61ACPI_MODULE_NAME("acpi_video") 68ACPI_MODULE_NAME("acpi_video")
@@ -66,16 +73,14 @@ MODULE_LICENSE("GPL");
66 73
67static int acpi_video_bus_add(struct acpi_device *device); 74static int acpi_video_bus_add(struct acpi_device *device);
68static int acpi_video_bus_remove(struct acpi_device *device, int type); 75static int acpi_video_bus_remove(struct acpi_device *device, int type);
69static int acpi_video_bus_match(struct acpi_device *device,
70 struct acpi_driver *driver);
71 76
72static struct acpi_driver acpi_video_bus = { 77static struct acpi_driver acpi_video_bus = {
73 .name = ACPI_VIDEO_DRIVER_NAME, 78 .name = ACPI_VIDEO_DRIVER_NAME,
74 .class = ACPI_VIDEO_CLASS, 79 .class = ACPI_VIDEO_CLASS,
80 .ids = ACPI_VIDEO_HID,
75 .ops = { 81 .ops = {
76 .add = acpi_video_bus_add, 82 .add = acpi_video_bus_add,
77 .remove = acpi_video_bus_remove, 83 .remove = acpi_video_bus_remove,
78 .match = acpi_video_bus_match,
79 }, 84 },
80}; 85};
81 86
@@ -133,20 +138,21 @@ struct acpi_video_device_flags {
133 u8 crt:1; 138 u8 crt:1;
134 u8 lcd:1; 139 u8 lcd:1;
135 u8 tvout:1; 140 u8 tvout:1;
141 u8 dvi:1;
136 u8 bios:1; 142 u8 bios:1;
137 u8 unknown:1; 143 u8 unknown:1;
138 u8 reserved:3; 144 u8 reserved:2;
139}; 145};
140 146
141struct acpi_video_device_cap { 147struct acpi_video_device_cap {
142 u8 _ADR:1; /*Return the unique ID */ 148 u8 _ADR:1; /*Return the unique ID */
143 u8 _BCL:1; /*Query list of brightness control levels supported */ 149 u8 _BCL:1; /*Query list of brightness control levels supported */
144 u8 _BCM:1; /*Set the brightness level */ 150 u8 _BCM:1; /*Set the brightness level */
151 u8 _BQC:1; /* Get current brightness level */
145 u8 _DDC:1; /*Return the EDID for this device */ 152 u8 _DDC:1; /*Return the EDID for this device */
146 u8 _DCS:1; /*Return status of output device */ 153 u8 _DCS:1; /*Return status of output device */
147 u8 _DGS:1; /*Query graphics state */ 154 u8 _DGS:1; /*Query graphics state */
148 u8 _DSS:1; /*Device state set */ 155 u8 _DSS:1; /*Device state set */
149 u8 _reserved:1;
150}; 156};
151 157
152struct acpi_video_device_brightness { 158struct acpi_video_device_brightness {
@@ -163,6 +169,8 @@ struct acpi_video_device {
163 struct acpi_video_bus *video; 169 struct acpi_video_bus *video;
164 struct acpi_device *dev; 170 struct acpi_device *dev;
165 struct acpi_video_device_brightness *brightness; 171 struct acpi_video_device_brightness *brightness;
172 struct backlight_device *backlight;
173 struct backlight_properties *data;
166}; 174};
167 175
168/* bus */ 176/* bus */
@@ -257,11 +265,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video,
257 struct acpi_video_device *device); 265 struct acpi_video_device *device);
258static int acpi_video_device_enumerate(struct acpi_video_bus *video); 266static int acpi_video_device_enumerate(struct acpi_video_bus *video);
259static int acpi_video_switch_output(struct acpi_video_bus *video, int event); 267static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
268static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
269 int level);
270static int acpi_video_device_lcd_get_level_current(
271 struct acpi_video_device *device,
272 unsigned long *level);
260static int acpi_video_get_next_level(struct acpi_video_device *device, 273static int acpi_video_get_next_level(struct acpi_video_device *device,
261 u32 level_current, u32 event); 274 u32 level_current, u32 event);
262static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
263 int event); 276 int event);
264 277
278/*backlight device sysfs support*/
279static int acpi_video_get_brightness(struct backlight_device *bd)
280{
281 unsigned long cur_level;
282 struct acpi_video_device *vd =
283 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
284 acpi_video_device_lcd_get_level_current(vd, &cur_level);
285 return (int) cur_level;
286}
287
288static int acpi_video_set_brightness(struct backlight_device *bd)
289{
290 int request_level = bd->props->brightness;
291 struct acpi_video_device *vd =
292 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
293 acpi_video_device_lcd_set_level(vd, request_level);
294 return 0;
295}
296
265/* -------------------------------------------------------------------------- 297/* --------------------------------------------------------------------------
266 Video Management 298 Video Management
267 -------------------------------------------------------------------------- */ 299 -------------------------------------------------------------------------- */
@@ -499,6 +531,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
499 acpi_integer status; 531 acpi_integer status;
500 acpi_handle h_dummy1; 532 acpi_handle h_dummy1;
501 int i; 533 int i;
534 u32 max_level = 0;
502 union acpi_object *obj = NULL; 535 union acpi_object *obj = NULL;
503 struct acpi_video_device_brightness *br = NULL; 536 struct acpi_video_device_brightness *br = NULL;
504 537
@@ -514,6 +547,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
514 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 547 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
515 device->cap._BCM = 1; 548 device->cap._BCM = 1;
516 } 549 }
550 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
551 device->cap._BQC = 1;
517 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 552 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
518 device->cap._DDC = 1; 553 device->cap._DDC = 1;
519 } 554 }
@@ -550,6 +585,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
550 continue; 585 continue;
551 } 586 }
552 br->levels[count] = (u32) o->integer.value; 587 br->levels[count] = (u32) o->integer.value;
588 if (br->levels[count] > max_level)
589 max_level = br->levels[count];
553 count++; 590 count++;
554 } 591 }
555 out: 592 out:
@@ -568,6 +605,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
568 605
569 kfree(obj); 606 kfree(obj);
570 607
608 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
609 unsigned long tmp;
610 static int count = 0;
611 char *name;
612 struct backlight_properties *acpi_video_data;
613
614 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
615 if (!name)
616 return;
617
618 acpi_video_data = kzalloc(
619 sizeof(struct backlight_properties),
620 GFP_KERNEL);
621 if (!acpi_video_data){
622 kfree(name);
623 return;
624 }
625 acpi_video_data->owner = THIS_MODULE;
626 acpi_video_data->get_brightness =
627 acpi_video_get_brightness;
628 acpi_video_data->update_status =
629 acpi_video_set_brightness;
630 sprintf(name, "acpi_video%d", count++);
631 device->data = acpi_video_data;
632 acpi_video_data->max_brightness = max_level;
633 acpi_video_device_lcd_get_level_current(device, &tmp);
634 acpi_video_data->brightness = (int)tmp;
635 device->backlight = backlight_device_register(name,
636 NULL, device, acpi_video_data);
637 kfree(name);
638 }
571 return; 639 return;
572} 640}
573 641
@@ -668,6 +736,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
668 seq_printf(seq, "LCD\n"); 736 seq_printf(seq, "LCD\n");
669 else if (dev->flags.tvout) 737 else if (dev->flags.tvout)
670 seq_printf(seq, "TVOUT\n"); 738 seq_printf(seq, "TVOUT\n");
739 else if (dev->flags.dvi)
740 seq_printf(seq, "DVI\n");
671 else 741 else
672 seq_printf(seq, "UNKNOWN\n"); 742 seq_printf(seq, "UNKNOWN\n");
673 743
@@ -1242,6 +1312,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1242 -------------------------------------------------------------------------- */ 1312 -------------------------------------------------------------------------- */
1243 1313
1244/* device interface */ 1314/* device interface */
1315static struct acpi_video_device_attrib*
1316acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1317{
1318 int count;
1319
1320 for(count = 0; count < video->attached_count; count++)
1321 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1322 return &(video->attached_array[count].value.attrib);
1323 return NULL;
1324}
1245 1325
1246static int 1326static int
1247acpi_video_bus_get_one_device(struct acpi_device *device, 1327acpi_video_bus_get_one_device(struct acpi_device *device,
@@ -1250,7 +1330,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1250 unsigned long device_id; 1330 unsigned long device_id;
1251 int status; 1331 int status;
1252 struct acpi_video_device *data; 1332 struct acpi_video_device *data;
1253 1333 struct acpi_video_device_attrib* attribute;
1254 1334
1255 if (!device || !video) 1335 if (!device || !video)
1256 return -EINVAL; 1336 return -EINVAL;
@@ -1271,20 +1351,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1271 data->video = video; 1351 data->video = video;
1272 data->dev = device; 1352 data->dev = device;
1273 1353
1274 switch (device_id & 0xffff) { 1354 attribute = acpi_video_get_device_attr(video, device_id);
1275 case 0x0100: 1355
1276 data->flags.crt = 1; 1356 if((attribute != NULL) && attribute->device_id_scheme) {
1277 break; 1357 switch (attribute->display_type) {
1278 case 0x0400: 1358 case ACPI_VIDEO_DISPLAY_CRT:
1279 data->flags.lcd = 1; 1359 data->flags.crt = 1;
1280 break; 1360 break;
1281 case 0x0200: 1361 case ACPI_VIDEO_DISPLAY_TV:
1282 data->flags.tvout = 1; 1362 data->flags.tvout = 1;
1283 break; 1363 break;
1284 default: 1364 case ACPI_VIDEO_DISPLAY_DVI:
1365 data->flags.dvi = 1;
1366 break;
1367 case ACPI_VIDEO_DISPLAY_LCD:
1368 data->flags.lcd = 1;
1369 break;
1370 default:
1371 data->flags.unknown = 1;
1372 break;
1373 }
1374 if(attribute->bios_can_detect)
1375 data->flags.bios = 1;
1376 } else
1285 data->flags.unknown = 1; 1377 data->flags.unknown = 1;
1286 break;
1287 }
1288 1378
1289 acpi_video_device_bind(video, data); 1379 acpi_video_device_bind(video, data);
1290 acpi_video_device_find_cap(data); 1380 acpi_video_device_find_cap(data);
@@ -1588,7 +1678,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1588 status = acpi_remove_notify_handler(device->dev->handle, 1678 status = acpi_remove_notify_handler(device->dev->handle,
1589 ACPI_DEVICE_NOTIFY, 1679 ACPI_DEVICE_NOTIFY,
1590 acpi_video_device_notify); 1680 acpi_video_device_notify);
1591 1681 if (device->backlight){
1682 backlight_device_unregister(device->backlight);
1683 kfree(device->data);
1684 }
1592 return 0; 1685 return 0;
1593} 1686}
1594 1687
@@ -1790,39 +1883,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1790 return 0; 1883 return 0;
1791} 1884}
1792 1885
1793static int
1794acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
1795{
1796 acpi_handle h_dummy1;
1797 acpi_handle h_dummy2;
1798 acpi_handle h_dummy3;
1799
1800
1801 if (!device || !driver)
1802 return -EINVAL;
1803
1804 /* Since there is no HID, CID for ACPI Video drivers, we have
1805 * to check well known required nodes for each feature we support.
1806 */
1807
1808 /* Does this device able to support video switching ? */
1809 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
1810 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
1811 return 0;
1812
1813 /* Does this device able to retrieve a video ROM ? */
1814 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
1815 return 0;
1816
1817 /* Does this device able to configure which video head to be POSTed ? */
1818 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
1819 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
1820 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
1821 return 0;
1822
1823 return -ENODEV;
1824}
1825
1826static int __init acpi_video_init(void) 1886static int __init acpi_video_init(void)
1827{ 1887{
1828 int result = 0; 1888 int result = 0;
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index f1afd26a509f..a7b33d2f5991 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1802,7 +1802,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
1802 return -ENODEV; 1802 return -ENODEV;
1803 } 1803 }
1804 1804
1805 if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) 1805 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
1806 addr_space = IPMI_MEM_ADDR_SPACE; 1806 addr_space = IPMI_MEM_ADDR_SPACE;
1807 else 1807 else
1808 addr_space = IPMI_IO_ADDR_SPACE; 1808 addr_space = IPMI_IO_ADDR_SPACE;
@@ -1848,19 +1848,19 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
1848 info->irq_setup = NULL; 1848 info->irq_setup = NULL;
1849 } 1849 }
1850 1850
1851 if (spmi->addr.register_bit_width) { 1851 if (spmi->addr.bit_width) {
1852 /* A (hopefully) properly formed register bit width. */ 1852 /* A (hopefully) properly formed register bit width. */
1853 info->io.regspacing = spmi->addr.register_bit_width / 8; 1853 info->io.regspacing = spmi->addr.bit_width / 8;
1854 } else { 1854 } else {
1855 info->io.regspacing = DEFAULT_REGSPACING; 1855 info->io.regspacing = DEFAULT_REGSPACING;
1856 } 1856 }
1857 info->io.regsize = info->io.regspacing; 1857 info->io.regsize = info->io.regspacing;
1858 info->io.regshift = spmi->addr.register_bit_offset; 1858 info->io.regshift = spmi->addr.bit_offset;
1859 1859
1860 if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 1860 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
1861 info->io_setup = mem_setup; 1861 info->io_setup = mem_setup;
1862 info->io.addr_type = IPMI_IO_ADDR_SPACE; 1862 info->io.addr_type = IPMI_IO_ADDR_SPACE;
1863 } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 1863 } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
1864 info->io_setup = port_setup; 1864 info->io_setup = port_setup;
1865 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 1865 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
1866 } else { 1866 } else {
@@ -1888,10 +1888,8 @@ static __devinit void acpi_find_bmc(void)
1888 return; 1888 return;
1889 1889
1890 for (i = 0; ; i++) { 1890 for (i = 0; ; i++) {
1891 status = acpi_get_firmware_table("SPMI", i+1, 1891 status = acpi_get_table(ACPI_SIG_SPMI, i+1,
1892 ACPI_LOGICAL_ADDRESSING, 1892 (struct acpi_table_header **)&spmi);
1893 (struct acpi_table_header **)
1894 &spmi);
1895 if (status != AE_OK) 1893 if (status != AE_OK)
1896 return; 1894 return;
1897 1895
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index a611972024e6..7fca5f470beb 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -372,10 +372,8 @@ static int read_log(struct tpm_bios_log *log)
372 } 372 }
373 373
374 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ 374 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
375 status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1, 375 status = acpi_get_table(ACPI_SIG_TCPA, 1,
376 ACPI_LOGICAL_ADDRESSING, 376 (struct acpi_table_header **)&buff);
377 (struct acpi_table_header **)
378 &buff);
379 377
380 if (ACPI_FAILURE(status)) { 378 if (ACPI_FAILURE(status)) {
381 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", 379 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
@@ -409,7 +407,7 @@ static int read_log(struct tpm_bios_log *log)
409 407
410 log->bios_event_log_end = log->bios_event_log + len; 408 log->bios_event_log_end = log->bios_event_log + len;
411 409
412 acpi_os_map_memory(start, len, (void *) &virt); 410 virt = acpi_os_map_memory(start, len);
413 411
414 memcpy(log->bios_event_log, virt, len); 412 memcpy(log->bios_event_log, virt, len);
415 413
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 879250d3d069..ff8c4beaace4 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -51,6 +51,8 @@ config CRYPTO_DEV_PADLOCK_SHA
51 If unsure say M. The compiled module will be 51 If unsure say M. The compiled module will be
52 called padlock-sha.ko 52 called padlock-sha.ko
53 53
54source "arch/s390/crypto/Kconfig"
55
54config CRYPTO_DEV_GEODE 56config CRYPTO_DEV_GEODE
55 tristate "Support for the Geode LX AES engine" 57 tristate "Support for the Geode LX AES engine"
56 depends on CRYPTO && X86_32 && PCI 58 depends on CRYPTO && X86_32 && PCI
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index c2ad72fefd9d..2b4b76e8bd72 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -26,7 +26,7 @@ setup_serial_console(struct pcdp_uart *uart)
26 static char options[64], *p = options; 26 static char options[64], *p = options;
27 char parity; 27 char parity;
28 28
29 mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); 29 mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
30 p += sprintf(p, "console=uart,%s,0x%lx", 30 p += sprintf(p, "console=uart,%s,0x%lx",
31 mmio ? "mmio" : "io", uart->addr.address); 31 mmio ? "mmio" : "io", uart->addr.address);
32 if (uart->baud) { 32 if (uart->baud) {
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index ec796ad087df..850788f4dd2e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -22,5 +22,19 @@ config HID
22 22
23 If unsure, say Y 23 If unsure, say Y
24 24
25config HID_DEBUG
26 bool "HID debugging support"
27 depends on HID
28 ---help---
29 This option lets the HID layer output diagnostics about its internal
30 state, resolve HID usages, dump HID fields, etc. Individual HID drivers
31 use this debugging facility to output information about individual HID
32 devices, etc.
33
34 This feature is useful for those who are either debugging the HID parser
35 or any HID hardware device.
36
37 If unsure, say N
38
25endmenu 39endmenu
26 40
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 6432392110bf..52e97d8f3c95 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -1,15 +1,8 @@
1# 1#
2# Makefile for the HID driver 2# Makefile for the HID driver
3# 3#
4 4hid-objs := hid-core.o hid-input.o
5# Multipart objects.
6hid-objs := hid-core.o hid-input.o
7
8# Optional parts of multipart objects.
9 5
10obj-$(CONFIG_HID) += hid.o 6obj-$(CONFIG_HID) += hid.o
11 7hid-$(CONFIG_HID_DEBUG) += hid-debug.o
12ifeq ($(CONFIG_INPUT_DEBUG),y)
13EXTRA_CFLAGS += -DDEBUG
14endif
15 8
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 49f18f5b2514..8c7d48eff7b7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -28,11 +28,9 @@
28#include <linux/input.h> 28#include <linux/input.h>
29#include <linux/wait.h> 29#include <linux/wait.h>
30 30
31#undef DEBUG
32#undef DEBUG_DATA
33
34#include <linux/hid.h> 31#include <linux/hid.h>
35#include <linux/hiddev.h> 32#include <linux/hiddev.h>
33#include <linux/hid-debug.h>
36 34
37/* 35/*
38 * Version Information 36 * Version Information
@@ -951,7 +949,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
951 return -1; 949 return -1;
952 } 950 }
953 951
954#ifdef DEBUG_DATA 952#ifdef CONFIG_HID_DEBUG
955 printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); 953 printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
956#endif 954#endif
957 955
@@ -961,7 +959,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
961 size--; 959 size--;
962 } 960 }
963 961
964#ifdef DEBUG_DATA 962#ifdef CONFIG_HID_DEBUG
965 { 963 {
966 int i; 964 int i;
967 printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size); 965 printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size);
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
new file mode 100644
index 000000000000..89241be4ec9b
--- /dev/null
+++ b/drivers/hid/hid-debug.c
@@ -0,0 +1,764 @@
1/*
2 * $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $
3 *
4 * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
5 * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
6 * (c) 2007 Jiri Kosina
7 *
8 * Some debug stuff for the HID parser.
9 */
10
11/*
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * Should you need to contact me, the author, you can do so either by
27 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
28 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
29 */
30
31#include <linux/hid.h>
32
33struct hid_usage_entry {
34 unsigned page;
35 unsigned usage;
36 char *description;
37};
38
39static const struct hid_usage_entry hid_usage_table[] = {
40 { 0, 0, "Undefined" },
41 { 1, 0, "GenericDesktop" },
42 {0, 0x01, "Pointer"},
43 {0, 0x02, "Mouse"},
44 {0, 0x04, "Joystick"},
45 {0, 0x05, "GamePad"},
46 {0, 0x06, "Keyboard"},
47 {0, 0x07, "Keypad"},
48 {0, 0x08, "MultiAxis"},
49 {0, 0x30, "X"},
50 {0, 0x31, "Y"},
51 {0, 0x32, "Z"},
52 {0, 0x33, "Rx"},
53 {0, 0x34, "Ry"},
54 {0, 0x35, "Rz"},
55 {0, 0x36, "Slider"},
56 {0, 0x37, "Dial"},
57 {0, 0x38, "Wheel"},
58 {0, 0x39, "HatSwitch"},
59 {0, 0x3a, "CountedBuffer"},
60 {0, 0x3b, "ByteCount"},
61 {0, 0x3c, "MotionWakeup"},
62 {0, 0x3d, "Start"},
63 {0, 0x3e, "Select"},
64 {0, 0x40, "Vx"},
65 {0, 0x41, "Vy"},
66 {0, 0x42, "Vz"},
67 {0, 0x43, "Vbrx"},
68 {0, 0x44, "Vbry"},
69 {0, 0x45, "Vbrz"},
70 {0, 0x46, "Vno"},
71 {0, 0x80, "SystemControl"},
72 {0, 0x81, "SystemPowerDown"},
73 {0, 0x82, "SystemSleep"},
74 {0, 0x83, "SystemWakeUp"},
75 {0, 0x84, "SystemContextMenu"},
76 {0, 0x85, "SystemMainMenu"},
77 {0, 0x86, "SystemAppMenu"},
78 {0, 0x87, "SystemMenuHelp"},
79 {0, 0x88, "SystemMenuExit"},
80 {0, 0x89, "SystemMenuSelect"},
81 {0, 0x8a, "SystemMenuRight"},
82 {0, 0x8b, "SystemMenuLeft"},
83 {0, 0x8c, "SystemMenuUp"},
84 {0, 0x8d, "SystemMenuDown"},
85 {0, 0x90, "D-PadUp"},
86 {0, 0x91, "D-PadDown"},
87 {0, 0x92, "D-PadRight"},
88 {0, 0x93, "D-PadLeft"},
89 { 2, 0, "Simulation" },
90 {0, 0xb0, "Aileron"},
91 {0, 0xb1, "AileronTrim"},
92 {0, 0xb2, "Anti-Torque"},
93 {0, 0xb3, "Autopilot"},
94 {0, 0xb4, "Chaff"},
95 {0, 0xb5, "Collective"},
96 {0, 0xb6, "DiveBrake"},
97 {0, 0xb7, "ElectronicCountermeasures"},
98 {0, 0xb8, "Elevator"},
99 {0, 0xb9, "ElevatorTrim"},
100 {0, 0xba, "Rudder"},
101 {0, 0xbb, "Throttle"},
102 {0, 0xbc, "FlightCommunications"},
103 {0, 0xbd, "FlareRelease"},
104 {0, 0xbe, "LandingGear"},
105 {0, 0xbf, "ToeBrake"},
106 { 7, 0, "Keyboard" },
107 { 8, 0, "LED" },
108 {0, 0x01, "NumLock"},
109 {0, 0x02, "CapsLock"},
110 {0, 0x03, "ScrollLock"},
111 {0, 0x04, "Compose"},
112 {0, 0x05, "Kana"},
113 {0, 0x4b, "GenericIndicator"},
114 { 9, 0, "Button" },
115 { 10, 0, "Ordinal" },
116 { 12, 0, "Consumer" },
117 {0, 0x238, "HorizontalWheel"},
118 { 13, 0, "Digitizers" },
119 {0, 0x01, "Digitizer"},
120 {0, 0x02, "Pen"},
121 {0, 0x03, "LightPen"},
122 {0, 0x04, "TouchScreen"},
123 {0, 0x05, "TouchPad"},
124 {0, 0x20, "Stylus"},
125 {0, 0x21, "Puck"},
126 {0, 0x22, "Finger"},
127 {0, 0x30, "TipPressure"},
128 {0, 0x31, "BarrelPressure"},
129 {0, 0x32, "InRange"},
130 {0, 0x33, "Touch"},
131 {0, 0x34, "UnTouch"},
132 {0, 0x35, "Tap"},
133 {0, 0x39, "TabletFunctionKey"},
134 {0, 0x3a, "ProgramChangeKey"},
135 {0, 0x3c, "Invert"},
136 {0, 0x42, "TipSwitch"},
137 {0, 0x43, "SecondaryTipSwitch"},
138 {0, 0x44, "BarrelSwitch"},
139 {0, 0x45, "Eraser"},
140 {0, 0x46, "TabletPick"},
141 { 15, 0, "PhysicalInterfaceDevice" },
142 {0, 0x00, "Undefined"},
143 {0, 0x01, "Physical_Interface_Device"},
144 {0, 0x20, "Normal"},
145 {0, 0x21, "Set_Effect_Report"},
146 {0, 0x22, "Effect_Block_Index"},
147 {0, 0x23, "Parameter_Block_Offset"},
148 {0, 0x24, "ROM_Flag"},
149 {0, 0x25, "Effect_Type"},
150 {0, 0x26, "ET_Constant_Force"},
151 {0, 0x27, "ET_Ramp"},
152 {0, 0x28, "ET_Custom_Force_Data"},
153 {0, 0x30, "ET_Square"},
154 {0, 0x31, "ET_Sine"},
155 {0, 0x32, "ET_Triangle"},
156 {0, 0x33, "ET_Sawtooth_Up"},
157 {0, 0x34, "ET_Sawtooth_Down"},
158 {0, 0x40, "ET_Spring"},
159 {0, 0x41, "ET_Damper"},
160 {0, 0x42, "ET_Inertia"},
161 {0, 0x43, "ET_Friction"},
162 {0, 0x50, "Duration"},
163 {0, 0x51, "Sample_Period"},
164 {0, 0x52, "Gain"},
165 {0, 0x53, "Trigger_Button"},
166 {0, 0x54, "Trigger_Repeat_Interval"},
167 {0, 0x55, "Axes_Enable"},
168 {0, 0x56, "Direction_Enable"},
169 {0, 0x57, "Direction"},
170 {0, 0x58, "Type_Specific_Block_Offset"},
171 {0, 0x59, "Block_Type"},
172 {0, 0x5A, "Set_Envelope_Report"},
173 {0, 0x5B, "Attack_Level"},
174 {0, 0x5C, "Attack_Time"},
175 {0, 0x5D, "Fade_Level"},
176 {0, 0x5E, "Fade_Time"},
177 {0, 0x5F, "Set_Condition_Report"},
178 {0, 0x60, "CP_Offset"},
179 {0, 0x61, "Positive_Coefficient"},
180 {0, 0x62, "Negative_Coefficient"},
181 {0, 0x63, "Positive_Saturation"},
182 {0, 0x64, "Negative_Saturation"},
183 {0, 0x65, "Dead_Band"},
184 {0, 0x66, "Download_Force_Sample"},
185 {0, 0x67, "Isoch_Custom_Force_Enable"},
186 {0, 0x68, "Custom_Force_Data_Report"},
187 {0, 0x69, "Custom_Force_Data"},
188 {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
189 {0, 0x6B, "Set_Custom_Force_Report"},
190 {0, 0x6C, "Custom_Force_Data_Offset"},
191 {0, 0x6D, "Sample_Count"},
192 {0, 0x6E, "Set_Periodic_Report"},
193 {0, 0x6F, "Offset"},
194 {0, 0x70, "Magnitude"},
195 {0, 0x71, "Phase"},
196 {0, 0x72, "Period"},
197 {0, 0x73, "Set_Constant_Force_Report"},
198 {0, 0x74, "Set_Ramp_Force_Report"},
199 {0, 0x75, "Ramp_Start"},
200 {0, 0x76, "Ramp_End"},
201 {0, 0x77, "Effect_Operation_Report"},
202 {0, 0x78, "Effect_Operation"},
203 {0, 0x79, "Op_Effect_Start"},
204 {0, 0x7A, "Op_Effect_Start_Solo"},
205 {0, 0x7B, "Op_Effect_Stop"},
206 {0, 0x7C, "Loop_Count"},
207 {0, 0x7D, "Device_Gain_Report"},
208 {0, 0x7E, "Device_Gain"},
209 {0, 0x7F, "PID_Pool_Report"},
210 {0, 0x80, "RAM_Pool_Size"},
211 {0, 0x81, "ROM_Pool_Size"},
212 {0, 0x82, "ROM_Effect_Block_Count"},
213 {0, 0x83, "Simultaneous_Effects_Max"},
214 {0, 0x84, "Pool_Alignment"},
215 {0, 0x85, "PID_Pool_Move_Report"},
216 {0, 0x86, "Move_Source"},
217 {0, 0x87, "Move_Destination"},
218 {0, 0x88, "Move_Length"},
219 {0, 0x89, "PID_Block_Load_Report"},
220 {0, 0x8B, "Block_Load_Status"},
221 {0, 0x8C, "Block_Load_Success"},
222 {0, 0x8D, "Block_Load_Full"},
223 {0, 0x8E, "Block_Load_Error"},
224 {0, 0x8F, "Block_Handle"},
225 {0, 0x90, "PID_Block_Free_Report"},
226 {0, 0x91, "Type_Specific_Block_Handle"},
227 {0, 0x92, "PID_State_Report"},
228 {0, 0x94, "Effect_Playing"},
229 {0, 0x95, "PID_Device_Control_Report"},
230 {0, 0x96, "PID_Device_Control"},
231 {0, 0x97, "DC_Enable_Actuators"},
232 {0, 0x98, "DC_Disable_Actuators"},
233 {0, 0x99, "DC_Stop_All_Effects"},
234 {0, 0x9A, "DC_Device_Reset"},
235 {0, 0x9B, "DC_Device_Pause"},
236 {0, 0x9C, "DC_Device_Continue"},
237 {0, 0x9F, "Device_Paused"},
238 {0, 0xA0, "Actuators_Enabled"},
239 {0, 0xA4, "Safety_Switch"},
240 {0, 0xA5, "Actuator_Override_Switch"},
241 {0, 0xA6, "Actuator_Power"},
242 {0, 0xA7, "Start_Delay"},
243 {0, 0xA8, "Parameter_Block_Size"},
244 {0, 0xA9, "Device_Managed_Pool"},
245 {0, 0xAA, "Shared_Parameter_Blocks"},
246 {0, 0xAB, "Create_New_Effect_Report"},
247 {0, 0xAC, "RAM_Pool_Available"},
248 { 0x84, 0, "Power Device" },
249 { 0x84, 0x02, "PresentStatus" },
250 { 0x84, 0x03, "ChangeStatus" },
251 { 0x84, 0x04, "UPS" },
252 { 0x84, 0x05, "PowerSupply" },
253 { 0x84, 0x10, "BatterySystem" },
254 { 0x84, 0x11, "BatterySystemID" },
255 { 0x84, 0x12, "Battery" },
256 { 0x84, 0x13, "BatteryID" },
257 { 0x84, 0x14, "Charger" },
258 { 0x84, 0x15, "ChargerID" },
259 { 0x84, 0x16, "PowerConverter" },
260 { 0x84, 0x17, "PowerConverterID" },
261 { 0x84, 0x18, "OutletSystem" },
262 { 0x84, 0x19, "OutletSystemID" },
263 { 0x84, 0x1a, "Input" },
264 { 0x84, 0x1b, "InputID" },
265 { 0x84, 0x1c, "Output" },
266 { 0x84, 0x1d, "OutputID" },
267 { 0x84, 0x1e, "Flow" },
268 { 0x84, 0x1f, "FlowID" },
269 { 0x84, 0x20, "Outlet" },
270 { 0x84, 0x21, "OutletID" },
271 { 0x84, 0x22, "Gang" },
272 { 0x84, 0x24, "PowerSummary" },
273 { 0x84, 0x25, "PowerSummaryID" },
274 { 0x84, 0x30, "Voltage" },
275 { 0x84, 0x31, "Current" },
276 { 0x84, 0x32, "Frequency" },
277 { 0x84, 0x33, "ApparentPower" },
278 { 0x84, 0x35, "PercentLoad" },
279 { 0x84, 0x40, "ConfigVoltage" },
280 { 0x84, 0x41, "ConfigCurrent" },
281 { 0x84, 0x43, "ConfigApparentPower" },
282 { 0x84, 0x53, "LowVoltageTransfer" },
283 { 0x84, 0x54, "HighVoltageTransfer" },
284 { 0x84, 0x56, "DelayBeforeStartup" },
285 { 0x84, 0x57, "DelayBeforeShutdown" },
286 { 0x84, 0x58, "Test" },
287 { 0x84, 0x5a, "AudibleAlarmControl" },
288 { 0x84, 0x60, "Present" },
289 { 0x84, 0x61, "Good" },
290 { 0x84, 0x62, "InternalFailure" },
291 { 0x84, 0x65, "Overload" },
292 { 0x84, 0x66, "OverCharged" },
293 { 0x84, 0x67, "OverTemperature" },
294 { 0x84, 0x68, "ShutdownRequested" },
295 { 0x84, 0x69, "ShutdownImminent" },
296 { 0x84, 0x6b, "SwitchOn/Off" },
297 { 0x84, 0x6c, "Switchable" },
298 { 0x84, 0x6d, "Used" },
299 { 0x84, 0x6e, "Boost" },
300 { 0x84, 0x73, "CommunicationLost" },
301 { 0x84, 0xfd, "iManufacturer" },
302 { 0x84, 0xfe, "iProduct" },
303 { 0x84, 0xff, "iSerialNumber" },
304 { 0x85, 0, "Battery System" },
305 { 0x85, 0x01, "SMBBatteryMode" },
306 { 0x85, 0x02, "SMBBatteryStatus" },
307 { 0x85, 0x03, "SMBAlarmWarning" },
308 { 0x85, 0x04, "SMBChargerMode" },
309 { 0x85, 0x05, "SMBChargerStatus" },
310 { 0x85, 0x06, "SMBChargerSpecInfo" },
311 { 0x85, 0x07, "SMBSelectorState" },
312 { 0x85, 0x08, "SMBSelectorPresets" },
313 { 0x85, 0x09, "SMBSelectorInfo" },
314 { 0x85, 0x29, "RemainingCapacityLimit" },
315 { 0x85, 0x2c, "CapacityMode" },
316 { 0x85, 0x42, "BelowRemainingCapacityLimit" },
317 { 0x85, 0x44, "Charging" },
318 { 0x85, 0x45, "Discharging" },
319 { 0x85, 0x4b, "NeedReplacement" },
320 { 0x85, 0x66, "RemainingCapacity" },
321 { 0x85, 0x68, "RunTimeToEmpty" },
322 { 0x85, 0x6a, "AverageTimeToFull" },
323 { 0x85, 0x83, "DesignCapacity" },
324 { 0x85, 0x85, "ManufacturerDate" },
325 { 0x85, 0x89, "iDeviceChemistry" },
326 { 0x85, 0x8b, "Rechargable" },
327 { 0x85, 0x8f, "iOEMInformation" },
328 { 0x85, 0x8d, "CapacityGranularity1" },
329 { 0x85, 0xd0, "ACPresent" },
330 /* pages 0xff00 to 0xffff are vendor-specific */
331 { 0xffff, 0, "Vendor-specific-FF" },
332 { 0, 0, NULL }
333};
334
335static void resolv_usage_page(unsigned page) {
336 const struct hid_usage_entry *p;
337
338 for (p = hid_usage_table; p->description; p++)
339 if (p->page == page) {
340 printk("%s", p->description);
341 return;
342 }
343 printk("%04x", page);
344}
345
346void hid_resolv_usage(unsigned usage) {
347 const struct hid_usage_entry *p;
348
349 resolv_usage_page(usage >> 16);
350 printk(".");
351 for (p = hid_usage_table; p->description; p++)
352 if (p->page == (usage >> 16)) {
353 for(++p; p->description && p->usage != 0; p++)
354 if (p->usage == (usage & 0xffff)) {
355 printk("%s", p->description);
356 return;
357 }
358 break;
359 }
360 printk("%04x", usage & 0xffff);
361}
362EXPORT_SYMBOL_GPL(hid_resolv_usage);
363
364__inline__ static void tab(int n) {
365 while (n--) printk(" ");
366}
367
368void hid_dump_field(struct hid_field *field, int n) {
369 int j;
370
371 if (field->physical) {
372 tab(n);
373 printk("Physical(");
374 hid_resolv_usage(field->physical); printk(")\n");
375 }
376 if (field->logical) {
377 tab(n);
378 printk("Logical(");
379 hid_resolv_usage(field->logical); printk(")\n");
380 }
381 tab(n); printk("Usage(%d)\n", field->maxusage);
382 for (j = 0; j < field->maxusage; j++) {
383 tab(n+2); hid_resolv_usage(field->usage[j].hid); printk("\n");
384 }
385 if (field->logical_minimum != field->logical_maximum) {
386 tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum);
387 tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum);
388 }
389 if (field->physical_minimum != field->physical_maximum) {
390 tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum);
391 tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum);
392 }
393 if (field->unit_exponent) {
394 tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
395 }
396 if (field->unit) {
397 char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
398 char *units[5][8] = {
399 { "None", "None", "None", "None", "None", "None", "None", "None" },
400 { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
401 { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
402 { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
403 { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
404 };
405
406 int i;
407 int sys;
408 __u32 data = field->unit;
409
410 /* First nibble tells us which system we're in. */
411 sys = data & 0xf;
412 data >>= 4;
413
414 if(sys > 4) {
415 tab(n); printk("Unit(Invalid)\n");
416 }
417 else {
418 int earlier_unit = 0;
419
420 tab(n); printk("Unit(%s : ", systems[sys]);
421
422 for (i=1 ; i<sizeof(__u32)*2 ; i++) {
423 char nibble = data & 0xf;
424 data >>= 4;
425 if (nibble != 0) {
426 if(earlier_unit++ > 0)
427 printk("*");
428 printk("%s", units[sys][i]);
429 if(nibble != 1) {
430 /* This is a _signed_ nibble(!) */
431
432 int val = nibble & 0x7;
433 if(nibble & 0x08)
434 val = -((0x7 & ~val) +1);
435 printk("^%d", val);
436 }
437 }
438 }
439 printk(")\n");
440 }
441 }
442 tab(n); printk("Report Size(%u)\n", field->report_size);
443 tab(n); printk("Report Count(%u)\n", field->report_count);
444 tab(n); printk("Report Offset(%u)\n", field->report_offset);
445
446 tab(n); printk("Flags( ");
447 j = field->flags;
448 printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
449 printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
450 printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
451 printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
452 printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
453 printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPrefferedState " : "");
454 printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
455 printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
456 printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
457 printk(")\n");
458}
459EXPORT_SYMBOL_GPL(hid_dump_field);
460
461void hid_dump_device(struct hid_device *device) {
462 struct hid_report_enum *report_enum;
463 struct hid_report *report;
464 struct list_head *list;
465 unsigned i,k;
466 static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
467
468 for (i = 0; i < HID_REPORT_TYPES; i++) {
469 report_enum = device->report_enum + i;
470 list = report_enum->report_list.next;
471 while (list != &report_enum->report_list) {
472 report = (struct hid_report *) list;
473 tab(2);
474 printk("%s", table[i]);
475 if (report->id)
476 printk("(%d)", report->id);
477 printk("[%s]", table[report->type]);
478 printk("\n");
479 for (k = 0; k < report->maxfield; k++) {
480 tab(4);
481 printk("Field(%d)\n", k);
482 hid_dump_field(report->field[k], 6);
483 }
484 list = list->next;
485 }
486 }
487}
488EXPORT_SYMBOL_GPL(hid_dump_device);
489
490void hid_dump_input(struct hid_usage *usage, __s32 value) {
491 printk("hid-debug: input ");
492 hid_resolv_usage(usage->hid);
493 printk(" = %d\n", value);
494}
495EXPORT_SYMBOL_GPL(hid_dump_input);
496
497static char *events[EV_MAX + 1] = {
498 [EV_SYN] = "Sync", [EV_KEY] = "Key",
499 [EV_REL] = "Relative", [EV_ABS] = "Absolute",
500 [EV_MSC] = "Misc", [EV_LED] = "LED",
501 [EV_SND] = "Sound", [EV_REP] = "Repeat",
502 [EV_FF] = "ForceFeedback", [EV_PWR] = "Power",
503 [EV_FF_STATUS] = "ForceFeedbackStatus",
504};
505
506static char *syncs[2] = {
507 [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config",
508};
509static char *keys[KEY_MAX + 1] = {
510 [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
511 [KEY_1] = "1", [KEY_2] = "2",
512 [KEY_3] = "3", [KEY_4] = "4",
513 [KEY_5] = "5", [KEY_6] = "6",
514 [KEY_7] = "7", [KEY_8] = "8",
515 [KEY_9] = "9", [KEY_0] = "0",
516 [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal",
517 [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab",
518 [KEY_Q] = "Q", [KEY_W] = "W",
519 [KEY_E] = "E", [KEY_R] = "R",
520 [KEY_T] = "T", [KEY_Y] = "Y",
521 [KEY_U] = "U", [KEY_I] = "I",
522 [KEY_O] = "O", [KEY_P] = "P",
523 [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace",
524 [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl",
525 [KEY_A] = "A", [KEY_S] = "S",
526 [KEY_D] = "D", [KEY_F] = "F",
527 [KEY_G] = "G", [KEY_H] = "H",
528 [KEY_J] = "J", [KEY_K] = "K",
529 [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon",
530 [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave",
531 [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash",
532 [KEY_Z] = "Z", [KEY_X] = "X",
533 [KEY_C] = "C", [KEY_V] = "V",
534 [KEY_B] = "B", [KEY_N] = "N",
535 [KEY_M] = "M", [KEY_COMMA] = "Comma",
536 [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash",
537 [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk",
538 [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space",
539 [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1",
540 [KEY_F2] = "F2", [KEY_F3] = "F3",
541 [KEY_F4] = "F4", [KEY_F5] = "F5",
542 [KEY_F6] = "F6", [KEY_F7] = "F7",
543 [KEY_F8] = "F8", [KEY_F9] = "F9",
544 [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock",
545 [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7",
546 [KEY_KP8] = "KP8", [KEY_KP9] = "KP9",
547 [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4",
548 [KEY_KP5] = "KP5", [KEY_KP6] = "KP6",
549 [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1",
550 [KEY_KP2] = "KP2", [KEY_KP3] = "KP3",
551 [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot",
552 [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
553 [KEY_F11] = "F11", [KEY_F12] = "F12",
554 [KEY_RO] = "RO", [KEY_KATAKANA] = "Katakana",
555 [KEY_HIRAGANA] = "HIRAGANA", [KEY_HENKAN] = "Henkan",
556 [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
557 [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter",
558 [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash",
559 [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt",
560 [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home",
561 [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp",
562 [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right",
563 [KEY_END] = "End", [KEY_DOWN] = "Down",
564 [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert",
565 [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro",
566 [KEY_MUTE] = "Mute", [KEY_VOLUMEDOWN] = "VolumeDown",
567 [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power",
568 [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus",
569 [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma",
570 [KEY_HANGUEL] = "Hangeul", [KEY_HANJA] = "Hanja",
571 [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta",
572 [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose",
573 [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again",
574 [KEY_PROPS] = "Props", [KEY_UNDO] = "Undo",
575 [KEY_FRONT] = "Front", [KEY_COPY] = "Copy",
576 [KEY_OPEN] = "Open", [KEY_PASTE] = "Paste",
577 [KEY_FIND] = "Find", [KEY_CUT] = "Cut",
578 [KEY_HELP] = "Help", [KEY_MENU] = "Menu",
579 [KEY_CALC] = "Calc", [KEY_SETUP] = "Setup",
580 [KEY_SLEEP] = "Sleep", [KEY_WAKEUP] = "WakeUp",
581 [KEY_FILE] = "File", [KEY_SENDFILE] = "SendFile",
582 [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer",
583 [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2",
584 [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS",
585 [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction",
586 [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail",
587 [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer",
588 [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward",
589 [KEY_CLOSECD] = "CloseCD", [KEY_EJECTCD] = "EjectCD",
590 [KEY_EJECTCLOSECD] = "EjectCloseCD", [KEY_NEXTSONG] = "NextSong",
591 [KEY_PLAYPAUSE] = "PlayPause", [KEY_PREVIOUSSONG] = "PreviousSong",
592 [KEY_STOPCD] = "StopCD", [KEY_RECORD] = "Record",
593 [KEY_REWIND] = "Rewind", [KEY_PHONE] = "Phone",
594 [KEY_ISO] = "ISOKey", [KEY_CONFIG] = "Config",
595 [KEY_HOMEPAGE] = "HomePage", [KEY_REFRESH] = "Refresh",
596 [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move",
597 [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp",
598 [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis",
599 [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New",
600 [KEY_REDO] = "Redo", [KEY_F13] = "F13",
601 [KEY_F14] = "F14", [KEY_F15] = "F15",
602 [KEY_F16] = "F16", [KEY_F17] = "F17",
603 [KEY_F18] = "F18", [KEY_F19] = "F19",
604 [KEY_F20] = "F20", [KEY_F21] = "F21",
605 [KEY_F22] = "F22", [KEY_F23] = "F23",
606 [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD",
607 [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3",
608 [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend",
609 [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play",
610 [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost",
611 [KEY_PRINT] = "Print", [KEY_HP] = "HP",
612 [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound",
613 [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email",
614 [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search",
615 [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance",
616 [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop",
617 [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel",
618 [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp",
619 [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown",
620 [BTN_0] = "Btn0", [BTN_1] = "Btn1",
621 [BTN_2] = "Btn2", [BTN_3] = "Btn3",
622 [BTN_4] = "Btn4", [BTN_5] = "Btn5",
623 [BTN_6] = "Btn6", [BTN_7] = "Btn7",
624 [BTN_8] = "Btn8", [BTN_9] = "Btn9",
625 [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn",
626 [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn",
627 [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn",
628 [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn",
629 [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn",
630 [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn",
631 [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn",
632 [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2",
633 [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4",
634 [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6",
635 [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA",
636 [BTN_B] = "BtnB", [BTN_C] = "BtnC",
637 [BTN_X] = "BtnX", [BTN_Y] = "BtnY",
638 [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL",
639 [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2",
640 [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect",
641 [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode",
642 [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR",
643 [BTN_TOOL_PEN] = "ToolPen", [BTN_TOOL_RUBBER] = "ToolRubber",
644 [BTN_TOOL_BRUSH] = "ToolBrush", [BTN_TOOL_PENCIL] = "ToolPencil",
645 [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger",
646 [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens",
647 [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus",
648 [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
649 [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn",
650 [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok",
651 [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
652 [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
653 [KEY_OPTION] = "Option", [KEY_INFO] = "Info",
654 [KEY_TIME] = "Time", [KEY_VENDOR] = "Vendor",
655 [KEY_ARCHIVE] = "Archive", [KEY_PROGRAM] = "Program",
656 [KEY_CHANNEL] = "Channel", [KEY_FAVORITES] = "Favorites",
657 [KEY_EPG] = "EPG", [KEY_PVR] = "PVR",
658 [KEY_MHP] = "MHP", [KEY_LANGUAGE] = "Language",
659 [KEY_TITLE] = "Title", [KEY_SUBTITLE] = "Subtitle",
660 [KEY_ANGLE] = "Angle", [KEY_ZOOM] = "Zoom",
661 [KEY_MODE] = "Mode", [KEY_KEYBOARD] = "Keyboard",
662 [KEY_SCREEN] = "Screen", [KEY_PC] = "PC",
663 [KEY_TV] = "TV", [KEY_TV2] = "TV2",
664 [KEY_VCR] = "VCR", [KEY_VCR2] = "VCR2",
665 [KEY_SAT] = "Sat", [KEY_SAT2] = "Sat2",
666 [KEY_CD] = "CD", [KEY_TAPE] = "Tape",
667 [KEY_RADIO] = "Radio", [KEY_TUNER] = "Tuner",
668 [KEY_PLAYER] = "Player", [KEY_TEXT] = "Text",
669 [KEY_DVD] = "DVD", [KEY_AUX] = "Aux",
670 [KEY_MP3] = "MP3", [KEY_AUDIO] = "Audio",
671 [KEY_VIDEO] = "Video", [KEY_DIRECTORY] = "Directory",
672 [KEY_LIST] = "List", [KEY_MEMO] = "Memo",
673 [KEY_CALENDAR] = "Calendar", [KEY_RED] = "Red",
674 [KEY_GREEN] = "Green", [KEY_YELLOW] = "Yellow",
675 [KEY_BLUE] = "Blue", [KEY_CHANNELUP] = "ChannelUp",
676 [KEY_CHANNELDOWN] = "ChannelDown", [KEY_FIRST] = "First",
677 [KEY_LAST] = "Last", [KEY_AB] = "AB",
678 [KEY_NEXT] = "Next", [KEY_RESTART] = "Restart",
679 [KEY_SLOW] = "Slow", [KEY_SHUFFLE] = "Shuffle",
680 [KEY_BREAK] = "Break", [KEY_PREVIOUS] = "Previous",
681 [KEY_DIGITS] = "Digits", [KEY_TEEN] = "TEEN",
682 [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL",
683 [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine",
684 [KEY_DEL_LINE] = "DeleteLine",
685 [KEY_SEND] = "Send", [KEY_REPLY] = "Reply",
686 [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save",
687 [KEY_DOCUMENTS] = "Documents",
688 [KEY_FN] = "Fn", [KEY_FN_ESC] = "Fn+ESC",
689 [KEY_FN_1] = "Fn+1", [KEY_FN_2] = "Fn+2",
690 [KEY_FN_B] = "Fn+B", [KEY_FN_D] = "Fn+D",
691 [KEY_FN_E] = "Fn+E", [KEY_FN_F] = "Fn+F",
692 [KEY_FN_S] = "Fn+S",
693 [KEY_FN_F1] = "Fn+F1", [KEY_FN_F2] = "Fn+F2",
694 [KEY_FN_F3] = "Fn+F3", [KEY_FN_F4] = "Fn+F4",
695 [KEY_FN_F5] = "Fn+F5", [KEY_FN_F6] = "Fn+F6",
696 [KEY_FN_F7] = "Fn+F7", [KEY_FN_F8] = "Fn+F8",
697 [KEY_FN_F9] = "Fn+F9", [KEY_FN_F10] = "Fn+F10",
698 [KEY_FN_F11] = "Fn+F11", [KEY_FN_F12] = "Fn+F12",
699 [KEY_KBDILLUMTOGGLE] = "KbdIlluminationToggle",
700 [KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
701 [KEY_KBDILLUMUP] = "KbdIlluminationUp",
702 [KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
703};
704
705static char *relatives[REL_MAX + 1] = {
706 [REL_X] = "X", [REL_Y] = "Y",
707 [REL_Z] = "Z", [REL_RX] = "Rx",
708 [REL_RY] = "Ry", [REL_RZ] = "Rz",
709 [REL_HWHEEL] = "HWheel", [REL_DIAL] = "Dial",
710 [REL_WHEEL] = "Wheel", [REL_MISC] = "Misc",
711};
712
713static char *absolutes[ABS_MAX + 1] = {
714 [ABS_X] = "X", [ABS_Y] = "Y",
715 [ABS_Z] = "Z", [ABS_RX] = "Rx",
716 [ABS_RY] = "Ry", [ABS_RZ] = "Rz",
717 [ABS_THROTTLE] = "Throttle", [ABS_RUDDER] = "Rudder",
718 [ABS_WHEEL] = "Wheel", [ABS_GAS] = "Gas",
719 [ABS_BRAKE] = "Brake", [ABS_HAT0X] = "Hat0X",
720 [ABS_HAT0Y] = "Hat0Y", [ABS_HAT1X] = "Hat1X",
721 [ABS_HAT1Y] = "Hat1Y", [ABS_HAT2X] = "Hat2X",
722 [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X",
723 [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure",
724 [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt",
725 [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "Tool Width",
726 [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc",
727};
728
729static char *misc[MSC_MAX + 1] = {
730 [MSC_SERIAL] = "Serial", [MSC_PULSELED] = "Pulseled",
731 [MSC_GESTURE] = "Gesture", [MSC_RAW] = "RawData"
732};
733
734static char *leds[LED_MAX + 1] = {
735 [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock",
736 [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose",
737 [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep",
738 [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute",
739 [LED_MISC] = "Misc",
740};
741
742static char *repeats[REP_MAX + 1] = {
743 [REP_DELAY] = "Delay", [REP_PERIOD] = "Period"
744};
745
746static char *sounds[SND_MAX + 1] = {
747 [SND_CLICK] = "Click", [SND_BELL] = "Bell",
748 [SND_TONE] = "Tone"
749};
750
751static char **names[EV_MAX + 1] = {
752 [EV_SYN] = syncs, [EV_KEY] = keys,
753 [EV_REL] = relatives, [EV_ABS] = absolutes,
754 [EV_MSC] = misc, [EV_LED] = leds,
755 [EV_SND] = sounds, [EV_REP] = repeats,
756};
757
758void hid_resolv_event(__u8 type, __u16 code) {
759
760 printk("%s.%s", events[type] ? events[type] : "?",
761 names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
762}
763EXPORT_SYMBOL_GPL(hid_resolv_event);
764
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index c7a6833f6821..25d180a24fc4 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -31,9 +31,8 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33 33
34#undef DEBUG
35
36#include <linux/hid.h> 34#include <linux/hid.h>
35#include <linux/hid-debug.h>
37 36
38static int hid_pb_fnmode = 1; 37static int hid_pb_fnmode = 1;
39module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); 38module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644);
@@ -252,9 +251,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
252 251
253 field->hidinput = hidinput; 252 field->hidinput = hidinput;
254 253
255#ifdef DEBUG 254#ifdef CONFIG_HID_DEBUG
256 printk(KERN_DEBUG "Mapping: "); 255 printk(KERN_DEBUG "Mapping: ");
257 resolv_usage(usage->hid); 256 hid_resolv_usage(usage->hid);
258 printk(" ---> "); 257 printk(" ---> ");
259#endif 258#endif
260 259
@@ -682,14 +681,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
682 field->dpad = usage->code; 681 field->dpad = usage->code;
683 } 682 }
684 683
685#ifdef DEBUG 684 hid_resolv_event(usage->type, usage->code);
686 resolv_event(usage->type, usage->code); 685#ifdef CONFIG_HID_DEBUG
687 printk("\n"); 686 printk("\n");
688#endif 687#endif
689 return; 688 return;
690 689
691ignore: 690ignore:
692#ifdef DEBUG 691#ifdef CONFIG_HID_DEBUG
693 printk("IGNORED\n"); 692 printk("IGNORED\n");
694#endif 693#endif
695 return; 694 return;
@@ -804,6 +803,18 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
804} 803}
805EXPORT_SYMBOL_GPL(hidinput_find_field); 804EXPORT_SYMBOL_GPL(hidinput_find_field);
806 805
806static int hidinput_open(struct input_dev *dev)
807{
808 struct hid_device *hid = dev->private;
809 return hid->hid_open(hid);
810}
811
812static void hidinput_close(struct input_dev *dev)
813{
814 struct hid_device *hid = dev->private;
815 hid->hid_close(hid);
816}
817
807/* 818/*
808 * Register the input device; print a message. 819 * Register the input device; print a message.
809 * Configure the input layer interface 820 * Configure the input layer interface
@@ -816,6 +827,7 @@ int hidinput_connect(struct hid_device *hid)
816 struct hid_input *hidinput = NULL; 827 struct hid_input *hidinput = NULL;
817 struct input_dev *input_dev; 828 struct input_dev *input_dev;
818 int i, j, k; 829 int i, j, k;
830 int max_report_type = HID_OUTPUT_REPORT;
819 831
820 INIT_LIST_HEAD(&hid->inputs); 832 INIT_LIST_HEAD(&hid->inputs);
821 833
@@ -828,7 +840,10 @@ int hidinput_connect(struct hid_device *hid)
828 if (i == hid->maxcollection) 840 if (i == hid->maxcollection)
829 return -1; 841 return -1;
830 842
831 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) 843 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
844 max_report_type = HID_INPUT_REPORT;
845
846 for (k = HID_INPUT_REPORT; k <= max_report_type; k++)
832 list_for_each_entry(report, &hid->report_enum[k].report_list, list) { 847 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
833 848
834 if (!report->maxfield) 849 if (!report->maxfield)
@@ -846,8 +861,8 @@ int hidinput_connect(struct hid_device *hid)
846 861
847 input_dev->private = hid; 862 input_dev->private = hid;
848 input_dev->event = hid->hidinput_input_event; 863 input_dev->event = hid->hidinput_input_event;
849 input_dev->open = hid->hidinput_open; 864 input_dev->open = hidinput_open;
850 input_dev->close = hid->hidinput_close; 865 input_dev->close = hidinput_close;
851 866
852 input_dev->name = hid->name; 867 input_dev->name = hid->name;
853 input_dev->phys = hid->phys; 868 input_dev->phys = hid->phys;
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index af939796750d..d2bb5a9a303f 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -360,8 +360,7 @@ static int netevent_callback(struct notifier_block *self, unsigned long event,
360 if (event == NETEVENT_NEIGH_UPDATE) { 360 if (event == NETEVENT_NEIGH_UPDATE) {
361 struct neighbour *neigh = ctx; 361 struct neighbour *neigh = ctx;
362 362
363 if (neigh->dev->type == ARPHRD_INFINIBAND && 363 if (neigh->nud_state & NUD_VALID) {
364 (neigh->nud_state & NUD_VALID)) {
365 set_timeout(jiffies); 364 set_timeout(jiffies);
366 } 365 }
367 } 366 }
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 5ed141ebd1c8..13efd4170349 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -642,7 +642,8 @@ static void snoop_recv(struct ib_mad_qp_info *qp_info,
642 spin_unlock_irqrestore(&qp_info->snoop_lock, flags); 642 spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
643} 643}
644 644
645static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num, 645static void build_smp_wc(struct ib_qp *qp,
646 u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
646 struct ib_wc *wc) 647 struct ib_wc *wc)
647{ 648{
648 memset(wc, 0, sizeof *wc); 649 memset(wc, 0, sizeof *wc);
@@ -652,7 +653,7 @@ static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
652 wc->pkey_index = pkey_index; 653 wc->pkey_index = pkey_index;
653 wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh); 654 wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh);
654 wc->src_qp = IB_QP0; 655 wc->src_qp = IB_QP0;
655 wc->qp_num = IB_QP0; 656 wc->qp = qp;
656 wc->slid = slid; 657 wc->slid = slid;
657 wc->sl = 0; 658 wc->sl = 0;
658 wc->dlid_path_bits = 0; 659 wc->dlid_path_bits = 0;
@@ -713,7 +714,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
713 goto out; 714 goto out;
714 } 715 }
715 716
716 build_smp_wc(send_wr->wr_id, be16_to_cpu(smp->dr_slid), 717 build_smp_wc(mad_agent_priv->agent.qp,
718 send_wr->wr_id, be16_to_cpu(smp->dr_slid),
717 send_wr->wr.ud.pkey_index, 719 send_wr->wr.ud.pkey_index,
718 send_wr->wr.ud.port_num, &mad_wc); 720 send_wr->wr.ud.port_num, &mad_wc);
719 721
@@ -2355,7 +2357,8 @@ static void local_completions(struct work_struct *work)
2355 * Defined behavior is to complete response 2357 * Defined behavior is to complete response
2356 * before request 2358 * before request
2357 */ 2359 */
2358 build_smp_wc((unsigned long) local->mad_send_wr, 2360 build_smp_wc(recv_mad_agent->agent.qp,
2361 (unsigned long) local->mad_send_wr,
2359 be16_to_cpu(IB_LID_PERMISSIVE), 2362 be16_to_cpu(IB_LID_PERMISSIVE),
2360 0, recv_mad_agent->agent.port_num, &wc); 2363 0, recv_mad_agent->agent.port_num, &wc);
2361 2364
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 743247ec065e..df1efbc10882 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -933,7 +933,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
933 resp->wc[i].vendor_err = wc[i].vendor_err; 933 resp->wc[i].vendor_err = wc[i].vendor_err;
934 resp->wc[i].byte_len = wc[i].byte_len; 934 resp->wc[i].byte_len = wc[i].byte_len;
935 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data; 935 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data;
936 resp->wc[i].qp_num = wc[i].qp_num; 936 resp->wc[i].qp_num = wc[i].qp->qp_num;
937 resp->wc[i].src_qp = wc[i].src_qp; 937 resp->wc[i].src_qp = wc[i].src_qp;
938 resp->wc[i].wc_flags = wc[i].wc_flags; 938 resp->wc[i].wc_flags = wc[i].wc_flags;
939 resp->wc[i].pkey_index = wc[i].pkey_index; 939 resp->wc[i].pkey_index = wc[i].pkey_index;
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c
index 05c9154d46f4..5175c99ee586 100644
--- a/drivers/infiniband/hw/amso1100/c2_cq.c
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -153,7 +153,7 @@ static inline int c2_poll_one(struct c2_dev *c2dev,
153 153
154 entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce)); 154 entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce));
155 entry->wr_id = ce->hdr.context; 155 entry->wr_id = ce->hdr.context;
156 entry->qp_num = ce->handle; 156 entry->qp = &qp->ibqp;
157 entry->wc_flags = 0; 157 entry->wc_flags = 0;
158 entry->slid = 0; 158 entry->slid = 0;
159 entry->sl = 0; 159 entry->sl = 0;
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 1c722032319c..cf95ee474b0f 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -119,13 +119,14 @@ struct ehca_qp {
119 struct ipz_qp_handle ipz_qp_handle; 119 struct ipz_qp_handle ipz_qp_handle;
120 struct ehca_pfqp pf; 120 struct ehca_pfqp pf;
121 struct ib_qp_init_attr init_attr; 121 struct ib_qp_init_attr init_attr;
122 u64 uspace_squeue;
123 u64 uspace_rqueue;
124 u64 uspace_fwh;
125 struct ehca_cq *send_cq; 122 struct ehca_cq *send_cq;
126 struct ehca_cq *recv_cq; 123 struct ehca_cq *recv_cq;
127 unsigned int sqerr_purgeflag; 124 unsigned int sqerr_purgeflag;
128 struct hlist_node list_entries; 125 struct hlist_node list_entries;
126 /* mmap counter for resources mapped into user space */
127 u32 mm_count_squeue;
128 u32 mm_count_rqueue;
129 u32 mm_count_galpa;
129}; 130};
130 131
131/* must be power of 2 */ 132/* must be power of 2 */
@@ -142,13 +143,14 @@ struct ehca_cq {
142 struct ipz_cq_handle ipz_cq_handle; 143 struct ipz_cq_handle ipz_cq_handle;
143 struct ehca_pfcq pf; 144 struct ehca_pfcq pf;
144 spinlock_t cb_lock; 145 spinlock_t cb_lock;
145 u64 uspace_queue;
146 u64 uspace_fwh;
147 struct hlist_head qp_hashtab[QP_HASHTAB_LEN]; 146 struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
148 struct list_head entry; 147 struct list_head entry;
149 u32 nr_callbacks; 148 u32 nr_callbacks;
150 spinlock_t task_lock; 149 spinlock_t task_lock;
151 u32 ownpid; 150 u32 ownpid;
151 /* mmap counter for resources mapped into user space */
152 u32 mm_count_queue;
153 u32 mm_count_galpa;
152}; 154};
153 155
154enum ehca_mr_flag { 156enum ehca_mr_flag {
@@ -248,20 +250,6 @@ struct ehca_ucontext {
248 struct ib_ucontext ib_ucontext; 250 struct ib_ucontext ib_ucontext;
249}; 251};
250 252
251struct ehca_module *ehca_module_new(void);
252
253int ehca_module_delete(struct ehca_module *me);
254
255int ehca_eq_ctor(struct ehca_eq *eq);
256
257int ehca_eq_dtor(struct ehca_eq *eq);
258
259struct ehca_shca *ehca_shca_new(void);
260
261int ehca_shca_delete(struct ehca_shca *me);
262
263struct ehca_sport *ehca_sport_new(struct ehca_shca *anchor);
264
265int ehca_init_pd_cache(void); 253int ehca_init_pd_cache(void);
266void ehca_cleanup_pd_cache(void); 254void ehca_cleanup_pd_cache(void);
267int ehca_init_cq_cache(void); 255int ehca_init_cq_cache(void);
@@ -283,7 +271,6 @@ extern int ehca_port_act_time;
283extern int ehca_use_hp_mr; 271extern int ehca_use_hp_mr;
284 272
285struct ipzu_queue_resp { 273struct ipzu_queue_resp {
286 u64 queue; /* points to first queue entry */
287 u32 qe_size; /* queue entry size */ 274 u32 qe_size; /* queue entry size */
288 u32 act_nr_of_sg; 275 u32 act_nr_of_sg;
289 u32 queue_length; /* queue length allocated in bytes */ 276 u32 queue_length; /* queue length allocated in bytes */
@@ -296,7 +283,6 @@ struct ehca_create_cq_resp {
296 u32 cq_number; 283 u32 cq_number;
297 u32 token; 284 u32 token;
298 struct ipzu_queue_resp ipz_queue; 285 struct ipzu_queue_resp ipz_queue;
299 struct h_galpas galpas;
300}; 286};
301 287
302struct ehca_create_qp_resp { 288struct ehca_create_qp_resp {
@@ -309,7 +295,6 @@ struct ehca_create_qp_resp {
309 u32 dummy; /* padding for 8 byte alignment */ 295 u32 dummy; /* padding for 8 byte alignment */
310 struct ipzu_queue_resp ipz_squeue; 296 struct ipzu_queue_resp ipz_squeue;
311 struct ipzu_queue_resp ipz_rqueue; 297 struct ipzu_queue_resp ipz_rqueue;
312 struct h_galpas galpas;
313}; 298};
314 299
315struct ehca_alloc_cq_parms { 300struct ehca_alloc_cq_parms {
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 6074c897f51c..9291a86ca053 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -267,7 +267,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
267 if (context) { 267 if (context) {
268 struct ipz_queue *ipz_queue = &my_cq->ipz_queue; 268 struct ipz_queue *ipz_queue = &my_cq->ipz_queue;
269 struct ehca_create_cq_resp resp; 269 struct ehca_create_cq_resp resp;
270 struct vm_area_struct *vma;
271 memset(&resp, 0, sizeof(resp)); 270 memset(&resp, 0, sizeof(resp));
272 resp.cq_number = my_cq->cq_number; 271 resp.cq_number = my_cq->cq_number;
273 resp.token = my_cq->token; 272 resp.token = my_cq->token;
@@ -276,40 +275,14 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
276 resp.ipz_queue.queue_length = ipz_queue->queue_length; 275 resp.ipz_queue.queue_length = ipz_queue->queue_length;
277 resp.ipz_queue.pagesize = ipz_queue->pagesize; 276 resp.ipz_queue.pagesize = ipz_queue->pagesize;
278 resp.ipz_queue.toggle_state = ipz_queue->toggle_state; 277 resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
279 ret = ehca_mmap_nopage(((u64)(my_cq->token) << 32) | 0x12000000,
280 ipz_queue->queue_length,
281 (void**)&resp.ipz_queue.queue,
282 &vma);
283 if (ret) {
284 ehca_err(device, "Could not mmap queue pages");
285 cq = ERR_PTR(ret);
286 goto create_cq_exit4;
287 }
288 my_cq->uspace_queue = resp.ipz_queue.queue;
289 resp.galpas = my_cq->galpas;
290 ret = ehca_mmap_register(my_cq->galpas.user.fw_handle,
291 (void**)&resp.galpas.kernel.fw_handle,
292 &vma);
293 if (ret) {
294 ehca_err(device, "Could not mmap fw_handle");
295 cq = ERR_PTR(ret);
296 goto create_cq_exit5;
297 }
298 my_cq->uspace_fwh = (u64)resp.galpas.kernel.fw_handle;
299 if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { 278 if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
300 ehca_err(device, "Copy to udata failed."); 279 ehca_err(device, "Copy to udata failed.");
301 goto create_cq_exit6; 280 goto create_cq_exit4;
302 } 281 }
303 } 282 }
304 283
305 return cq; 284 return cq;
306 285
307create_cq_exit6:
308 ehca_munmap(my_cq->uspace_fwh, EHCA_PAGESIZE);
309
310create_cq_exit5:
311 ehca_munmap(my_cq->uspace_queue, my_cq->ipz_queue.queue_length);
312
313create_cq_exit4: 286create_cq_exit4:
314 ipz_queue_dtor(&my_cq->ipz_queue); 287 ipz_queue_dtor(&my_cq->ipz_queue);
315 288
@@ -333,7 +306,6 @@ create_cq_exit1:
333int ehca_destroy_cq(struct ib_cq *cq) 306int ehca_destroy_cq(struct ib_cq *cq)
334{ 307{
335 u64 h_ret; 308 u64 h_ret;
336 int ret;
337 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); 309 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
338 int cq_num = my_cq->cq_number; 310 int cq_num = my_cq->cq_number;
339 struct ib_device *device = cq->device; 311 struct ib_device *device = cq->device;
@@ -343,6 +315,20 @@ int ehca_destroy_cq(struct ib_cq *cq)
343 u32 cur_pid = current->tgid; 315 u32 cur_pid = current->tgid;
344 unsigned long flags; 316 unsigned long flags;
345 317
318 if (cq->uobject) {
319 if (my_cq->mm_count_galpa || my_cq->mm_count_queue) {
320 ehca_err(device, "Resources still referenced in "
321 "user space cq_num=%x", my_cq->cq_number);
322 return -EINVAL;
323 }
324 if (my_cq->ownpid != cur_pid) {
325 ehca_err(device, "Invalid caller pid=%x ownpid=%x "
326 "cq_num=%x",
327 cur_pid, my_cq->ownpid, my_cq->cq_number);
328 return -EINVAL;
329 }
330 }
331
346 spin_lock_irqsave(&ehca_cq_idr_lock, flags); 332 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
347 while (my_cq->nr_callbacks) { 333 while (my_cq->nr_callbacks) {
348 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 334 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
@@ -353,25 +339,6 @@ int ehca_destroy_cq(struct ib_cq *cq)
353 idr_remove(&ehca_cq_idr, my_cq->token); 339 idr_remove(&ehca_cq_idr, my_cq->token);
354 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 340 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
355 341
356 if (my_cq->uspace_queue && my_cq->ownpid != cur_pid) {
357 ehca_err(device, "Invalid caller pid=%x ownpid=%x",
358 cur_pid, my_cq->ownpid);
359 return -EINVAL;
360 }
361
362 /* un-mmap if vma alloc */
363 if (my_cq->uspace_queue ) {
364 ret = ehca_munmap(my_cq->uspace_queue,
365 my_cq->ipz_queue.queue_length);
366 if (ret)
367 ehca_err(device, "Could not munmap queue ehca_cq=%p "
368 "cq_num=%x", my_cq, cq_num);
369 ret = ehca_munmap(my_cq->uspace_fwh, EHCA_PAGESIZE);
370 if (ret)
371 ehca_err(device, "Could not munmap fwh ehca_cq=%p "
372 "cq_num=%x", my_cq, cq_num);
373 }
374
375 h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0); 342 h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
376 if (h_ret == H_R_STATE) { 343 if (h_ret == H_R_STATE) {
377 /* cq in err: read err data and destroy it forcibly */ 344 /* cq in err: read err data and destroy it forcibly */
@@ -400,7 +367,7 @@ int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
400 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); 367 struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
401 u32 cur_pid = current->tgid; 368 u32 cur_pid = current->tgid;
402 369
403 if (my_cq->uspace_queue && my_cq->ownpid != cur_pid) { 370 if (cq->uobject && my_cq->ownpid != cur_pid) {
404 ehca_err(cq->device, "Invalid caller pid=%x ownpid=%x", 371 ehca_err(cq->device, "Invalid caller pid=%x ownpid=%x",
405 cur_pid, my_cq->ownpid); 372 cur_pid, my_cq->ownpid);
406 return -EINVAL; 373 return -EINVAL;
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index cd7789f0d08e..95fd59fb4528 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -171,14 +171,6 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
171 171
172void ehca_poll_eqs(unsigned long data); 172void ehca_poll_eqs(unsigned long data);
173 173
174int ehca_mmap_nopage(u64 foffset,u64 length,void **mapped,
175 struct vm_area_struct **vma);
176
177int ehca_mmap_register(u64 physical,void **mapped,
178 struct vm_area_struct **vma);
179
180int ehca_munmap(unsigned long addr, size_t len);
181
182#ifdef CONFIG_PPC_64K_PAGES 174#ifdef CONFIG_PPC_64K_PAGES
183void *ehca_alloc_fw_ctrlblock(gfp_t flags); 175void *ehca_alloc_fw_ctrlblock(gfp_t flags);
184void ehca_free_fw_ctrlblock(void *ptr); 176void ehca_free_fw_ctrlblock(void *ptr);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 6574fbbaead5..1155bcf48212 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
52MODULE_LICENSE("Dual BSD/GPL"); 52MODULE_LICENSE("Dual BSD/GPL");
53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); 54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
55MODULE_VERSION("SVNEHCA_0019"); 55MODULE_VERSION("SVNEHCA_0020");
56 56
57int ehca_open_aqp1 = 0; 57int ehca_open_aqp1 = 0;
58int ehca_debug_level = 0; 58int ehca_debug_level = 0;
@@ -288,7 +288,7 @@ int ehca_init_device(struct ehca_shca *shca)
288 strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX); 288 strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
289 shca->ib_device.owner = THIS_MODULE; 289 shca->ib_device.owner = THIS_MODULE;
290 290
291 shca->ib_device.uverbs_abi_ver = 5; 291 shca->ib_device.uverbs_abi_ver = 6;
292 shca->ib_device.uverbs_cmd_mask = 292 shca->ib_device.uverbs_cmd_mask =
293 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | 293 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
294 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | 294 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
@@ -790,7 +790,7 @@ int __init ehca_module_init(void)
790 int ret; 790 int ret;
791 791
792 printk(KERN_INFO "eHCA Infiniband Device Driver " 792 printk(KERN_INFO "eHCA Infiniband Device Driver "
793 "(Rel.: SVNEHCA_0019)\n"); 793 "(Rel.: SVNEHCA_0020)\n");
794 idr_init(&ehca_qp_idr); 794 idr_init(&ehca_qp_idr);
795 idr_init(&ehca_cq_idr); 795 idr_init(&ehca_cq_idr);
796 spin_lock_init(&ehca_qp_idr_lock); 796 spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 34b85556d01e..95efef921f1d 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -637,7 +637,6 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
637 struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue; 637 struct ipz_queue *ipz_rqueue = &my_qp->ipz_rqueue;
638 struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue; 638 struct ipz_queue *ipz_squeue = &my_qp->ipz_squeue;
639 struct ehca_create_qp_resp resp; 639 struct ehca_create_qp_resp resp;
640 struct vm_area_struct * vma;
641 memset(&resp, 0, sizeof(resp)); 640 memset(&resp, 0, sizeof(resp));
642 641
643 resp.qp_num = my_qp->real_qp_num; 642 resp.qp_num = my_qp->real_qp_num;
@@ -651,59 +650,21 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
651 resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length; 650 resp.ipz_rqueue.queue_length = ipz_rqueue->queue_length;
652 resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize; 651 resp.ipz_rqueue.pagesize = ipz_rqueue->pagesize;
653 resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state; 652 resp.ipz_rqueue.toggle_state = ipz_rqueue->toggle_state;
654 ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x22000000,
655 ipz_rqueue->queue_length,
656 (void**)&resp.ipz_rqueue.queue,
657 &vma);
658 if (ret) {
659 ehca_err(pd->device, "Could not mmap rqueue pages");
660 goto create_qp_exit3;
661 }
662 my_qp->uspace_rqueue = resp.ipz_rqueue.queue;
663 /* squeue properties */ 653 /* squeue properties */
664 resp.ipz_squeue.qe_size = ipz_squeue->qe_size; 654 resp.ipz_squeue.qe_size = ipz_squeue->qe_size;
665 resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg; 655 resp.ipz_squeue.act_nr_of_sg = ipz_squeue->act_nr_of_sg;
666 resp.ipz_squeue.queue_length = ipz_squeue->queue_length; 656 resp.ipz_squeue.queue_length = ipz_squeue->queue_length;
667 resp.ipz_squeue.pagesize = ipz_squeue->pagesize; 657 resp.ipz_squeue.pagesize = ipz_squeue->pagesize;
668 resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state; 658 resp.ipz_squeue.toggle_state = ipz_squeue->toggle_state;
669 ret = ehca_mmap_nopage(((u64)(my_qp->token) << 32) | 0x23000000,
670 ipz_squeue->queue_length,
671 (void**)&resp.ipz_squeue.queue,
672 &vma);
673 if (ret) {
674 ehca_err(pd->device, "Could not mmap squeue pages");
675 goto create_qp_exit4;
676 }
677 my_qp->uspace_squeue = resp.ipz_squeue.queue;
678 /* fw_handle */
679 resp.galpas = my_qp->galpas;
680 ret = ehca_mmap_register(my_qp->galpas.user.fw_handle,
681 (void**)&resp.galpas.kernel.fw_handle,
682 &vma);
683 if (ret) {
684 ehca_err(pd->device, "Could not mmap fw_handle");
685 goto create_qp_exit5;
686 }
687 my_qp->uspace_fwh = (u64)resp.galpas.kernel.fw_handle;
688
689 if (ib_copy_to_udata(udata, &resp, sizeof resp)) { 659 if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
690 ehca_err(pd->device, "Copy to udata failed"); 660 ehca_err(pd->device, "Copy to udata failed");
691 ret = -EINVAL; 661 ret = -EINVAL;
692 goto create_qp_exit6; 662 goto create_qp_exit3;
693 } 663 }
694 } 664 }
695 665
696 return &my_qp->ib_qp; 666 return &my_qp->ib_qp;
697 667
698create_qp_exit6:
699 ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE);
700
701create_qp_exit5:
702 ehca_munmap(my_qp->uspace_squeue, my_qp->ipz_squeue.queue_length);
703
704create_qp_exit4:
705 ehca_munmap(my_qp->uspace_rqueue, my_qp->ipz_rqueue.queue_length);
706
707create_qp_exit3: 668create_qp_exit3:
708 ipz_queue_dtor(&my_qp->ipz_rqueue); 669 ipz_queue_dtor(&my_qp->ipz_rqueue);
709 ipz_queue_dtor(&my_qp->ipz_squeue); 670 ipz_queue_dtor(&my_qp->ipz_squeue);
@@ -931,7 +892,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
931 my_qp->qp_type == IB_QPT_SMI) && 892 my_qp->qp_type == IB_QPT_SMI) &&
932 statetrans == IB_QPST_SQE2RTS) { 893 statetrans == IB_QPST_SQE2RTS) {
933 /* mark next free wqe if kernel */ 894 /* mark next free wqe if kernel */
934 if (my_qp->uspace_squeue == 0) { 895 if (!ibqp->uobject) {
935 struct ehca_wqe *wqe; 896 struct ehca_wqe *wqe;
936 /* lock send queue */ 897 /* lock send queue */
937 spin_lock_irqsave(&my_qp->spinlock_s, spl_flags); 898 spin_lock_irqsave(&my_qp->spinlock_s, spl_flags);
@@ -1417,11 +1378,18 @@ int ehca_destroy_qp(struct ib_qp *ibqp)
1417 enum ib_qp_type qp_type; 1378 enum ib_qp_type qp_type;
1418 unsigned long flags; 1379 unsigned long flags;
1419 1380
1420 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && 1381 if (ibqp->uobject) {
1421 my_pd->ownpid != cur_pid) { 1382 if (my_qp->mm_count_galpa ||
1422 ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x", 1383 my_qp->mm_count_rqueue || my_qp->mm_count_squeue) {
1423 cur_pid, my_pd->ownpid); 1384 ehca_err(ibqp->device, "Resources still referenced in "
1424 return -EINVAL; 1385 "user space qp_num=%x", ibqp->qp_num);
1386 return -EINVAL;
1387 }
1388 if (my_pd->ownpid != cur_pid) {
1389 ehca_err(ibqp->device, "Invalid caller pid=%x ownpid=%x",
1390 cur_pid, my_pd->ownpid);
1391 return -EINVAL;
1392 }
1425 } 1393 }
1426 1394
1427 if (my_qp->send_cq) { 1395 if (my_qp->send_cq) {
@@ -1439,24 +1407,6 @@ int ehca_destroy_qp(struct ib_qp *ibqp)
1439 idr_remove(&ehca_qp_idr, my_qp->token); 1407 idr_remove(&ehca_qp_idr, my_qp->token);
1440 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags); 1408 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags);
1441 1409
1442 /* un-mmap if vma alloc */
1443 if (my_qp->uspace_rqueue) {
1444 ret = ehca_munmap(my_qp->uspace_rqueue,
1445 my_qp->ipz_rqueue.queue_length);
1446 if (ret)
1447 ehca_err(ibqp->device, "Could not munmap rqueue "
1448 "qp_num=%x", qp_num);
1449 ret = ehca_munmap(my_qp->uspace_squeue,
1450 my_qp->ipz_squeue.queue_length);
1451 if (ret)
1452 ehca_err(ibqp->device, "Could not munmap squeue "
1453 "qp_num=%x", qp_num);
1454 ret = ehca_munmap(my_qp->uspace_fwh, EHCA_PAGESIZE);
1455 if (ret)
1456 ehca_err(ibqp->device, "Could not munmap fwh qp_num=%x",
1457 qp_num);
1458 }
1459
1460 h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); 1410 h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
1461 if (h_ret != H_SUCCESS) { 1411 if (h_ret != H_SUCCESS) {
1462 ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx " 1412 ehca_err(ibqp->device, "hipz_h_destroy_qp() failed rc=%lx "
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index b46bda1bf85d..08d3f892d9f3 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -579,7 +579,7 @@ poll_cq_one_read_cqe:
579 } else 579 } else
580 wc->status = IB_WC_SUCCESS; 580 wc->status = IB_WC_SUCCESS;
581 581
582 wc->qp_num = cqe->local_qp_number; 582 wc->qp = NULL;
583 wc->byte_len = cqe->nr_bytes_transferred; 583 wc->byte_len = cqe->nr_bytes_transferred;
584 wc->pkey_index = cqe->pkey_index; 584 wc->pkey_index = cqe->pkey_index;
585 wc->slid = cqe->rlid; 585 wc->slid = cqe->rlid;
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index e08764e4aef2..73db920b6945 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -68,105 +68,183 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context)
68 return 0; 68 return 0;
69} 69}
70 70
71struct page *ehca_nopage(struct vm_area_struct *vma, 71static void ehca_mm_open(struct vm_area_struct *vma)
72 unsigned long address, int *type)
73{ 72{
74 struct page *mypage = NULL; 73 u32 *count = (u32*)vma->vm_private_data;
75 u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT; 74 if (!count) {
76 u32 idr_handle = fileoffset >> 32; 75 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
77 u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */ 76 vma->vm_start, vma->vm_end);
78 u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */ 77 return;
79 u32 cur_pid = current->tgid; 78 }
80 unsigned long flags; 79 (*count)++;
81 struct ehca_cq *cq; 80 if (!(*count))
82 struct ehca_qp *qp; 81 ehca_gen_err("Use count overflow vm_start=%lx vm_end=%lx",
83 struct ehca_pd *pd; 82 vma->vm_start, vma->vm_end);
84 u64 offset; 83 ehca_gen_dbg("vm_start=%lx vm_end=%lx count=%x",
85 void *vaddr; 84 vma->vm_start, vma->vm_end, *count);
85}
86 86
87 switch (q_type) { 87static void ehca_mm_close(struct vm_area_struct *vma)
88 case 1: /* CQ */ 88{
89 spin_lock_irqsave(&ehca_cq_idr_lock, flags); 89 u32 *count = (u32*)vma->vm_private_data;
90 cq = idr_find(&ehca_cq_idr, idr_handle); 90 if (!count) {
91 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 91 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
92 vma->vm_start, vma->vm_end);
93 return;
94 }
95 (*count)--;
96 ehca_gen_dbg("vm_start=%lx vm_end=%lx count=%x",
97 vma->vm_start, vma->vm_end, *count);
98}
92 99
93 /* make sure this mmap really belongs to the authorized user */ 100static struct vm_operations_struct vm_ops = {
94 if (!cq) { 101 .open = ehca_mm_open,
95 ehca_gen_err("cq is NULL ret=NOPAGE_SIGBUS"); 102 .close = ehca_mm_close,
96 return NOPAGE_SIGBUS; 103};
104
105static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
106 u32 *mm_count)
107{
108 int ret;
109 u64 vsize, physical;
110
111 vsize = vma->vm_end - vma->vm_start;
112 if (vsize != EHCA_PAGESIZE) {
113 ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start);
114 return -EINVAL;
115 }
116
117 physical = galpas->user.fw_handle;
118 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
119 ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical);
120 /* VM_IO | VM_RESERVED are set by remap_pfn_range() */
121 ret = remap_pfn_range(vma, vma->vm_start, physical >> PAGE_SHIFT,
122 vsize, vma->vm_page_prot);
123 if (unlikely(ret)) {
124 ehca_gen_err("remap_pfn_range() failed ret=%x", ret);
125 return -ENOMEM;
126 }
127
128 vma->vm_private_data = mm_count;
129 (*mm_count)++;
130 vma->vm_ops = &vm_ops;
131
132 return 0;
133}
134
135static int ehca_mmap_queue(struct vm_area_struct *vma, struct ipz_queue *queue,
136 u32 *mm_count)
137{
138 int ret;
139 u64 start, ofs;
140 struct page *page;
141
142 vma->vm_flags |= VM_RESERVED;
143 start = vma->vm_start;
144 for (ofs = 0; ofs < queue->queue_length; ofs += PAGE_SIZE) {
145 u64 virt_addr = (u64)ipz_qeit_calc(queue, ofs);
146 page = virt_to_page(virt_addr);
147 ret = vm_insert_page(vma, start, page);
148 if (unlikely(ret)) {
149 ehca_gen_err("vm_insert_page() failed rc=%x", ret);
150 return ret;
97 } 151 }
152 start += PAGE_SIZE;
153 }
154 vma->vm_private_data = mm_count;
155 (*mm_count)++;
156 vma->vm_ops = &vm_ops;
98 157
99 if (cq->ownpid != cur_pid) { 158 return 0;
159}
160
161static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq,
162 u32 rsrc_type)
163{
164 int ret;
165
166 switch (rsrc_type) {
167 case 1: /* galpa fw handle */
168 ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number);
169 ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa);
170 if (unlikely(ret)) {
100 ehca_err(cq->ib_cq.device, 171 ehca_err(cq->ib_cq.device,
101 "Invalid caller pid=%x ownpid=%x", 172 "ehca_mmap_fw() failed rc=%x cq_num=%x",
102 cur_pid, cq->ownpid); 173 ret, cq->cq_number);
103 return NOPAGE_SIGBUS; 174 return ret;
104 } 175 }
176 break;
105 177
106 if (rsrc_type == 2) { 178 case 2: /* cq queue_addr */
107 ehca_dbg(cq->ib_cq.device, "cq=%p cq queuearea", cq); 179 ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number);
108 offset = address - vma->vm_start; 180 ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue);
109 vaddr = ipz_qeit_calc(&cq->ipz_queue, offset); 181 if (unlikely(ret)) {
110 ehca_dbg(cq->ib_cq.device, "offset=%lx vaddr=%p", 182 ehca_err(cq->ib_cq.device,
111 offset, vaddr); 183 "ehca_mmap_queue() failed rc=%x cq_num=%x",
112 mypage = virt_to_page(vaddr); 184 ret, cq->cq_number);
185 return ret;
113 } 186 }
114 break; 187 break;
115 188
116 case 2: /* QP */ 189 default:
117 spin_lock_irqsave(&ehca_qp_idr_lock, flags); 190 ehca_err(cq->ib_cq.device, "bad resource type=%x cq_num=%x",
118 qp = idr_find(&ehca_qp_idr, idr_handle); 191 rsrc_type, cq->cq_number);
119 spin_unlock_irqrestore(&ehca_qp_idr_lock, flags); 192 return -EINVAL;
193 }
120 194
121 /* make sure this mmap really belongs to the authorized user */ 195 return 0;
122 if (!qp) { 196}
123 ehca_gen_err("qp is NULL ret=NOPAGE_SIGBUS"); 197
124 return NOPAGE_SIGBUS; 198static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
199 u32 rsrc_type)
200{
201 int ret;
202
203 switch (rsrc_type) {
204 case 1: /* galpa fw handle */
205 ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num);
206 ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa);
207 if (unlikely(ret)) {
208 ehca_err(qp->ib_qp.device,
209 "remap_pfn_range() failed ret=%x qp_num=%x",
210 ret, qp->ib_qp.qp_num);
211 return -ENOMEM;
125 } 212 }
213 break;
126 214
127 pd = container_of(qp->ib_qp.pd, struct ehca_pd, ib_pd); 215 case 2: /* qp rqueue_addr */
128 if (pd->ownpid != cur_pid) { 216 ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue",
217 qp->ib_qp.qp_num);
218 ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, &qp->mm_count_rqueue);
219 if (unlikely(ret)) {
129 ehca_err(qp->ib_qp.device, 220 ehca_err(qp->ib_qp.device,
130 "Invalid caller pid=%x ownpid=%x", 221 "ehca_mmap_queue(rq) failed rc=%x qp_num=%x",
131 cur_pid, pd->ownpid); 222 ret, qp->ib_qp.qp_num);
132 return NOPAGE_SIGBUS; 223 return ret;
133 } 224 }
225 break;
134 226
135 if (rsrc_type == 2) { /* rqueue */ 227 case 3: /* qp squeue_addr */
136 ehca_dbg(qp->ib_qp.device, "qp=%p qp rqueuearea", qp); 228 ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue",
137 offset = address - vma->vm_start; 229 qp->ib_qp.qp_num);
138 vaddr = ipz_qeit_calc(&qp->ipz_rqueue, offset); 230 ret = ehca_mmap_queue(vma, &qp->ipz_squeue, &qp->mm_count_squeue);
139 ehca_dbg(qp->ib_qp.device, "offset=%lx vaddr=%p", 231 if (unlikely(ret)) {
140 offset, vaddr); 232 ehca_err(qp->ib_qp.device,
141 mypage = virt_to_page(vaddr); 233 "ehca_mmap_queue(sq) failed rc=%x qp_num=%x",
142 } else if (rsrc_type == 3) { /* squeue */ 234 ret, qp->ib_qp.qp_num);
143 ehca_dbg(qp->ib_qp.device, "qp=%p qp squeuearea", qp); 235 return ret;
144 offset = address - vma->vm_start;
145 vaddr = ipz_qeit_calc(&qp->ipz_squeue, offset);
146 ehca_dbg(qp->ib_qp.device, "offset=%lx vaddr=%p",
147 offset, vaddr);
148 mypage = virt_to_page(vaddr);
149 } 236 }
150 break; 237 break;
151 238
152 default: 239 default:
153 ehca_gen_err("bad queue type %x", q_type); 240 ehca_err(qp->ib_qp.device, "bad resource type=%x qp=num=%x",
154 return NOPAGE_SIGBUS; 241 rsrc_type, qp->ib_qp.qp_num);
155 } 242 return -EINVAL;
156
157 if (!mypage) {
158 ehca_gen_err("Invalid page adr==NULL ret=NOPAGE_SIGBUS");
159 return NOPAGE_SIGBUS;
160 } 243 }
161 get_page(mypage);
162 244
163 return mypage; 245 return 0;
164} 246}
165 247
166static struct vm_operations_struct ehcau_vm_ops = {
167 .nopage = ehca_nopage,
168};
169
170int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) 248int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
171{ 249{
172 u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT; 250 u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT;
@@ -175,7 +253,6 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
175 u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */ 253 u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */
176 u32 cur_pid = current->tgid; 254 u32 cur_pid = current->tgid;
177 u32 ret; 255 u32 ret;
178 u64 vsize, physical;
179 unsigned long flags; 256 unsigned long flags;
180 struct ehca_cq *cq; 257 struct ehca_cq *cq;
181 struct ehca_qp *qp; 258 struct ehca_qp *qp;
@@ -201,44 +278,12 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
201 if (!cq->ib_cq.uobject || cq->ib_cq.uobject->context != context) 278 if (!cq->ib_cq.uobject || cq->ib_cq.uobject->context != context)
202 return -EINVAL; 279 return -EINVAL;
203 280
204 switch (rsrc_type) { 281 ret = ehca_mmap_cq(vma, cq, rsrc_type);
205 case 1: /* galpa fw handle */ 282 if (unlikely(ret)) {
206 ehca_dbg(cq->ib_cq.device, "cq=%p cq triggerarea", cq); 283 ehca_err(cq->ib_cq.device,
207 vma->vm_flags |= VM_RESERVED; 284 "ehca_mmap_cq() failed rc=%x cq_num=%x",
208 vsize = vma->vm_end - vma->vm_start; 285 ret, cq->cq_number);
209 if (vsize != EHCA_PAGESIZE) { 286 return ret;
210 ehca_err(cq->ib_cq.device, "invalid vsize=%lx",
211 vma->vm_end - vma->vm_start);
212 return -EINVAL;
213 }
214
215 physical = cq->galpas.user.fw_handle;
216 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
217 vma->vm_flags |= VM_IO | VM_RESERVED;
218
219 ehca_dbg(cq->ib_cq.device,
220 "vsize=%lx physical=%lx", vsize, physical);
221 ret = remap_pfn_range(vma, vma->vm_start,
222 physical >> PAGE_SHIFT, vsize,
223 vma->vm_page_prot);
224 if (ret) {
225 ehca_err(cq->ib_cq.device,
226 "remap_pfn_range() failed ret=%x",
227 ret);
228 return -ENOMEM;
229 }
230 break;
231
232 case 2: /* cq queue_addr */
233 ehca_dbg(cq->ib_cq.device, "cq=%p cq q_addr", cq);
234 vma->vm_flags |= VM_RESERVED;
235 vma->vm_ops = &ehcau_vm_ops;
236 break;
237
238 default:
239 ehca_err(cq->ib_cq.device, "bad resource type %x",
240 rsrc_type);
241 return -EINVAL;
242 } 287 }
243 break; 288 break;
244 289
@@ -262,50 +307,12 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
262 if (!qp->ib_qp.uobject || qp->ib_qp.uobject->context != context) 307 if (!qp->ib_qp.uobject || qp->ib_qp.uobject->context != context)
263 return -EINVAL; 308 return -EINVAL;
264 309
265 switch (rsrc_type) { 310 ret = ehca_mmap_qp(vma, qp, rsrc_type);
266 case 1: /* galpa fw handle */ 311 if (unlikely(ret)) {
267 ehca_dbg(qp->ib_qp.device, "qp=%p qp triggerarea", qp); 312 ehca_err(qp->ib_qp.device,
268 vma->vm_flags |= VM_RESERVED; 313 "ehca_mmap_qp() failed rc=%x qp_num=%x",
269 vsize = vma->vm_end - vma->vm_start; 314 ret, qp->ib_qp.qp_num);
270 if (vsize != EHCA_PAGESIZE) { 315 return ret;
271 ehca_err(qp->ib_qp.device, "invalid vsize=%lx",
272 vma->vm_end - vma->vm_start);
273 return -EINVAL;
274 }
275
276 physical = qp->galpas.user.fw_handle;
277 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
278 vma->vm_flags |= VM_IO | VM_RESERVED;
279
280 ehca_dbg(qp->ib_qp.device, "vsize=%lx physical=%lx",
281 vsize, physical);
282 ret = remap_pfn_range(vma, vma->vm_start,
283 physical >> PAGE_SHIFT, vsize,
284 vma->vm_page_prot);
285 if (ret) {
286 ehca_err(qp->ib_qp.device,
287 "remap_pfn_range() failed ret=%x",
288 ret);
289 return -ENOMEM;
290 }
291 break;
292
293 case 2: /* qp rqueue_addr */
294 ehca_dbg(qp->ib_qp.device, "qp=%p qp rqueue_addr", qp);
295 vma->vm_flags |= VM_RESERVED;
296 vma->vm_ops = &ehcau_vm_ops;
297 break;
298
299 case 3: /* qp squeue_addr */
300 ehca_dbg(qp->ib_qp.device, "qp=%p qp squeue_addr", qp);
301 vma->vm_flags |= VM_RESERVED;
302 vma->vm_ops = &ehcau_vm_ops;
303 break;
304
305 default:
306 ehca_err(qp->ib_qp.device, "bad resource type %x",
307 rsrc_type);
308 return -EINVAL;
309 } 316 }
310 break; 317 break;
311 318
@@ -316,77 +323,3 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
316 323
317 return 0; 324 return 0;
318} 325}
319
320int ehca_mmap_nopage(u64 foffset, u64 length, void **mapped,
321 struct vm_area_struct **vma)
322{
323 down_write(&current->mm->mmap_sem);
324 *mapped = (void*)do_mmap(NULL,0, length, PROT_WRITE,
325 MAP_SHARED | MAP_ANONYMOUS,
326 foffset);
327 up_write(&current->mm->mmap_sem);
328 if (!(*mapped)) {
329 ehca_gen_err("couldn't mmap foffset=%lx length=%lx",
330 foffset, length);
331 return -EINVAL;
332 }
333
334 *vma = find_vma(current->mm, (u64)*mapped);
335 if (!(*vma)) {
336 down_write(&current->mm->mmap_sem);
337 do_munmap(current->mm, 0, length);
338 up_write(&current->mm->mmap_sem);
339 ehca_gen_err("couldn't find vma queue=%p", *mapped);
340 return -EINVAL;
341 }
342 (*vma)->vm_flags |= VM_RESERVED;
343 (*vma)->vm_ops = &ehcau_vm_ops;
344
345 return 0;
346}
347
348int ehca_mmap_register(u64 physical, void **mapped,
349 struct vm_area_struct **vma)
350{
351 int ret;
352 unsigned long vsize;
353 /* ehca hw supports only 4k page */
354 ret = ehca_mmap_nopage(0, EHCA_PAGESIZE, mapped, vma);
355 if (ret) {
356 ehca_gen_err("could'nt mmap physical=%lx", physical);
357 return ret;
358 }
359
360 (*vma)->vm_flags |= VM_RESERVED;
361 vsize = (*vma)->vm_end - (*vma)->vm_start;
362 if (vsize != EHCA_PAGESIZE) {
363 ehca_gen_err("invalid vsize=%lx",
364 (*vma)->vm_end - (*vma)->vm_start);
365 return -EINVAL;
366 }
367
368 (*vma)->vm_page_prot = pgprot_noncached((*vma)->vm_page_prot);
369 (*vma)->vm_flags |= VM_IO | VM_RESERVED;
370
371 ret = remap_pfn_range((*vma), (*vma)->vm_start,
372 physical >> PAGE_SHIFT, vsize,
373 (*vma)->vm_page_prot);
374 if (ret) {
375 ehca_gen_err("remap_pfn_range() failed ret=%x", ret);
376 return -ENOMEM;
377 }
378
379 return 0;
380
381}
382
383int ehca_munmap(unsigned long addr, size_t len) {
384 int ret = 0;
385 struct mm_struct *mm = current->mm;
386 if (mm) {
387 down_write(&mm->mmap_sem);
388 ret = do_munmap(mm, addr, len);
389 up_write(&mm->mmap_sem);
390 }
391 return ret;
392}
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 46c1c89bf6ae..64f07b19349f 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -379,7 +379,7 @@ void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
379 wc.vendor_err = 0; 379 wc.vendor_err = 0;
380 wc.byte_len = 0; 380 wc.byte_len = 0;
381 wc.imm_data = 0; 381 wc.imm_data = 0;
382 wc.qp_num = qp->ibqp.qp_num; 382 wc.qp = &qp->ibqp;
383 wc.src_qp = 0; 383 wc.src_qp = 0;
384 wc.wc_flags = 0; 384 wc.wc_flags = 0;
385 wc.pkey_index = 0; 385 wc.pkey_index = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index ce6038743c5c..5ff20cb04494 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -702,7 +702,7 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
702 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 702 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
703 wc->vendor_err = 0; 703 wc->vendor_err = 0;
704 wc->byte_len = 0; 704 wc->byte_len = 0;
705 wc->qp_num = qp->ibqp.qp_num; 705 wc->qp = &qp->ibqp;
706 wc->src_qp = qp->remote_qpn; 706 wc->src_qp = qp->remote_qpn;
707 wc->pkey_index = 0; 707 wc->pkey_index = 0;
708 wc->slid = qp->remote_ah_attr.dlid; 708 wc->slid = qp->remote_ah_attr.dlid;
@@ -836,7 +836,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
836 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 836 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
837 wc.vendor_err = 0; 837 wc.vendor_err = 0;
838 wc.byte_len = wqe->length; 838 wc.byte_len = wqe->length;
839 wc.qp_num = qp->ibqp.qp_num; 839 wc.qp = &qp->ibqp;
840 wc.src_qp = qp->remote_qpn; 840 wc.src_qp = qp->remote_qpn;
841 wc.pkey_index = 0; 841 wc.pkey_index = 0;
842 wc.slid = qp->remote_ah_attr.dlid; 842 wc.slid = qp->remote_ah_attr.dlid;
@@ -951,7 +951,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
951 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 951 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
952 wc.vendor_err = 0; 952 wc.vendor_err = 0;
953 wc.byte_len = 0; 953 wc.byte_len = 0;
954 wc.qp_num = qp->ibqp.qp_num; 954 wc.qp = &qp->ibqp;
955 wc.src_qp = qp->remote_qpn; 955 wc.src_qp = qp->remote_qpn;
956 wc.pkey_index = 0; 956 wc.pkey_index = 0;
957 wc.slid = qp->remote_ah_attr.dlid; 957 wc.slid = qp->remote_ah_attr.dlid;
@@ -1511,7 +1511,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
1511 wc.status = IB_WC_SUCCESS; 1511 wc.status = IB_WC_SUCCESS;
1512 wc.opcode = IB_WC_RECV; 1512 wc.opcode = IB_WC_RECV;
1513 wc.vendor_err = 0; 1513 wc.vendor_err = 0;
1514 wc.qp_num = qp->ibqp.qp_num; 1514 wc.qp = &qp->ibqp;
1515 wc.src_qp = qp->remote_qpn; 1515 wc.src_qp = qp->remote_qpn;
1516 wc.pkey_index = 0; 1516 wc.pkey_index = 0;
1517 wc.slid = qp->remote_ah_attr.dlid; 1517 wc.slid = qp->remote_ah_attr.dlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index f7530512045d..e86cb171872e 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -137,7 +137,7 @@ bad_lkey:
137 wc.vendor_err = 0; 137 wc.vendor_err = 0;
138 wc.byte_len = 0; 138 wc.byte_len = 0;
139 wc.imm_data = 0; 139 wc.imm_data = 0;
140 wc.qp_num = qp->ibqp.qp_num; 140 wc.qp = &qp->ibqp;
141 wc.src_qp = 0; 141 wc.src_qp = 0;
142 wc.wc_flags = 0; 142 wc.wc_flags = 0;
143 wc.pkey_index = 0; 143 wc.pkey_index = 0;
@@ -336,7 +336,7 @@ again:
336 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 336 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
337 wc.vendor_err = 0; 337 wc.vendor_err = 0;
338 wc.byte_len = 0; 338 wc.byte_len = 0;
339 wc.qp_num = sqp->ibqp.qp_num; 339 wc.qp = &sqp->ibqp;
340 wc.src_qp = sqp->remote_qpn; 340 wc.src_qp = sqp->remote_qpn;
341 wc.pkey_index = 0; 341 wc.pkey_index = 0;
342 wc.slid = sqp->remote_ah_attr.dlid; 342 wc.slid = sqp->remote_ah_attr.dlid;
@@ -426,7 +426,7 @@ again:
426 wc.status = IB_WC_SUCCESS; 426 wc.status = IB_WC_SUCCESS;
427 wc.vendor_err = 0; 427 wc.vendor_err = 0;
428 wc.byte_len = wqe->length; 428 wc.byte_len = wqe->length;
429 wc.qp_num = qp->ibqp.qp_num; 429 wc.qp = &qp->ibqp;
430 wc.src_qp = qp->remote_qpn; 430 wc.src_qp = qp->remote_qpn;
431 /* XXX do we know which pkey matched? Only needed for GSI. */ 431 /* XXX do we know which pkey matched? Only needed for GSI. */
432 wc.pkey_index = 0; 432 wc.pkey_index = 0;
@@ -447,7 +447,7 @@ send_comp:
447 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 447 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
448 wc.vendor_err = 0; 448 wc.vendor_err = 0;
449 wc.byte_len = wqe->length; 449 wc.byte_len = wqe->length;
450 wc.qp_num = sqp->ibqp.qp_num; 450 wc.qp = &sqp->ibqp;
451 wc.src_qp = 0; 451 wc.src_qp = 0;
452 wc.pkey_index = 0; 452 wc.pkey_index = 0;
453 wc.slid = 0; 453 wc.slid = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index e636cfd67a82..325d6634ff53 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -49,7 +49,7 @@ static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe,
49 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 49 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
50 wc->vendor_err = 0; 50 wc->vendor_err = 0;
51 wc->byte_len = wqe->length; 51 wc->byte_len = wqe->length;
52 wc->qp_num = qp->ibqp.qp_num; 52 wc->qp = &qp->ibqp;
53 wc->src_qp = qp->remote_qpn; 53 wc->src_qp = qp->remote_qpn;
54 wc->pkey_index = 0; 54 wc->pkey_index = 0;
55 wc->slid = qp->remote_ah_attr.dlid; 55 wc->slid = qp->remote_ah_attr.dlid;
@@ -411,7 +411,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
411 wc.status = IB_WC_SUCCESS; 411 wc.status = IB_WC_SUCCESS;
412 wc.opcode = IB_WC_RECV; 412 wc.opcode = IB_WC_RECV;
413 wc.vendor_err = 0; 413 wc.vendor_err = 0;
414 wc.qp_num = qp->ibqp.qp_num; 414 wc.qp = &qp->ibqp;
415 wc.src_qp = qp->remote_qpn; 415 wc.src_qp = qp->remote_qpn;
416 wc.pkey_index = 0; 416 wc.pkey_index = 0;
417 wc.slid = qp->remote_ah_attr.dlid; 417 wc.slid = qp->remote_ah_attr.dlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 49f1102af8b3..9a3e54664ee4 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -66,7 +66,7 @@ bad_lkey:
66 wc.vendor_err = 0; 66 wc.vendor_err = 0;
67 wc.byte_len = 0; 67 wc.byte_len = 0;
68 wc.imm_data = 0; 68 wc.imm_data = 0;
69 wc.qp_num = qp->ibqp.qp_num; 69 wc.qp = &qp->ibqp;
70 wc.src_qp = 0; 70 wc.src_qp = 0;
71 wc.wc_flags = 0; 71 wc.wc_flags = 0;
72 wc.pkey_index = 0; 72 wc.pkey_index = 0;
@@ -255,7 +255,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
255 wc->status = IB_WC_SUCCESS; 255 wc->status = IB_WC_SUCCESS;
256 wc->opcode = IB_WC_RECV; 256 wc->opcode = IB_WC_RECV;
257 wc->vendor_err = 0; 257 wc->vendor_err = 0;
258 wc->qp_num = qp->ibqp.qp_num; 258 wc->qp = &qp->ibqp;
259 wc->src_qp = sqp->ibqp.qp_num; 259 wc->src_qp = sqp->ibqp.qp_num;
260 /* XXX do we know which pkey matched? Only needed for GSI. */ 260 /* XXX do we know which pkey matched? Only needed for GSI. */
261 wc->pkey_index = 0; 261 wc->pkey_index = 0;
@@ -474,7 +474,7 @@ done:
474 wc.vendor_err = 0; 474 wc.vendor_err = 0;
475 wc.opcode = IB_WC_SEND; 475 wc.opcode = IB_WC_SEND;
476 wc.byte_len = len; 476 wc.byte_len = len;
477 wc.qp_num = qp->ibqp.qp_num; 477 wc.qp = &qp->ibqp;
478 wc.src_qp = 0; 478 wc.src_qp = 0;
479 wc.wc_flags = 0; 479 wc.wc_flags = 0;
480 /* XXX initialize other fields? */ 480 /* XXX initialize other fields? */
@@ -651,7 +651,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
651 wc.status = IB_WC_SUCCESS; 651 wc.status = IB_WC_SUCCESS;
652 wc.opcode = IB_WC_RECV; 652 wc.opcode = IB_WC_RECV;
653 wc.vendor_err = 0; 653 wc.vendor_err = 0;
654 wc.qp_num = qp->ibqp.qp_num; 654 wc.qp = &qp->ibqp;
655 wc.src_qp = src_qp; 655 wc.src_qp = src_qp;
656 /* XXX do we know which pkey matched? Only needed for GSI. */ 656 /* XXX do we know which pkey matched? Only needed for GSI. */
657 wc.pkey_index = 0; 657 wc.pkey_index = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 768df7265b81..968d1519761c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1854,7 +1854,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey,
1854 1854
1855 memset(inbox + 256, 0, 256); 1855 memset(inbox + 256, 0, 256);
1856 1856
1857 MTHCA_PUT(inbox, in_wc->qp_num, MAD_IFC_MY_QPN_OFFSET); 1857 MTHCA_PUT(inbox, in_wc->qp->qp_num, MAD_IFC_MY_QPN_OFFSET);
1858 MTHCA_PUT(inbox, in_wc->src_qp, MAD_IFC_RQPN_OFFSET); 1858 MTHCA_PUT(inbox, in_wc->src_qp, MAD_IFC_RQPN_OFFSET);
1859 1859
1860 val = in_wc->sl << 4; 1860 val = in_wc->sl << 4;
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 1159c8a0f2c5..efd79ef109a6 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -534,7 +534,7 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
534 } 534 }
535 } 535 }
536 536
537 entry->qp_num = (*cur_qp)->qpn; 537 entry->qp = &(*cur_qp)->ibqp;
538 538
539 if (is_send) { 539 if (is_send) {
540 wq = &(*cur_qp)->sq; 540 wq = &(*cur_qp)->sq;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 72611fd15103..5e8ac577f0ad 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -548,6 +548,7 @@ static int srp_reconnect_target(struct srp_target_port *target)
548 target->tx_head = 0; 548 target->tx_head = 0;
549 target->tx_tail = 0; 549 target->tx_tail = 0;
550 550
551 target->qp_in_error = 0;
551 ret = srp_connect_target(target); 552 ret = srp_connect_target(target);
552 if (ret) 553 if (ret)
553 goto err; 554 goto err;
@@ -878,6 +879,7 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr)
878 printk(KERN_ERR PFX "failed %s status %d\n", 879 printk(KERN_ERR PFX "failed %s status %d\n",
879 wc.wr_id & SRP_OP_RECV ? "receive" : "send", 880 wc.wr_id & SRP_OP_RECV ? "receive" : "send",
880 wc.status); 881 wc.status);
882 target->qp_in_error = 1;
881 break; 883 break;
882 } 884 }
883 885
@@ -1337,6 +1339,8 @@ static int srp_abort(struct scsi_cmnd *scmnd)
1337 1339
1338 printk(KERN_ERR "SRP abort called\n"); 1340 printk(KERN_ERR "SRP abort called\n");
1339 1341
1342 if (target->qp_in_error)
1343 return FAILED;
1340 if (srp_find_req(target, scmnd, &req)) 1344 if (srp_find_req(target, scmnd, &req))
1341 return FAILED; 1345 return FAILED;
1342 if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK)) 1346 if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK))
@@ -1365,6 +1369,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
1365 1369
1366 printk(KERN_ERR "SRP reset_device called\n"); 1370 printk(KERN_ERR "SRP reset_device called\n");
1367 1371
1372 if (target->qp_in_error)
1373 return FAILED;
1368 if (srp_find_req(target, scmnd, &req)) 1374 if (srp_find_req(target, scmnd, &req))
1369 return FAILED; 1375 return FAILED;
1370 if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET)) 1376 if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET))
@@ -1801,6 +1807,7 @@ static ssize_t srp_create_target(struct class_device *class_dev,
1801 goto err_free; 1807 goto err_free;
1802 } 1808 }
1803 1809
1810 target->qp_in_error = 0;
1804 ret = srp_connect_target(target); 1811 ret = srp_connect_target(target);
1805 if (ret) { 1812 if (ret) {
1806 printk(KERN_ERR PFX "Connection failed\n"); 1813 printk(KERN_ERR PFX "Connection failed\n");
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index c21772317b86..2f3319c719a5 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -158,6 +158,7 @@ struct srp_target_port {
158 struct completion done; 158 struct completion done;
159 int status; 159 int status;
160 enum srp_target_state state; 160 enum srp_target_state state;
161 int qp_in_error;
161}; 162};
162 163
163struct srp_iu { 164struct srp_iu {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 00db31c314e0..89bba277da5f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -69,6 +69,25 @@ config TIFM_7XX1
69 To compile this driver as a module, choose M here: the module will 69 To compile this driver as a module, choose M here: the module will
70 be called tifm_7xx1. 70 be called tifm_7xx1.
71 71
72config ASUS_LAPTOP
73 tristate "Asus Laptop Extras (EXPERIMENTAL)"
74 depends on X86
75 depends on ACPI
76 depends on EXPERIMENTAL && !ACPI_ASUS
77 depends on LEDS_CLASS
78 depends on BACKLIGHT_CLASS_DEVICE
79 ---help---
80 This is the new Linux driver for Asus laptops. It may also support some
81 MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
82 standard ACPI events that go through /proc/acpi/events. It also adds
83 support for video output switching, LCD backlight control, Bluetooth and
84 Wlan control, and most importantly, allows you to blink those fancy LEDs.
85
86 For more information and a userspace daemon for handling the extra
87 buttons see <http://acpi4asus.sf.net/>.
88
89 If you have an ACPI-compatible ASUS laptop, say Y or M here.
90
72config MSI_LAPTOP 91config MSI_LAPTOP
73 tristate "MSI Laptop Extras" 92 tristate "MSI Laptop Extras"
74 depends on X86 93 depends on X86
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c9e98ab021c5..35da53c409c0 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -6,6 +6,7 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
6obj-$(CONFIG_IBM_ASM) += ibmasm/ 6obj-$(CONFIG_IBM_ASM) += ibmasm/
7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ 7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o 8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
9obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
9obj-$(CONFIG_LKDTM) += lkdtm.o 10obj-$(CONFIG_LKDTM) += lkdtm.o
10obj-$(CONFIG_TIFM_CORE) += tifm_core.o 11obj-$(CONFIG_TIFM_CORE) += tifm_core.o
11obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
new file mode 100644
index 000000000000..861c39935f99
--- /dev/null
+++ b/drivers/misc/asus-laptop.c
@@ -0,0 +1,1165 @@
1/*
2 * asus-laptop.c - Asus Laptop Support
3 *
4 *
5 * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
6 * Copyright (C) 2006 Corentin Chary
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 *
23 * The development page for this driver is located at
24 * http://sourceforge.net/projects/acpi4asus/
25 *
26 * Credits:
27 * Pontus Fuchs - Helper functions, cleanup
28 * Johann Wiesner - Small compile fixes
29 * John Belmonte - ACPI code for Toshiba laptop was a good starting point.
30 * Eric Burghard - LED display support for W1N
31 * Josh Green - Light Sens support
32 * Thomas Tuttle - His first patch for led support was very helpfull
33 *
34 */
35
36#include <linux/autoconf.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/types.h>
41#include <linux/err.h>
42#include <linux/proc_fs.h>
43#include <linux/backlight.h>
44#include <linux/fb.h>
45#include <linux/leds.h>
46#include <linux/platform_device.h>
47#include <acpi/acpi_drivers.h>
48#include <acpi/acpi_bus.h>
49#include <asm/uaccess.h>
50
51#define ASUS_LAPTOP_VERSION "0.40"
52
53#define ASUS_HOTK_NAME "Asus Laptop Support"
54#define ASUS_HOTK_CLASS "hotkey"
55#define ASUS_HOTK_DEVICE_NAME "Hotkey"
56#define ASUS_HOTK_HID "ATK0100"
57#define ASUS_HOTK_FILE "asus-laptop"
58#define ASUS_HOTK_PREFIX "\\_SB.ATKD."
59
60/*
61 * Some events we use, same for all Asus
62 */
63#define ATKD_BR_UP 0x10
64#define ATKD_BR_DOWN 0x20
65#define ATKD_LCD_ON 0x33
66#define ATKD_LCD_OFF 0x34
67
68/*
69 * Known bits returned by \_SB.ATKD.HWRS
70 */
71#define WL_HWRS 0x80
72#define BT_HWRS 0x100
73
74/*
75 * Flags for hotk status
76 * WL_ON and BT_ON are also used for wireless_status()
77 */
78#define WL_ON 0x01 //internal Wifi
79#define BT_ON 0x02 //internal Bluetooth
80#define MLED_ON 0x04 //mail LED
81#define TLED_ON 0x08 //touchpad LED
82#define RLED_ON 0x10 //Record LED
83#define PLED_ON 0x20 //Phone LED
84#define LCD_ON 0x40 //LCD backlight
85
86#define ASUS_LOG ASUS_HOTK_FILE ": "
87#define ASUS_ERR KERN_ERR ASUS_LOG
88#define ASUS_WARNING KERN_WARNING ASUS_LOG
89#define ASUS_NOTICE KERN_NOTICE ASUS_LOG
90#define ASUS_INFO KERN_INFO ASUS_LOG
91#define ASUS_DEBUG KERN_DEBUG ASUS_LOG
92
93MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
94MODULE_DESCRIPTION(ASUS_HOTK_NAME);
95MODULE_LICENSE("GPL");
96
97#define ASUS_HANDLE(object, paths...) \
98 static acpi_handle object##_handle = NULL; \
99 static char *object##_paths[] = { paths }
100
101/* LED */
102ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
103ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
104ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */
105ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */
106
107/* LEDD */
108ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
109
110/* Bluetooth and WLAN
111 * WLED and BLED are not handled like other XLED, because in some dsdt
112 * they also control the WLAN/Bluetooth device.
113 */
114ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED");
115ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED");
116ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS"); /* All new models */
117
118/* Brightness */
119ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV");
120ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV");
121
122/* Backlight */
123ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
124 "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */
125 "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
126 "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */
127 "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
128 "\\_SB.PCI0.PX40.Q10", /* S1x */
129 "\\Q10"); /* A2x, L2D, L3D, M2E */
130
131/* Display */
132ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP");
133ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G
134 M6A M6V VX-1 V6J V6V W3Z */
135 "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V
136 S5A M5A z33A W1Jc W2V */
137 "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */
138 "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */
139 "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */
140 "\\_SB.PCI0.VGA.GETD", /* Z96F */
141 "\\ACTD", /* A2D */
142 "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
143 "\\DNXT", /* P30 */
144 "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
145 "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */
146
147ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */
148ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */
149
150/*
151 * This is the main structure, we can use it to store anything interesting
152 * about the hotk device
153 */
154struct asus_hotk {
155 char *name; //laptop name
156 struct acpi_device *device; //the device we are in
157 acpi_handle handle; //the handle of the hotk device
158 char status; //status of the hotk, for LEDs, ...
159 u32 ledd_status; //status of the LED display
160 u8 light_level; //light sensor level
161 u8 light_switch; //light sensor switch value
162 u16 event_count[128]; //count for each event TODO make this better
163};
164
165/*
166 * This header is made available to allow proper configuration given model,
167 * revision number , ... this info cannot go in struct asus_hotk because it is
168 * available before the hotk
169 */
170static struct acpi_table_header *asus_info;
171
172/* The actual device the driver binds to */
173static struct asus_hotk *hotk;
174
175/*
176 * The hotkey driver declaration
177 */
178static int asus_hotk_add(struct acpi_device *device);
179static int asus_hotk_remove(struct acpi_device *device, int type);
180static struct acpi_driver asus_hotk_driver = {
181 .name = ASUS_HOTK_NAME,
182 .class = ASUS_HOTK_CLASS,
183 .ids = ASUS_HOTK_HID,
184 .ops = {
185 .add = asus_hotk_add,
186 .remove = asus_hotk_remove,
187 },
188};
189
190/* The backlight device /sys/class/backlight */
191static struct backlight_device *asus_backlight_device;
192
193/*
194 * The backlight class declaration
195 */
196static int read_brightness(struct backlight_device *bd);
197static int update_bl_status(struct backlight_device *bd);
198static struct backlight_properties asusbl_data = {
199 .owner = THIS_MODULE,
200 .get_brightness = read_brightness,
201 .update_status = update_bl_status,
202 .max_brightness = 15,
203};
204
205/* These functions actually update the LED's, and are called from a
206 * workqueue. By doing this as separate work rather than when the LED
207 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
208 * potentially bad time, such as a timer interrupt. */
209static struct workqueue_struct *led_workqueue;
210
211#define ASUS_LED(object, ledname) \
212 static void object##_led_set(struct led_classdev *led_cdev, \
213 enum led_brightness value); \
214 static void object##_led_update(struct work_struct *ignored); \
215 static int object##_led_wk; \
216 DECLARE_WORK(object##_led_work, object##_led_update); \
217 static struct led_classdev object##_led = { \
218 .name = "asus:" ledname, \
219 .brightness_set = object##_led_set, \
220 }
221
222ASUS_LED(mled, "mail");
223ASUS_LED(tled, "touchpad");
224ASUS_LED(rled, "record");
225ASUS_LED(pled, "phone");
226
227/*
228 * This function evaluates an ACPI method, given an int as parameter, the
229 * method is searched within the scope of the handle, can be NULL. The output
230 * of the method is written is output, which can also be NULL
231 *
232 * returns 1 if write is successful, 0 else.
233 */
234static int write_acpi_int(acpi_handle handle, const char *method, int val,
235 struct acpi_buffer *output)
236{
237 struct acpi_object_list params; //list of input parameters (an int here)
238 union acpi_object in_obj; //the only param we use
239 acpi_status status;
240
241 params.count = 1;
242 params.pointer = &in_obj;
243 in_obj.type = ACPI_TYPE_INTEGER;
244 in_obj.integer.value = val;
245
246 status = acpi_evaluate_object(handle, (char *)method, &params, output);
247 return (status == AE_OK);
248}
249
250static int read_acpi_int(acpi_handle handle, const char *method, int *val,
251 struct acpi_object_list *params)
252{
253 struct acpi_buffer output;
254 union acpi_object out_obj;
255 acpi_status status;
256
257 output.length = sizeof(out_obj);
258 output.pointer = &out_obj;
259
260 status = acpi_evaluate_object(handle, (char *)method, params, &output);
261 *val = out_obj.integer.value;
262 return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
263}
264
265static int read_wireless_status(int mask)
266{
267 int status;
268
269 if (!wireless_status_handle)
270 return (hotk->status & mask) ? 1 : 0;
271
272 if (read_acpi_int(wireless_status_handle, NULL, &status, NULL)) {
273 return (status & mask) ? 1 : 0;
274 } else
275 printk(ASUS_WARNING "Error reading Wireless status\n");
276
277 return (hotk->status & mask) ? 1 : 0;
278}
279
280/* Generic LED functions */
281static int read_status(int mask)
282{
283 /* There is a special method for both wireless devices */
284 if (mask == BT_ON || mask == WL_ON)
285 return read_wireless_status(mask);
286
287 return (hotk->status & mask) ? 1 : 0;
288}
289
290static void write_status(acpi_handle handle, int out, int mask, int invert)
291{
292 hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask);
293
294 if (invert) /* invert target value */
295 out = !out & 0x1;
296
297 if (handle && !write_acpi_int(handle, NULL, out, NULL))
298 printk(ASUS_WARNING " write failed\n");
299}
300
301/* /sys/class/led handlers */
302#define ASUS_LED_HANDLER(object, mask, invert) \
303 static void object##_led_set(struct led_classdev *led_cdev, \
304 enum led_brightness value) \
305 { \
306 object##_led_wk = value; \
307 queue_work(led_workqueue, &object##_led_work); \
308 } \
309 static void object##_led_update(struct work_struct *ignored) \
310 { \
311 int value = object##_led_wk; \
312 write_status(object##_set_handle, value, (mask), (invert)); \
313 }
314
315ASUS_LED_HANDLER(mled, MLED_ON, 1);
316ASUS_LED_HANDLER(pled, PLED_ON, 0);
317ASUS_LED_HANDLER(rled, RLED_ON, 0);
318ASUS_LED_HANDLER(tled, TLED_ON, 0);
319
320static int get_lcd_state(void)
321{
322 return read_status(LCD_ON);
323}
324
325static int set_lcd_state(int value)
326{
327 int lcd = 0;
328 acpi_status status = 0;
329
330 lcd = value ? 1 : 0;
331
332 if (lcd == get_lcd_state())
333 return 0;
334
335 if (lcd_switch_handle) {
336 status = acpi_evaluate_object(lcd_switch_handle,
337 NULL, NULL, NULL);
338
339 if (ACPI_FAILURE(status))
340 printk(ASUS_WARNING "Error switching LCD\n");
341 }
342
343 write_status(NULL, lcd, LCD_ON, 0);
344 return 0;
345}
346
347static void lcd_blank(int blank)
348{
349 struct backlight_device *bd = asus_backlight_device;
350
351 if (bd) {
352 down(&bd->sem);
353 if (likely(bd->props)) {
354 bd->props->power = blank;
355 if (likely(bd->props->update_status))
356 bd->props->update_status(bd);
357 }
358 up(&bd->sem);
359 }
360}
361
362static int read_brightness(struct backlight_device *bd)
363{
364 int value;
365
366 if (!read_acpi_int(brightness_get_handle, NULL, &value, NULL))
367 printk(ASUS_WARNING "Error reading brightness\n");
368
369 return value;
370}
371
372static int set_brightness(struct backlight_device *bd, int value)
373{
374 int ret = 0;
375
376 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
377 /* 0 <= value <= 15 */
378
379 if (!write_acpi_int(brightness_set_handle, NULL, value, NULL)) {
380 printk(ASUS_WARNING "Error changing brightness\n");
381 ret = -EIO;
382 }
383
384 return ret;
385}
386
387static int update_bl_status(struct backlight_device *bd)
388{
389 int rv;
390 int value = bd->props->brightness;
391
392 rv = set_brightness(bd, value);
393 if (rv)
394 return rv;
395
396 value = (bd->props->power == FB_BLANK_UNBLANK) ? 1 : 0;
397 return set_lcd_state(value);
398}
399
400/*
401 * Platform device handlers
402 */
403
404/*
405 * We write our info in page, we begin at offset off and cannot write more
406 * than count bytes. We set eof to 1 if we handle those 2 values. We return the
407 * number of bytes written in page
408 */
409static ssize_t show_infos(struct device *dev,
410 struct device_attribute *attr, char *page)
411{
412 int len = 0;
413 int temp;
414 char buf[16]; //enough for all info
415 /*
416 * We use the easy way, we don't care of off and count, so we don't set eof
417 * to 1
418 */
419
420 len += sprintf(page, ASUS_HOTK_NAME " " ASUS_LAPTOP_VERSION "\n");
421 len += sprintf(page + len, "Model reference : %s\n", hotk->name);
422 /*
423 * The SFUN method probably allows the original driver to get the list
424 * of features supported by a given model. For now, 0x0100 or 0x0800
425 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
426 * The significance of others is yet to be found.
427 */
428 if (read_acpi_int(hotk->handle, "SFUN", &temp, NULL))
429 len +=
430 sprintf(page + len, "SFUN value : 0x%04x\n", temp);
431 /*
432 * Another value for userspace: the ASYM method returns 0x02 for
433 * battery low and 0x04 for battery critical, its readings tend to be
434 * more accurate than those provided by _BST.
435 * Note: since not all the laptops provide this method, errors are
436 * silently ignored.
437 */
438 if (read_acpi_int(hotk->handle, "ASYM", &temp, NULL))
439 len +=
440 sprintf(page + len, "ASYM value : 0x%04x\n", temp);
441 if (asus_info) {
442 snprintf(buf, 16, "%d", asus_info->length);
443 len += sprintf(page + len, "DSDT length : %s\n", buf);
444 snprintf(buf, 16, "%d", asus_info->checksum);
445 len += sprintf(page + len, "DSDT checksum : %s\n", buf);
446 snprintf(buf, 16, "%d", asus_info->revision);
447 len += sprintf(page + len, "DSDT revision : %s\n", buf);
448 snprintf(buf, 7, "%s", asus_info->oem_id);
449 len += sprintf(page + len, "OEM id : %s\n", buf);
450 snprintf(buf, 9, "%s", asus_info->oem_table_id);
451 len += sprintf(page + len, "OEM table id : %s\n", buf);
452 snprintf(buf, 16, "%x", asus_info->oem_revision);
453 len += sprintf(page + len, "OEM revision : 0x%s\n", buf);
454 snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
455 len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
456 snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
457 len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf);
458 }
459
460 return len;
461}
462
463static int parse_arg(const char *buf, unsigned long count, int *val)
464{
465 if (!count)
466 return 0;
467 if (count > 31)
468 return -EINVAL;
469 if (sscanf(buf, "%i", val) != 1)
470 return -EINVAL;
471 return count;
472}
473
474static ssize_t store_status(const char *buf, size_t count,
475 acpi_handle handle, int mask, int invert)
476{
477 int rv, value;
478 int out = 0;
479
480 rv = parse_arg(buf, count, &value);
481 if (rv > 0)
482 out = value ? 1 : 0;
483
484 write_status(handle, out, mask, invert);
485
486 return rv;
487}
488
489/*
490 * LEDD display
491 */
492static ssize_t show_ledd(struct device *dev,
493 struct device_attribute *attr, char *buf)
494{
495 return sprintf(buf, "0x%08x\n", hotk->ledd_status);
496}
497
498static ssize_t store_ledd(struct device *dev, struct device_attribute *attr,
499 const char *buf, size_t count)
500{
501 int rv, value;
502
503 rv = parse_arg(buf, count, &value);
504 if (rv > 0) {
505 if (!write_acpi_int(ledd_set_handle, NULL, value, NULL))
506 printk(ASUS_WARNING "LED display write failed\n");
507 else
508 hotk->ledd_status = (u32) value;
509 }
510 return rv;
511}
512
513/*
514 * WLAN
515 */
516static ssize_t show_wlan(struct device *dev,
517 struct device_attribute *attr, char *buf)
518{
519 return sprintf(buf, "%d\n", read_status(WL_ON));
520}
521
522static ssize_t store_wlan(struct device *dev, struct device_attribute *attr,
523 const char *buf, size_t count)
524{
525 return store_status(buf, count, wl_switch_handle, WL_ON, 0);
526}
527
528/*
529 * Bluetooth
530 */
531static ssize_t show_bluetooth(struct device *dev,
532 struct device_attribute *attr, char *buf)
533{
534 return sprintf(buf, "%d\n", read_status(BT_ON));
535}
536
537static ssize_t store_bluetooth(struct device *dev,
538 struct device_attribute *attr, const char *buf,
539 size_t count)
540{
541 return store_status(buf, count, bt_switch_handle, BT_ON, 0);
542}
543
544/*
545 * Display
546 */
547static void set_display(int value)
548{
549 /* no sanity check needed for now */
550 if (!write_acpi_int(display_set_handle, NULL, value, NULL))
551 printk(ASUS_WARNING "Error setting display\n");
552 return;
553}
554
555static int read_display(void)
556{
557 int value = 0;
558
559 /* In most of the case, we know how to set the display, but sometime
560 we can't read it */
561 if (display_get_handle) {
562 if (!read_acpi_int(display_get_handle, NULL, &value, NULL))
563 printk(ASUS_WARNING "Error reading display status\n");
564 }
565
566 value &= 0x0F; /* needed for some models, shouldn't hurt others */
567
568 return value;
569}
570
571/*
572 * Now, *this* one could be more user-friendly, but so far, no-one has
573 * complained. The significance of bits is the same as in store_disp()
574 */
575static ssize_t show_disp(struct device *dev,
576 struct device_attribute *attr, char *buf)
577{
578 return sprintf(buf, "%d\n", read_display());
579}
580
581/*
582 * Experimental support for display switching. As of now: 1 should activate
583 * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI.
584 * Any combination (bitwise) of these will suffice. I never actually tested 4
585 * displays hooked up simultaneously, so be warned. See the acpi4asus README
586 * for more info.
587 */
588static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
589 const char *buf, size_t count)
590{
591 int rv, value;
592
593 rv = parse_arg(buf, count, &value);
594 if (rv > 0)
595 set_display(value);
596 return rv;
597}
598
599/*
600 * Light Sens
601 */
602static void set_light_sens_switch(int value)
603{
604 if (!write_acpi_int(ls_switch_handle, NULL, value, NULL))
605 printk(ASUS_WARNING "Error setting light sensor switch\n");
606 hotk->light_switch = value;
607}
608
609static ssize_t show_lssw(struct device *dev,
610 struct device_attribute *attr, char *buf)
611{
612 return sprintf(buf, "%d\n", hotk->light_switch);
613}
614
615static ssize_t store_lssw(struct device *dev, struct device_attribute *attr,
616 const char *buf, size_t count)
617{
618 int rv, value;
619
620 rv = parse_arg(buf, count, &value);
621 if (rv > 0)
622 set_light_sens_switch(value ? 1 : 0);
623
624 return rv;
625}
626
627static void set_light_sens_level(int value)
628{
629 if (!write_acpi_int(ls_level_handle, NULL, value, NULL))
630 printk(ASUS_WARNING "Error setting light sensor level\n");
631 hotk->light_level = value;
632}
633
634static ssize_t show_lslvl(struct device *dev,
635 struct device_attribute *attr, char *buf)
636{
637 return sprintf(buf, "%d\n", hotk->light_level);
638}
639
640static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
641 const char *buf, size_t count)
642{
643 int rv, value;
644
645 rv = parse_arg(buf, count, &value);
646 if (rv > 0) {
647 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
648 /* 0 <= value <= 15 */
649 set_light_sens_level(value);
650 }
651
652 return rv;
653}
654
655static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
656{
657 /* TODO Find a better way to handle events count. */
658 if (!hotk)
659 return;
660
661 /*
662 * We need to tell the backlight device when the backlight power is
663 * switched
664 */
665 if (event == ATKD_LCD_ON) {
666 write_status(NULL, 1, LCD_ON, 0);
667 lcd_blank(FB_BLANK_UNBLANK);
668 } else if (event == ATKD_LCD_OFF) {
669 write_status(NULL, 0, LCD_ON, 0);
670 lcd_blank(FB_BLANK_POWERDOWN);
671 }
672
673 acpi_bus_generate_event(hotk->device, event,
674 hotk->event_count[event % 128]++);
675
676 return;
677}
678
679#define ASUS_CREATE_DEVICE_ATTR(_name) \
680 struct device_attribute dev_attr_##_name = { \
681 .attr = { \
682 .name = __stringify(_name), \
683 .mode = 0, \
684 .owner = THIS_MODULE }, \
685 .show = NULL, \
686 .store = NULL, \
687 }
688
689#define ASUS_SET_DEVICE_ATTR(_name, _mode, _show, _store) \
690 do { \
691 dev_attr_##_name.attr.mode = _mode; \
692 dev_attr_##_name.show = _show; \
693 dev_attr_##_name.store = _store; \
694 } while(0)
695
696static ASUS_CREATE_DEVICE_ATTR(infos);
697static ASUS_CREATE_DEVICE_ATTR(wlan);
698static ASUS_CREATE_DEVICE_ATTR(bluetooth);
699static ASUS_CREATE_DEVICE_ATTR(display);
700static ASUS_CREATE_DEVICE_ATTR(ledd);
701static ASUS_CREATE_DEVICE_ATTR(ls_switch);
702static ASUS_CREATE_DEVICE_ATTR(ls_level);
703
704static struct attribute *asuspf_attributes[] = {
705 &dev_attr_infos.attr,
706 &dev_attr_wlan.attr,
707 &dev_attr_bluetooth.attr,
708 &dev_attr_display.attr,
709 &dev_attr_ledd.attr,
710 &dev_attr_ls_switch.attr,
711 &dev_attr_ls_level.attr,
712 NULL
713};
714
715static struct attribute_group asuspf_attribute_group = {
716 .attrs = asuspf_attributes
717};
718
719static struct platform_driver asuspf_driver = {
720 .driver = {
721 .name = ASUS_HOTK_FILE,
722 .owner = THIS_MODULE,
723 }
724};
725
726static struct platform_device *asuspf_device;
727
728static void asus_hotk_add_fs(void)
729{
730 ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL);
731
732 if (wl_switch_handle)
733 ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan);
734
735 if (bt_switch_handle)
736 ASUS_SET_DEVICE_ATTR(bluetooth, 0644,
737 show_bluetooth, store_bluetooth);
738
739 if (display_set_handle && display_get_handle)
740 ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp);
741 else if (display_set_handle)
742 ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp);
743
744 if (ledd_set_handle)
745 ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd);
746
747 if (ls_switch_handle && ls_level_handle) {
748 ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl);
749 ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw);
750 }
751}
752
753static int asus_handle_init(char *name, acpi_handle * handle,
754 char **paths, int num_paths)
755{
756 int i;
757 acpi_status status;
758
759 for (i = 0; i < num_paths; i++) {
760 status = acpi_get_handle(NULL, paths[i], handle);
761 if (ACPI_SUCCESS(status))
762 return 0;
763 }
764
765 *handle = NULL;
766 return -ENODEV;
767}
768
769#define ASUS_HANDLE_INIT(object) \
770 asus_handle_init(#object, &object##_handle, object##_paths, \
771 ARRAY_SIZE(object##_paths))
772
773/*
774 * This function is used to initialize the hotk with right values. In this
775 * method, we can make all the detection we want, and modify the hotk struct
776 */
777static int asus_hotk_get_info(void)
778{
779 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
780 union acpi_object *model = NULL;
781 int bsts_result, hwrs_result;
782 char *string = NULL;
783 acpi_status status;
784
785 /*
786 * Get DSDT headers early enough to allow for differentiating between
787 * models, but late enough to allow acpi_bus_register_driver() to fail
788 * before doing anything ACPI-specific. Should we encounter a machine,
789 * which needs special handling (i.e. its hotkey device has a different
790 * HID), this bit will be moved. A global variable asus_info contains
791 * the DSDT header.
792 */
793 status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
794 if (ACPI_FAILURE(status))
795 printk(ASUS_WARNING "Couldn't get the DSDT table header\n");
796
797 /* We have to write 0 on init this far for all ASUS models */
798 if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
799 printk(ASUS_ERR "Hotkey initialization failed\n");
800 return -ENODEV;
801 }
802
803 /* This needs to be called for some laptops to init properly */
804 if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result, NULL))
805 printk(ASUS_WARNING "Error calling BSTS\n");
806 else if (bsts_result)
807 printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n",
808 bsts_result);
809
810 /*
811 * Try to match the object returned by INIT to the specific model.
812 * Handle every possible object (or the lack of thereof) the DSDT
813 * writers might throw at us. When in trouble, we pass NULL to
814 * asus_model_match() and try something completely different.
815 */
816 if (buffer.pointer) {
817 model = buffer.pointer;
818 switch (model->type) {
819 case ACPI_TYPE_STRING:
820 string = model->string.pointer;
821 break;
822 case ACPI_TYPE_BUFFER:
823 string = model->buffer.pointer;
824 break;
825 default:
826 string = "";
827 break;
828 }
829 }
830 hotk->name = kstrdup(string, GFP_KERNEL);
831 if (!hotk->name)
832 return -ENOMEM;
833
834 if (*string)
835 printk(ASUS_NOTICE " %s model detected\n", string);
836
837 ASUS_HANDLE_INIT(mled_set);
838 ASUS_HANDLE_INIT(tled_set);
839 ASUS_HANDLE_INIT(rled_set);
840 ASUS_HANDLE_INIT(pled_set);
841
842 ASUS_HANDLE_INIT(ledd_set);
843
844 /*
845 * The HWRS method return informations about the hardware.
846 * 0x80 bit is for WLAN, 0x100 for Bluetooth.
847 * The significance of others is yet to be found.
848 * If we don't find the method, we assume the device are present.
849 */
850 if (!read_acpi_int(hotk->handle, "HRWS", &hwrs_result, NULL))
851 hwrs_result = WL_HWRS | BT_HWRS;
852
853 if (hwrs_result & WL_HWRS)
854 ASUS_HANDLE_INIT(wl_switch);
855 if (hwrs_result & BT_HWRS)
856 ASUS_HANDLE_INIT(bt_switch);
857
858 ASUS_HANDLE_INIT(wireless_status);
859
860 ASUS_HANDLE_INIT(brightness_set);
861 ASUS_HANDLE_INIT(brightness_get);
862
863 ASUS_HANDLE_INIT(lcd_switch);
864
865 ASUS_HANDLE_INIT(display_set);
866 ASUS_HANDLE_INIT(display_get);
867
868 /* There is a lot of models with "ALSL", but a few get
869 a real light sens, so we need to check it. */
870 if (ASUS_HANDLE_INIT(ls_switch))
871 ASUS_HANDLE_INIT(ls_level);
872
873 kfree(model);
874
875 return AE_OK;
876}
877
878static int asus_hotk_check(void)
879{
880 int result = 0;
881
882 result = acpi_bus_get_status(hotk->device);
883 if (result)
884 return result;
885
886 if (hotk->device->status.present) {
887 result = asus_hotk_get_info();
888 } else {
889 printk(ASUS_ERR "Hotkey device not present, aborting\n");
890 return -EINVAL;
891 }
892
893 return result;
894}
895
896static int asus_hotk_found;
897
898static int asus_hotk_add(struct acpi_device *device)
899{
900 acpi_status status = AE_OK;
901 int result;
902
903 if (!device)
904 return -EINVAL;
905
906 printk(ASUS_NOTICE "Asus Laptop Support version %s\n",
907 ASUS_LAPTOP_VERSION);
908
909 hotk = kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
910 if (!hotk)
911 return -ENOMEM;
912 memset(hotk, 0, sizeof(struct asus_hotk));
913
914 hotk->handle = device->handle;
915 strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
916 strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
917 acpi_driver_data(device) = hotk;
918 hotk->device = device;
919
920 result = asus_hotk_check();
921 if (result)
922 goto end;
923
924 asus_hotk_add_fs();
925
926 /*
927 * We install the handler, it will receive the hotk in parameter, so, we
928 * could add other data to the hotk struct
929 */
930 status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
931 asus_hotk_notify, hotk);
932 if (ACPI_FAILURE(status))
933 printk(ASUS_ERR "Error installing notify handler\n");
934
935 asus_hotk_found = 1;
936
937 /* WLED and BLED are on by default */
938 write_status(bt_switch_handle, 1, BT_ON, 0);
939 write_status(wl_switch_handle, 1, WL_ON, 0);
940
941 /* LCD Backlight is on by default */
942 write_status(NULL, 1, LCD_ON, 0);
943
944 /* LED display is off by default */
945 hotk->ledd_status = 0xFFF;
946
947 /* Set initial values of light sensor and level */
948 hotk->light_switch = 1; /* Default to light sensor disabled */
949 hotk->light_level = 0; /* level 5 for sensor sensitivity */
950
951 if (ls_switch_handle)
952 set_light_sens_switch(hotk->light_switch);
953
954 if (ls_level_handle)
955 set_light_sens_level(hotk->light_level);
956
957 end:
958 if (result) {
959 kfree(hotk->name);
960 kfree(hotk);
961 }
962
963 return result;
964}
965
966static int asus_hotk_remove(struct acpi_device *device, int type)
967{
968 acpi_status status = 0;
969
970 if (!device || !acpi_driver_data(device))
971 return -EINVAL;
972
973 status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
974 asus_hotk_notify);
975 if (ACPI_FAILURE(status))
976 printk(ASUS_ERR "Error removing notify handler\n");
977
978 kfree(hotk->name);
979 kfree(hotk);
980
981 return 0;
982}
983
984static void asus_backlight_exit(void)
985{
986 if (asus_backlight_device)
987 backlight_device_unregister(asus_backlight_device);
988}
989
990#define ASUS_LED_UNREGISTER(object) \
991 if(object##_led.class_dev \
992 && !IS_ERR(object##_led.class_dev)) \
993 led_classdev_unregister(&object##_led)
994
995static void asus_led_exit(void)
996{
997 ASUS_LED_UNREGISTER(mled);
998 ASUS_LED_UNREGISTER(tled);
999 ASUS_LED_UNREGISTER(pled);
1000 ASUS_LED_UNREGISTER(rled);
1001
1002 destroy_workqueue(led_workqueue);
1003}
1004
1005static void __exit asus_laptop_exit(void)
1006{
1007 asus_backlight_exit();
1008 asus_led_exit();
1009
1010 acpi_bus_unregister_driver(&asus_hotk_driver);
1011 sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
1012 platform_device_unregister(asuspf_device);
1013 platform_driver_unregister(&asuspf_driver);
1014}
1015
1016static int asus_backlight_init(struct device *dev)
1017{
1018 struct backlight_device *bd;
1019
1020 if (brightness_set_handle && lcd_switch_handle) {
1021 bd = backlight_device_register(ASUS_HOTK_FILE, dev,
1022 NULL, &asusbl_data);
1023 if (IS_ERR(bd)) {
1024 printk(ASUS_ERR
1025 "Could not register asus backlight device\n");
1026 asus_backlight_device = NULL;
1027 return PTR_ERR(bd);
1028 }
1029
1030 asus_backlight_device = bd;
1031
1032 down(&bd->sem);
1033 if (likely(bd->props)) {
1034 bd->props->brightness = read_brightness(NULL);
1035 bd->props->power = FB_BLANK_UNBLANK;
1036 if (likely(bd->props->update_status))
1037 bd->props->update_status(bd);
1038 }
1039 up(&bd->sem);
1040 }
1041 return 0;
1042}
1043
1044static int asus_led_register(acpi_handle handle,
1045 struct led_classdev *ldev, struct device *dev)
1046{
1047 if (!handle)
1048 return 0;
1049
1050 return led_classdev_register(dev, ldev);
1051}
1052
1053#define ASUS_LED_REGISTER(object, device) \
1054 asus_led_register(object##_set_handle, &object##_led, device)
1055
1056static int asus_led_init(struct device *dev)
1057{
1058 int rv;
1059
1060 rv = ASUS_LED_REGISTER(mled, dev);
1061 if (rv)
1062 return rv;
1063
1064 rv = ASUS_LED_REGISTER(tled, dev);
1065 if (rv)
1066 return rv;
1067
1068 rv = ASUS_LED_REGISTER(rled, dev);
1069 if (rv)
1070 return rv;
1071
1072 rv = ASUS_LED_REGISTER(pled, dev);
1073 if (rv)
1074 return rv;
1075
1076 led_workqueue = create_singlethread_workqueue("led_workqueue");
1077 if (!led_workqueue)
1078 return -ENOMEM;
1079
1080 return 0;
1081}
1082
1083static int __init asus_laptop_init(void)
1084{
1085 struct device *dev;
1086 int result;
1087
1088 if (acpi_disabled)
1089 return -ENODEV;
1090
1091 if (!acpi_specific_hotkey_enabled) {
1092 printk(ASUS_ERR "Using generic hotkey driver\n");
1093 return -ENODEV;
1094 }
1095
1096 result = acpi_bus_register_driver(&asus_hotk_driver);
1097 if (result < 0)
1098 return result;
1099
1100 /*
1101 * This is a bit of a kludge. We only want this module loaded
1102 * for ASUS systems, but there's currently no way to probe the
1103 * ACPI namespace for ASUS HIDs. So we just return failure if
1104 * we didn't find one, which will cause the module to be
1105 * unloaded.
1106 */
1107 if (!asus_hotk_found) {
1108 acpi_bus_unregister_driver(&asus_hotk_driver);
1109 return -ENODEV;
1110 }
1111
1112 dev = acpi_get_physical_device(hotk->device->handle);
1113
1114 result = asus_backlight_init(dev);
1115 if (result)
1116 goto fail_backlight;
1117
1118 result = asus_led_init(dev);
1119 if (result)
1120 goto fail_led;
1121
1122 /* Register platform stuff */
1123 result = platform_driver_register(&asuspf_driver);
1124 if (result)
1125 goto fail_platform_driver;
1126
1127 asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
1128 if (!asuspf_device) {
1129 result = -ENOMEM;
1130 goto fail_platform_device1;
1131 }
1132
1133 result = platform_device_add(asuspf_device);
1134 if (result)
1135 goto fail_platform_device2;
1136
1137 result = sysfs_create_group(&asuspf_device->dev.kobj,
1138 &asuspf_attribute_group);
1139 if (result)
1140 goto fail_sysfs;
1141
1142 return 0;
1143
1144 fail_sysfs:
1145 platform_device_del(asuspf_device);
1146
1147 fail_platform_device2:
1148 platform_device_put(asuspf_device);
1149
1150 fail_platform_device1:
1151 platform_driver_unregister(&asuspf_driver);
1152
1153 fail_platform_driver:
1154 asus_led_exit();
1155
1156 fail_led:
1157 asus_backlight_exit();
1158
1159 fail_backlight:
1160
1161 return result;
1162}
1163
1164module_init(asus_laptop_init);
1165module_exit(asus_laptop_exit);
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index 2ab7add78f94..e21e490fedb0 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -11,66 +11,25 @@
11 11
12#include <linux/tifm.h> 12#include <linux/tifm.h>
13#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
14#include <linux/freezer.h>
14 15
15#define DRIVER_NAME "tifm_7xx1" 16#define DRIVER_NAME "tifm_7xx1"
16#define DRIVER_VERSION "0.6" 17#define DRIVER_VERSION "0.7"
17 18
18static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) 19static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
19{ 20{
20 int cnt;
21 unsigned long flags;
22
23 spin_lock_irqsave(&fm->lock, flags);
24 if (!fm->inhibit_new_cards) {
25 for (cnt = 0; cnt < fm->max_sockets; cnt++) {
26 if (fm->sockets[cnt] == sock) {
27 fm->remove_mask |= (1 << cnt);
28 queue_work(fm->wq, &fm->media_remover);
29 break;
30 }
31 }
32 }
33 spin_unlock_irqrestore(&fm->lock, flags);
34}
35
36static void tifm_7xx1_remove_media(struct work_struct *work)
37{
38 struct tifm_adapter *fm =
39 container_of(work, struct tifm_adapter, media_remover);
40 unsigned long flags; 21 unsigned long flags;
41 int cnt;
42 struct tifm_dev *sock;
43 22
44 if (!class_device_get(&fm->cdev))
45 return;
46 spin_lock_irqsave(&fm->lock, flags); 23 spin_lock_irqsave(&fm->lock, flags);
47 for (cnt = 0; cnt < fm->max_sockets; cnt++) { 24 fm->socket_change_set |= 1 << sock->socket_id;
48 if (fm->sockets[cnt] && (fm->remove_mask & (1 << cnt))) { 25 wake_up_all(&fm->change_set_notify);
49 printk(KERN_INFO DRIVER_NAME
50 ": demand removing card from socket %d\n", cnt);
51 sock = fm->sockets[cnt];
52 fm->sockets[cnt] = NULL;
53 fm->remove_mask &= ~(1 << cnt);
54
55 writel(0x0e00, sock->addr + SOCK_CONTROL);
56
57 writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
58 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
59 writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
60 fm->addr + FM_SET_INTERRUPT_ENABLE);
61
62 spin_unlock_irqrestore(&fm->lock, flags);
63 device_unregister(&sock->dev);
64 spin_lock_irqsave(&fm->lock, flags);
65 }
66 }
67 spin_unlock_irqrestore(&fm->lock, flags); 26 spin_unlock_irqrestore(&fm->lock, flags);
68 class_device_put(&fm->cdev);
69} 27}
70 28
71static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) 29static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
72{ 30{
73 struct tifm_adapter *fm = dev_id; 31 struct tifm_adapter *fm = dev_id;
32 struct tifm_dev *sock;
74 unsigned int irq_status; 33 unsigned int irq_status;
75 unsigned int sock_irq_status, cnt; 34 unsigned int sock_irq_status, cnt;
76 35
@@ -84,42 +43,32 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
84 if (irq_status & TIFM_IRQ_ENABLE) { 43 if (irq_status & TIFM_IRQ_ENABLE) {
85 writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 44 writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
86 45
87 for (cnt = 0; cnt < fm->max_sockets; cnt++) { 46 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
88 sock_irq_status = (irq_status >> cnt) & 47 sock = fm->sockets[cnt];
89 (TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK); 48 sock_irq_status = (irq_status >> cnt)
90 49 & (TIFM_IRQ_FIFOMASK(1)
91 if (fm->sockets[cnt]) { 50 | TIFM_IRQ_CARDMASK(1));
92 if (sock_irq_status &&
93 fm->sockets[cnt]->signal_irq)
94 sock_irq_status = fm->sockets[cnt]->
95 signal_irq(fm->sockets[cnt],
96 sock_irq_status);
97 51
98 if (irq_status & (1 << cnt)) 52 if (sock && sock_irq_status)
99 fm->remove_mask |= 1 << cnt; 53 sock->signal_irq(sock, sock_irq_status);
100 } else {
101 if (irq_status & (1 << cnt))
102 fm->insert_mask |= 1 << cnt;
103 }
104 } 54 }
55
56 fm->socket_change_set |= irq_status
57 & ((1 << fm->num_sockets) - 1);
105 } 58 }
106 writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); 59 writel(irq_status, fm->addr + FM_INTERRUPT_STATUS);
107 60
108 if (!fm->inhibit_new_cards) { 61 if (!fm->socket_change_set)
109 if (!fm->remove_mask && !fm->insert_mask) { 62 writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
110 writel(TIFM_IRQ_ENABLE, 63 else
111 fm->addr + FM_SET_INTERRUPT_ENABLE); 64 wake_up_all(&fm->change_set_notify);
112 } else {
113 queue_work(fm->wq, &fm->media_remover);
114 queue_work(fm->wq, &fm->media_inserter);
115 }
116 }
117 65
118 spin_unlock(&fm->lock); 66 spin_unlock(&fm->lock);
119 return IRQ_HANDLED; 67 return IRQ_HANDLED;
120} 68}
121 69
122static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is_x2) 70static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr,
71 int is_x2)
123{ 72{
124 unsigned int s_state; 73 unsigned int s_state;
125 int cnt; 74 int cnt;
@@ -127,8 +76,8 @@ static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is
127 writel(0x0e00, sock_addr + SOCK_CONTROL); 76 writel(0x0e00, sock_addr + SOCK_CONTROL);
128 77
129 for (cnt = 0; cnt < 100; cnt++) { 78 for (cnt = 0; cnt < 100; cnt++) {
130 if (!(TIFM_SOCK_STATE_POWERED & 79 if (!(TIFM_SOCK_STATE_POWERED
131 readl(sock_addr + SOCK_PRESENT_STATE))) 80 & readl(sock_addr + SOCK_PRESENT_STATE)))
132 break; 81 break;
133 msleep(10); 82 msleep(10);
134 } 83 }
@@ -151,8 +100,8 @@ static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is
151 } 100 }
152 101
153 for (cnt = 0; cnt < 100; cnt++) { 102 for (cnt = 0; cnt < 100; cnt++) {
154 if ((TIFM_SOCK_STATE_POWERED & 103 if ((TIFM_SOCK_STATE_POWERED
155 readl(sock_addr + SOCK_PRESENT_STATE))) 104 & readl(sock_addr + SOCK_PRESENT_STATE)))
156 break; 105 break;
157 msleep(10); 106 msleep(10);
158 } 107 }
@@ -170,130 +119,209 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
170 return base_addr + ((sock_num + 1) << 10); 119 return base_addr + ((sock_num + 1) << 10);
171} 120}
172 121
173static void tifm_7xx1_insert_media(struct work_struct *work) 122static int tifm_7xx1_switch_media(void *data)
174{ 123{
175 struct tifm_adapter *fm = 124 struct tifm_adapter *fm = data;
176 container_of(work, struct tifm_adapter, media_inserter);
177 unsigned long flags; 125 unsigned long flags;
178 tifm_media_id media_id; 126 tifm_media_id media_id;
179 char *card_name = "xx"; 127 char *card_name = "xx";
180 int cnt, ok_to_register; 128 int cnt, rc;
181 unsigned int insert_mask; 129 struct tifm_dev *sock;
182 struct tifm_dev *new_sock = NULL; 130 unsigned int socket_change_set;
183 131
184 if (!class_device_get(&fm->cdev)) 132 while (1) {
185 return; 133 rc = wait_event_interruptible(fm->change_set_notify,
186 spin_lock_irqsave(&fm->lock, flags); 134 fm->socket_change_set);
187 insert_mask = fm->insert_mask; 135 if (rc == -ERESTARTSYS)
188 fm->insert_mask = 0; 136 try_to_freeze();
189 if (fm->inhibit_new_cards) { 137
138 spin_lock_irqsave(&fm->lock, flags);
139 socket_change_set = fm->socket_change_set;
140 fm->socket_change_set = 0;
141
142 dev_dbg(fm->dev, "checking media set %x\n",
143 socket_change_set);
144
145 if (kthread_should_stop())
146 socket_change_set = (1 << fm->num_sockets) - 1;
190 spin_unlock_irqrestore(&fm->lock, flags); 147 spin_unlock_irqrestore(&fm->lock, flags);
191 class_device_put(&fm->cdev);
192 return;
193 }
194 spin_unlock_irqrestore(&fm->lock, flags);
195 148
196 for (cnt = 0; cnt < fm->max_sockets; cnt++) { 149 if (!socket_change_set)
197 if (!(insert_mask & (1 << cnt)))
198 continue; 150 continue;
199 151
200 media_id = tifm_7xx1_toggle_sock_power(tifm_7xx1_sock_addr(fm->addr, cnt), 152 spin_lock_irqsave(&fm->lock, flags);
201 fm->max_sockets == 2); 153 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
202 if (media_id) { 154 if (!(socket_change_set & (1 << cnt)))
203 ok_to_register = 0; 155 continue;
204 new_sock = tifm_alloc_device(fm, cnt); 156 sock = fm->sockets[cnt];
205 if (new_sock) { 157 if (sock) {
206 new_sock->addr = tifm_7xx1_sock_addr(fm->addr,
207 cnt);
208 new_sock->media_id = media_id;
209 switch (media_id) {
210 case 1:
211 card_name = "xd";
212 break;
213 case 2:
214 card_name = "ms";
215 break;
216 case 3:
217 card_name = "sd";
218 break;
219 default:
220 break;
221 }
222 snprintf(new_sock->dev.bus_id, BUS_ID_SIZE,
223 "tifm_%s%u:%u", card_name, fm->id, cnt);
224 printk(KERN_INFO DRIVER_NAME 158 printk(KERN_INFO DRIVER_NAME
225 ": %s card detected in socket %d\n", 159 ": demand removing card from socket %d\n",
226 card_name, cnt); 160 cnt);
161 fm->sockets[cnt] = NULL;
162 spin_unlock_irqrestore(&fm->lock, flags);
163 device_unregister(&sock->dev);
227 spin_lock_irqsave(&fm->lock, flags); 164 spin_lock_irqsave(&fm->lock, flags);
228 if (!fm->sockets[cnt]) { 165 writel(0x0e00,
229 fm->sockets[cnt] = new_sock; 166 tifm_7xx1_sock_addr(fm->addr, cnt)
230 ok_to_register = 1; 167 + SOCK_CONTROL);
168 }
169 if (kthread_should_stop())
170 continue;
171
172 spin_unlock_irqrestore(&fm->lock, flags);
173 media_id = tifm_7xx1_toggle_sock_power(
174 tifm_7xx1_sock_addr(fm->addr, cnt),
175 fm->num_sockets == 2);
176 if (media_id) {
177 sock = tifm_alloc_device(fm);
178 if (sock) {
179 sock->addr = tifm_7xx1_sock_addr(fm->addr,
180 cnt);
181 sock->media_id = media_id;
182 sock->socket_id = cnt;
183 switch (media_id) {
184 case 1:
185 card_name = "xd";
186 break;
187 case 2:
188 card_name = "ms";
189 break;
190 case 3:
191 card_name = "sd";
192 break;
193 default:
194 tifm_free_device(&sock->dev);
195 spin_lock_irqsave(&fm->lock, flags);
196 continue;
197 }
198 snprintf(sock->dev.bus_id, BUS_ID_SIZE,
199 "tifm_%s%u:%u", card_name,
200 fm->id, cnt);
201 printk(KERN_INFO DRIVER_NAME
202 ": %s card detected in socket %d\n",
203 card_name, cnt);
204 if (!device_register(&sock->dev)) {
205 spin_lock_irqsave(&fm->lock, flags);
206 if (!fm->sockets[cnt]) {
207 fm->sockets[cnt] = sock;
208 sock = NULL;
209 }
210 spin_unlock_irqrestore(&fm->lock, flags);
211 }
212 if (sock)
213 tifm_free_device(&sock->dev);
231 } 214 }
215 spin_lock_irqsave(&fm->lock, flags);
216 }
217 }
218
219 if (!kthread_should_stop()) {
220 writel(TIFM_IRQ_FIFOMASK(socket_change_set)
221 | TIFM_IRQ_CARDMASK(socket_change_set),
222 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
223 writel(TIFM_IRQ_FIFOMASK(socket_change_set)
224 | TIFM_IRQ_CARDMASK(socket_change_set),
225 fm->addr + FM_SET_INTERRUPT_ENABLE);
226 writel(TIFM_IRQ_ENABLE,
227 fm->addr + FM_SET_INTERRUPT_ENABLE);
228 spin_unlock_irqrestore(&fm->lock, flags);
229 } else {
230 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
231 if (fm->sockets[cnt])
232 fm->socket_change_set |= 1 << cnt;
233 }
234 if (!fm->socket_change_set) {
235 spin_unlock_irqrestore(&fm->lock, flags);
236 return 0;
237 } else {
232 spin_unlock_irqrestore(&fm->lock, flags); 238 spin_unlock_irqrestore(&fm->lock, flags);
233 if (!ok_to_register ||
234 device_register(&new_sock->dev)) {
235 spin_lock_irqsave(&fm->lock, flags);
236 fm->sockets[cnt] = NULL;
237 spin_unlock_irqrestore(&fm->lock,
238 flags);
239 tifm_free_device(&new_sock->dev);
240 }
241 } 239 }
242 } 240 }
243 writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
244 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
245 writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
246 fm->addr + FM_SET_INTERRUPT_ENABLE);
247 } 241 }
248 242 return 0;
249 writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
250 class_device_put(&fm->cdev);
251} 243}
252 244
245#ifdef CONFIG_PM
246
253static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) 247static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
254{ 248{
255 struct tifm_adapter *fm = pci_get_drvdata(dev); 249 dev_dbg(&dev->dev, "suspending host\n");
256 unsigned long flags;
257 250
258 spin_lock_irqsave(&fm->lock, flags); 251 pci_save_state(dev);
259 fm->inhibit_new_cards = 1; 252 pci_enable_wake(dev, pci_choose_state(dev, state), 0);
260 fm->remove_mask = 0xf; 253 pci_disable_device(dev);
261 fm->insert_mask = 0; 254 pci_set_power_state(dev, pci_choose_state(dev, state));
262 writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
263 spin_unlock_irqrestore(&fm->lock, flags);
264 flush_workqueue(fm->wq);
265
266 tifm_7xx1_remove_media(&fm->media_remover);
267
268 pci_set_power_state(dev, PCI_D3hot);
269 pci_disable_device(dev);
270 pci_save_state(dev);
271 return 0; 255 return 0;
272} 256}
273 257
274static int tifm_7xx1_resume(struct pci_dev *dev) 258static int tifm_7xx1_resume(struct pci_dev *dev)
275{ 259{
276 struct tifm_adapter *fm = pci_get_drvdata(dev); 260 struct tifm_adapter *fm = pci_get_drvdata(dev);
261 int cnt, rc;
277 unsigned long flags; 262 unsigned long flags;
263 tifm_media_id new_ids[fm->num_sockets];
278 264
265 pci_set_power_state(dev, PCI_D0);
279 pci_restore_state(dev); 266 pci_restore_state(dev);
280 pci_enable_device(dev); 267 rc = pci_enable_device(dev);
281 pci_set_power_state(dev, PCI_D0); 268 if (rc)
282 pci_set_master(dev); 269 return rc;
270 pci_set_master(dev);
283 271
272 dev_dbg(&dev->dev, "resuming host\n");
273
274 for (cnt = 0; cnt < fm->num_sockets; cnt++)
275 new_ids[cnt] = tifm_7xx1_toggle_sock_power(
276 tifm_7xx1_sock_addr(fm->addr, cnt),
277 fm->num_sockets == 2);
284 spin_lock_irqsave(&fm->lock, flags); 278 spin_lock_irqsave(&fm->lock, flags);
285 fm->inhibit_new_cards = 0; 279 fm->socket_change_set = 0;
286 writel(TIFM_IRQ_SETALL, fm->addr + FM_INTERRUPT_STATUS); 280 for (cnt = 0; cnt < fm->num_sockets; cnt++) {
287 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 281 if (fm->sockets[cnt]) {
288 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK, 282 if (fm->sockets[cnt]->media_id == new_ids[cnt])
289 fm->addr + FM_SET_INTERRUPT_ENABLE); 283 fm->socket_change_set |= 1 << cnt;
290 fm->insert_mask = 0xf; 284
285 fm->sockets[cnt]->media_id = new_ids[cnt];
286 }
287 }
288
289 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
290 fm->addr + FM_SET_INTERRUPT_ENABLE);
291 if (!fm->socket_change_set) {
292 spin_unlock_irqrestore(&fm->lock, flags);
293 return 0;
294 } else {
295 fm->socket_change_set = 0;
296 spin_unlock_irqrestore(&fm->lock, flags);
297 }
298
299 wait_event_timeout(fm->change_set_notify, fm->socket_change_set, HZ);
300
301 spin_lock_irqsave(&fm->lock, flags);
302 writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set)
303 | TIFM_IRQ_CARDMASK(fm->socket_change_set),
304 fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
305 writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set)
306 | TIFM_IRQ_CARDMASK(fm->socket_change_set),
307 fm->addr + FM_SET_INTERRUPT_ENABLE);
308 writel(TIFM_IRQ_ENABLE,
309 fm->addr + FM_SET_INTERRUPT_ENABLE);
310 fm->socket_change_set = 0;
311
291 spin_unlock_irqrestore(&fm->lock, flags); 312 spin_unlock_irqrestore(&fm->lock, flags);
292 return 0; 313 return 0;
293} 314}
294 315
316#else
317
318#define tifm_7xx1_suspend NULL
319#define tifm_7xx1_resume NULL
320
321#endif /* CONFIG_PM */
322
295static int tifm_7xx1_probe(struct pci_dev *dev, 323static int tifm_7xx1_probe(struct pci_dev *dev,
296 const struct pci_device_id *dev_id) 324 const struct pci_device_id *dev_id)
297{ 325{
298 struct tifm_adapter *fm; 326 struct tifm_adapter *fm;
299 int pci_dev_busy = 0; 327 int pci_dev_busy = 0;
@@ -324,19 +352,18 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
324 } 352 }
325 353
326 fm->dev = &dev->dev; 354 fm->dev = &dev->dev;
327 fm->max_sockets = (dev->device == 0x803B) ? 2 : 4; 355 fm->num_sockets = (dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM)
328 fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->max_sockets, 356 ? 4 : 2;
329 GFP_KERNEL); 357 fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->num_sockets,
358 GFP_KERNEL);
330 if (!fm->sockets) 359 if (!fm->sockets)
331 goto err_out_free; 360 goto err_out_free;
332 361
333 INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media);
334 INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media);
335 fm->eject = tifm_7xx1_eject; 362 fm->eject = tifm_7xx1_eject;
336 pci_set_drvdata(dev, fm); 363 pci_set_drvdata(dev, fm);
337 364
338 fm->addr = ioremap(pci_resource_start(dev, 0), 365 fm->addr = ioremap(pci_resource_start(dev, 0),
339 pci_resource_len(dev, 0)); 366 pci_resource_len(dev, 0));
340 if (!fm->addr) 367 if (!fm->addr)
341 goto err_out_free; 368 goto err_out_free;
342 369
@@ -344,16 +371,15 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
344 if (rc) 371 if (rc)
345 goto err_out_unmap; 372 goto err_out_unmap;
346 373
347 rc = tifm_add_adapter(fm); 374 init_waitqueue_head(&fm->change_set_notify);
375 rc = tifm_add_adapter(fm, tifm_7xx1_switch_media);
348 if (rc) 376 if (rc)
349 goto err_out_irq; 377 goto err_out_irq;
350 378
351 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); 379 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
352 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK, 380 writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
353 fm->addr + FM_SET_INTERRUPT_ENABLE); 381 fm->addr + FM_SET_INTERRUPT_ENABLE);
354 382 wake_up_process(fm->media_switcher);
355 fm->insert_mask = 0xf;
356
357 return 0; 383 return 0;
358 384
359err_out_irq: 385err_out_irq:
@@ -377,19 +403,15 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
377 struct tifm_adapter *fm = pci_get_drvdata(dev); 403 struct tifm_adapter *fm = pci_get_drvdata(dev);
378 unsigned long flags; 404 unsigned long flags;
379 405
406 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
407 mmiowb();
408 free_irq(dev->irq, fm);
409
380 spin_lock_irqsave(&fm->lock, flags); 410 spin_lock_irqsave(&fm->lock, flags);
381 fm->inhibit_new_cards = 1; 411 fm->socket_change_set = (1 << fm->num_sockets) - 1;
382 fm->remove_mask = 0xf;
383 fm->insert_mask = 0;
384 writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
385 spin_unlock_irqrestore(&fm->lock, flags); 412 spin_unlock_irqrestore(&fm->lock, flags);
386 413
387 flush_workqueue(fm->wq); 414 kthread_stop(fm->media_switcher);
388
389 tifm_7xx1_remove_media(&fm->media_remover);
390
391 writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
392 free_irq(dev->irq, fm);
393 415
394 tifm_remove_adapter(fm); 416 tifm_remove_adapter(fm);
395 417
@@ -404,10 +426,12 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
404} 426}
405 427
406static struct pci_device_id tifm_7xx1_pci_tbl [] = { 428static struct pci_device_id tifm_7xx1_pci_tbl [] = {
407 { PCI_VENDOR_ID_TI, 0x8033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 429 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11_FM, PCI_ANY_ID,
408 0 }, /* xx21 - the one I have */ 430 PCI_ANY_ID, 0, 0, 0 }, /* xx21 - the one I have */
409 { PCI_VENDOR_ID_TI, 0x803B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 431 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX12_FM, PCI_ANY_ID,
410 0 }, /* xx12 - should be also supported */ 432 PCI_ANY_ID, 0, 0, 0 },
433 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX20_FM, PCI_ANY_ID,
434 PCI_ANY_ID, 0, 0, 0 },
411 { } 435 { }
412}; 436};
413 437
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index d61df5c3ac36..6b10ebe9d936 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -14,7 +14,7 @@
14#include <linux/idr.h> 14#include <linux/idr.h>
15 15
16#define DRIVER_NAME "tifm_core" 16#define DRIVER_NAME "tifm_core"
17#define DRIVER_VERSION "0.6" 17#define DRIVER_VERSION "0.7"
18 18
19static DEFINE_IDR(tifm_adapter_idr); 19static DEFINE_IDR(tifm_adapter_idr);
20static DEFINE_SPINLOCK(tifm_adapter_lock); 20static DEFINE_SPINLOCK(tifm_adapter_lock);
@@ -60,10 +60,41 @@ static int tifm_uevent(struct device *dev, char **envp, int num_envp,
60 return 0; 60 return 0;
61} 61}
62 62
63#ifdef CONFIG_PM
64
65static int tifm_device_suspend(struct device *dev, pm_message_t state)
66{
67 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
68 struct tifm_driver *drv = fm_dev->drv;
69
70 if (drv && drv->suspend)
71 return drv->suspend(fm_dev, state);
72 return 0;
73}
74
75static int tifm_device_resume(struct device *dev)
76{
77 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
78 struct tifm_driver *drv = fm_dev->drv;
79
80 if (drv && drv->resume)
81 return drv->resume(fm_dev);
82 return 0;
83}
84
85#else
86
87#define tifm_device_suspend NULL
88#define tifm_device_resume NULL
89
90#endif /* CONFIG_PM */
91
63static struct bus_type tifm_bus_type = { 92static struct bus_type tifm_bus_type = {
64 .name = "tifm", 93 .name = "tifm",
65 .match = tifm_match, 94 .match = tifm_match,
66 .uevent = tifm_uevent, 95 .uevent = tifm_uevent,
96 .suspend = tifm_device_suspend,
97 .resume = tifm_device_resume
67}; 98};
68 99
69static void tifm_free(struct class_device *cdev) 100static void tifm_free(struct class_device *cdev)
@@ -71,8 +102,6 @@ static void tifm_free(struct class_device *cdev)
71 struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); 102 struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev);
72 103
73 kfree(fm->sockets); 104 kfree(fm->sockets);
74 if (fm->wq)
75 destroy_workqueue(fm->wq);
76 kfree(fm); 105 kfree(fm);
77} 106}
78 107
@@ -101,7 +130,8 @@ void tifm_free_adapter(struct tifm_adapter *fm)
101} 130}
102EXPORT_SYMBOL(tifm_free_adapter); 131EXPORT_SYMBOL(tifm_free_adapter);
103 132
104int tifm_add_adapter(struct tifm_adapter *fm) 133int tifm_add_adapter(struct tifm_adapter *fm,
134 int (*mediathreadfn)(void *data))
105{ 135{
106 int rc; 136 int rc;
107 137
@@ -113,10 +143,10 @@ int tifm_add_adapter(struct tifm_adapter *fm)
113 spin_unlock(&tifm_adapter_lock); 143 spin_unlock(&tifm_adapter_lock);
114 if (!rc) { 144 if (!rc) {
115 snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); 145 snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id);
116 strncpy(fm->wq_name, fm->cdev.class_id, KOBJ_NAME_LEN); 146 fm->media_switcher = kthread_create(mediathreadfn,
147 fm, "tifm/%u", fm->id);
117 148
118 fm->wq = create_singlethread_workqueue(fm->wq_name); 149 if (!IS_ERR(fm->media_switcher))
119 if (fm->wq)
120 return class_device_add(&fm->cdev); 150 return class_device_add(&fm->cdev);
121 151
122 spin_lock(&tifm_adapter_lock); 152 spin_lock(&tifm_adapter_lock);
@@ -141,27 +171,27 @@ EXPORT_SYMBOL(tifm_remove_adapter);
141void tifm_free_device(struct device *dev) 171void tifm_free_device(struct device *dev)
142{ 172{
143 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); 173 struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
144 if (fm_dev->wq)
145 destroy_workqueue(fm_dev->wq);
146 kfree(fm_dev); 174 kfree(fm_dev);
147} 175}
148EXPORT_SYMBOL(tifm_free_device); 176EXPORT_SYMBOL(tifm_free_device);
149 177
150struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) 178static void tifm_dummy_signal_irq(struct tifm_dev *sock,
179 unsigned int sock_irq_status)
180{
181 return;
182}
183
184struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm)
151{ 185{
152 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); 186 struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
153 187
154 if (dev) { 188 if (dev) {
155 spin_lock_init(&dev->lock); 189 spin_lock_init(&dev->lock);
156 snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id); 190
157 dev->wq = create_singlethread_workqueue(dev->wq_name);
158 if (!dev->wq) {
159 kfree(dev);
160 return NULL;
161 }
162 dev->dev.parent = fm->dev; 191 dev->dev.parent = fm->dev;
163 dev->dev.bus = &tifm_bus_type; 192 dev->dev.bus = &tifm_bus_type;
164 dev->dev.release = tifm_free_device; 193 dev->dev.release = tifm_free_device;
194 dev->signal_irq = tifm_dummy_signal_irq;
165 } 195 }
166 return dev; 196 return dev;
167} 197}
@@ -219,6 +249,7 @@ static int tifm_device_remove(struct device *dev)
219 struct tifm_driver *drv = fm_dev->drv; 249 struct tifm_driver *drv = fm_dev->drv;
220 250
221 if (drv) { 251 if (drv) {
252 fm_dev->signal_irq = tifm_dummy_signal_irq;
222 if (drv->remove) 253 if (drv->remove)
223 drv->remove(fm_dev); 254 drv->remove(fm_dev);
224 fm_dev->drv = NULL; 255 fm_dev->drv = NULL;
@@ -233,6 +264,8 @@ int tifm_register_driver(struct tifm_driver *drv)
233 drv->driver.bus = &tifm_bus_type; 264 drv->driver.bus = &tifm_bus_type;
234 drv->driver.probe = tifm_device_probe; 265 drv->driver.probe = tifm_device_probe;
235 drv->driver.remove = tifm_device_remove; 266 drv->driver.remove = tifm_device_remove;
267 drv->driver.suspend = tifm_device_suspend;
268 drv->driver.resume = tifm_device_resume;
236 269
237 return driver_register(&drv->driver); 270 return driver_register(&drv->driver);
238} 271}
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index aa152f31851e..2ce50f38e3c7 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -823,6 +823,9 @@ static int __init at91_mci_probe(struct platform_device *pdev)
823 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 823 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
824 mmc->caps = MMC_CAP_BYTEBLOCK; 824 mmc->caps = MMC_CAP_BYTEBLOCK;
825 825
826 mmc->max_blk_size = 4095;
827 mmc->max_blk_count = mmc->max_req_size;
828
826 host = mmc_priv(mmc); 829 host = mmc_priv(mmc);
827 host->mmc = mmc; 830 host->mmc = mmc;
828 host->buffer = NULL; 831 host->buffer = NULL;
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 800527cf40d5..b834be261ab7 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -152,8 +152,9 @@ static inline int au1xmmc_card_inserted(struct au1xmmc_host *host)
152 ? 1 : 0; 152 ? 1 : 0;
153} 153}
154 154
155static inline int au1xmmc_card_readonly(struct au1xmmc_host *host) 155static int au1xmmc_card_readonly(struct mmc_host *mmc)
156{ 156{
157 struct au1xmmc_host *host = mmc_priv(mmc);
157 return (bcsr->status & au1xmmc_card_table[host->id].wpstatus) 158 return (bcsr->status & au1xmmc_card_table[host->id].wpstatus)
158 ? 1 : 0; 159 ? 1 : 0;
159} 160}
@@ -193,6 +194,8 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
193 u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); 194 u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
194 195
195 switch (mmc_resp_type(cmd)) { 196 switch (mmc_resp_type(cmd)) {
197 case MMC_RSP_NONE:
198 break;
196 case MMC_RSP_R1: 199 case MMC_RSP_R1:
197 mmccmd |= SD_CMD_RT_1; 200 mmccmd |= SD_CMD_RT_1;
198 break; 201 break;
@@ -205,6 +208,10 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
205 case MMC_RSP_R3: 208 case MMC_RSP_R3:
206 mmccmd |= SD_CMD_RT_3; 209 mmccmd |= SD_CMD_RT_3;
207 break; 210 break;
211 default:
212 printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
213 mmc_resp_type(cmd));
214 return MMC_ERR_INVALID;
208 } 215 }
209 216
210 switch(cmd->opcode) { 217 switch(cmd->opcode) {
@@ -878,6 +885,7 @@ static void au1xmmc_init_dma(struct au1xmmc_host *host)
878static const struct mmc_host_ops au1xmmc_ops = { 885static const struct mmc_host_ops au1xmmc_ops = {
879 .request = au1xmmc_request, 886 .request = au1xmmc_request,
880 .set_ios = au1xmmc_set_ios, 887 .set_ios = au1xmmc_set_ios,
888 .get_ro = au1xmmc_card_readonly,
881}; 889};
882 890
883static int __devinit au1xmmc_probe(struct platform_device *pdev) 891static int __devinit au1xmmc_probe(struct platform_device *pdev)
@@ -914,6 +922,9 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
914 mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE; 922 mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
915 mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT; 923 mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
916 924
925 mmc->max_blk_size = 2048;
926 mmc->max_blk_count = 512;
927
917 mmc->ocr_avail = AU1XMMC_OCR; 928 mmc->ocr_avail = AU1XMMC_OCR;
918 929
919 host = mmc_priv(mmc); 930 host = mmc_priv(mmc);
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index bfb9ff693208..b060d4bfba29 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -958,8 +958,10 @@ static int imxmci_probe(struct platform_device *pdev)
958 /* MMC core transfer sizes tunable parameters */ 958 /* MMC core transfer sizes tunable parameters */
959 mmc->max_hw_segs = 64; 959 mmc->max_hw_segs = 64;
960 mmc->max_phys_segs = 64; 960 mmc->max_phys_segs = 64;
961 mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */
962 mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */ 961 mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */
962 mmc->max_req_size = 64*512; /* default PAGE_CACHE_SIZE */
963 mmc->max_blk_size = 2048;
964 mmc->max_blk_count = 65535;
963 965
964 host = mmc_priv(mmc); 966 host = mmc_priv(mmc);
965 host->mmc = mmc; 967 host->mmc = mmc;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6f2a282e2b97..5046a1661342 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -103,11 +103,16 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
103 mmc_hostname(host), mrq->cmd->opcode, 103 mmc_hostname(host), mrq->cmd->opcode,
104 mrq->cmd->arg, mrq->cmd->flags); 104 mrq->cmd->arg, mrq->cmd->flags);
105 105
106 WARN_ON(host->card_busy == NULL); 106 WARN_ON(!host->claimed);
107 107
108 mrq->cmd->error = 0; 108 mrq->cmd->error = 0;
109 mrq->cmd->mrq = mrq; 109 mrq->cmd->mrq = mrq;
110 if (mrq->data) { 110 if (mrq->data) {
111 BUG_ON(mrq->data->blksz > host->max_blk_size);
112 BUG_ON(mrq->data->blocks > host->max_blk_count);
113 BUG_ON(mrq->data->blocks * mrq->data->blksz >
114 host->max_req_size);
115
111 mrq->cmd->data = mrq->data; 116 mrq->cmd->data = mrq->data;
112 mrq->data->error = 0; 117 mrq->data->error = 0;
113 mrq->data->mrq = mrq; 118 mrq->data->mrq = mrq;
@@ -157,7 +162,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
157{ 162{
158 struct mmc_request mrq; 163 struct mmc_request mrq;
159 164
160 BUG_ON(host->card_busy == NULL); 165 BUG_ON(!host->claimed);
161 166
162 memset(&mrq, 0, sizeof(struct mmc_request)); 167 memset(&mrq, 0, sizeof(struct mmc_request));
163 168
@@ -195,7 +200,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
195 200
196 int i, err; 201 int i, err;
197 202
198 BUG_ON(host->card_busy == NULL); 203 BUG_ON(!host->claimed);
199 BUG_ON(retries < 0); 204 BUG_ON(retries < 0);
200 205
201 err = MMC_ERR_INVALID; 206 err = MMC_ERR_INVALID;
@@ -289,7 +294,10 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
289 else 294 else
290 limit_us = 100000; 295 limit_us = 100000;
291 296
292 if (timeout_us > limit_us) { 297 /*
298 * SDHC cards always use these fixed values.
299 */
300 if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
293 data->timeout_ns = limit_us * 1000; 301 data->timeout_ns = limit_us * 1000;
294 data->timeout_clks = 0; 302 data->timeout_clks = 0;
295 } 303 }
@@ -320,14 +328,14 @@ int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
320 spin_lock_irqsave(&host->lock, flags); 328 spin_lock_irqsave(&host->lock, flags);
321 while (1) { 329 while (1) {
322 set_current_state(TASK_UNINTERRUPTIBLE); 330 set_current_state(TASK_UNINTERRUPTIBLE);
323 if (host->card_busy == NULL) 331 if (!host->claimed)
324 break; 332 break;
325 spin_unlock_irqrestore(&host->lock, flags); 333 spin_unlock_irqrestore(&host->lock, flags);
326 schedule(); 334 schedule();
327 spin_lock_irqsave(&host->lock, flags); 335 spin_lock_irqsave(&host->lock, flags);
328 } 336 }
329 set_current_state(TASK_RUNNING); 337 set_current_state(TASK_RUNNING);
330 host->card_busy = card; 338 host->claimed = 1;
331 spin_unlock_irqrestore(&host->lock, flags); 339 spin_unlock_irqrestore(&host->lock, flags);
332 remove_wait_queue(&host->wq, &wait); 340 remove_wait_queue(&host->wq, &wait);
333 341
@@ -353,10 +361,10 @@ void mmc_release_host(struct mmc_host *host)
353{ 361{
354 unsigned long flags; 362 unsigned long flags;
355 363
356 BUG_ON(host->card_busy == NULL); 364 BUG_ON(!host->claimed);
357 365
358 spin_lock_irqsave(&host->lock, flags); 366 spin_lock_irqsave(&host->lock, flags);
359 host->card_busy = NULL; 367 host->claimed = 0;
360 spin_unlock_irqrestore(&host->lock, flags); 368 spin_unlock_irqrestore(&host->lock, flags);
361 369
362 wake_up(&host->wq); 370 wake_up(&host->wq);
@@ -372,7 +380,7 @@ static inline void mmc_set_ios(struct mmc_host *host)
372 mmc_hostname(host), ios->clock, ios->bus_mode, 380 mmc_hostname(host), ios->clock, ios->bus_mode,
373 ios->power_mode, ios->chip_select, ios->vdd, 381 ios->power_mode, ios->chip_select, ios->vdd,
374 ios->bus_width); 382 ios->bus_width);
375 383
376 host->ops->set_ios(host, ios); 384 host->ops->set_ios(host, ios);
377} 385}
378 386
@@ -381,7 +389,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
381 int err; 389 int err;
382 struct mmc_command cmd; 390 struct mmc_command cmd;
383 391
384 BUG_ON(host->card_busy == NULL); 392 BUG_ON(!host->claimed);
385 393
386 if (host->card_selected == card) 394 if (host->card_selected == card)
387 return MMC_ERR_NONE; 395 return MMC_ERR_NONE;
@@ -588,34 +596,65 @@ static void mmc_decode_csd(struct mmc_card *card)
588 596
589 if (mmc_card_sd(card)) { 597 if (mmc_card_sd(card)) {
590 csd_struct = UNSTUFF_BITS(resp, 126, 2); 598 csd_struct = UNSTUFF_BITS(resp, 126, 2);
591 if (csd_struct != 0) { 599
600 switch (csd_struct) {
601 case 0:
602 m = UNSTUFF_BITS(resp, 115, 4);
603 e = UNSTUFF_BITS(resp, 112, 3);
604 csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
605 csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
606
607 m = UNSTUFF_BITS(resp, 99, 4);
608 e = UNSTUFF_BITS(resp, 96, 3);
609 csd->max_dtr = tran_exp[e] * tran_mant[m];
610 csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
611
612 e = UNSTUFF_BITS(resp, 47, 3);
613 m = UNSTUFF_BITS(resp, 62, 12);
614 csd->capacity = (1 + m) << (e + 2);
615
616 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
617 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
618 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
619 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
620 csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
621 csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
622 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
623 break;
624 case 1:
625 /*
626 * This is a block-addressed SDHC card. Most
627 * interesting fields are unused and have fixed
628 * values. To avoid getting tripped by buggy cards,
629 * we assume those fixed values ourselves.
630 */
631 mmc_card_set_blockaddr(card);
632
633 csd->tacc_ns = 0; /* Unused */
634 csd->tacc_clks = 0; /* Unused */
635
636 m = UNSTUFF_BITS(resp, 99, 4);
637 e = UNSTUFF_BITS(resp, 96, 3);
638 csd->max_dtr = tran_exp[e] * tran_mant[m];
639 csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
640
641 m = UNSTUFF_BITS(resp, 48, 22);
642 csd->capacity = (1 + m) << 10;
643
644 csd->read_blkbits = 9;
645 csd->read_partial = 0;
646 csd->write_misalign = 0;
647 csd->read_misalign = 0;
648 csd->r2w_factor = 4; /* Unused */
649 csd->write_blkbits = 9;
650 csd->write_partial = 0;
651 break;
652 default:
592 printk("%s: unrecognised CSD structure version %d\n", 653 printk("%s: unrecognised CSD structure version %d\n",
593 mmc_hostname(card->host), csd_struct); 654 mmc_hostname(card->host), csd_struct);
594 mmc_card_set_bad(card); 655 mmc_card_set_bad(card);
595 return; 656 return;
596 } 657 }
597
598 m = UNSTUFF_BITS(resp, 115, 4);
599 e = UNSTUFF_BITS(resp, 112, 3);
600 csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
601 csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
602
603 m = UNSTUFF_BITS(resp, 99, 4);
604 e = UNSTUFF_BITS(resp, 96, 3);
605 csd->max_dtr = tran_exp[e] * tran_mant[m];
606 csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
607
608 e = UNSTUFF_BITS(resp, 47, 3);
609 m = UNSTUFF_BITS(resp, 62, 12);
610 csd->capacity = (1 + m) << (e + 2);
611
612 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
613 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
614 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
615 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
616 csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
617 csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
618 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
619 } else { 658 } else {
620 /* 659 /*
621 * We only understand CSD structure v1.1 and v1.2. 660 * We only understand CSD structure v1.1 and v1.2.
@@ -848,6 +887,41 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
848 return err; 887 return err;
849} 888}
850 889
890static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2)
891{
892 struct mmc_command cmd;
893 int err, sd2;
894 static const u8 test_pattern = 0xAA;
895
896 /*
897 * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
898 * before SD_APP_OP_COND. This command will harmlessly fail for
899 * SD 1.0 cards.
900 */
901 cmd.opcode = SD_SEND_IF_COND;
902 cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
903 cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
904
905 err = mmc_wait_for_cmd(host, &cmd, 0);
906 if (err == MMC_ERR_NONE) {
907 if ((cmd.resp[0] & 0xFF) == test_pattern) {
908 sd2 = 1;
909 } else {
910 sd2 = 0;
911 err = MMC_ERR_FAILED;
912 }
913 } else {
914 /*
915 * Treat errors as SD 1.0 card.
916 */
917 sd2 = 0;
918 err = MMC_ERR_NONE;
919 }
920 if (rsd2)
921 *rsd2 = sd2;
922 return err;
923}
924
851/* 925/*
852 * Discover cards by requesting their CID. If this command 926 * Discover cards by requesting their CID. If this command
853 * times out, it is not an error; there are no further cards 927 * times out, it is not an error; there are no further cards
@@ -1018,7 +1092,8 @@ static void mmc_process_ext_csds(struct mmc_host *host)
1018 mmc_wait_for_req(host, &mrq); 1092 mmc_wait_for_req(host, &mrq);
1019 1093
1020 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { 1094 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
1021 mmc_card_set_dead(card); 1095 printk("%s: unable to read EXT_CSD, performance "
1096 "might suffer.\n", mmc_hostname(card->host));
1022 continue; 1097 continue;
1023 } 1098 }
1024 1099
@@ -1034,7 +1109,6 @@ static void mmc_process_ext_csds(struct mmc_host *host)
1034 printk("%s: card is mmc v4 but doesn't support " 1109 printk("%s: card is mmc v4 but doesn't support "
1035 "any high-speed modes.\n", 1110 "any high-speed modes.\n",
1036 mmc_hostname(card->host)); 1111 mmc_hostname(card->host));
1037 mmc_card_set_bad(card);
1038 continue; 1112 continue;
1039 } 1113 }
1040 1114
@@ -1215,7 +1289,9 @@ static void mmc_read_switch_caps(struct mmc_host *host)
1215 mmc_wait_for_req(host, &mrq); 1289 mmc_wait_for_req(host, &mrq);
1216 1290
1217 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { 1291 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
1218 mmc_card_set_dead(card); 1292 printk("%s: unable to read switch capabilities, "
1293 "performance might suffer.\n",
1294 mmc_hostname(card->host));
1219 continue; 1295 continue;
1220 } 1296 }
1221 1297
@@ -1247,12 +1323,8 @@ static void mmc_read_switch_caps(struct mmc_host *host)
1247 1323
1248 mmc_wait_for_req(host, &mrq); 1324 mmc_wait_for_req(host, &mrq);
1249 1325
1250 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { 1326 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE ||
1251 mmc_card_set_dead(card); 1327 (status[16] & 0xF) != 1) {
1252 continue;
1253 }
1254
1255 if ((status[16] & 0xF) != 1) {
1256 printk(KERN_WARNING "%s: Problem switching card " 1328 printk(KERN_WARNING "%s: Problem switching card "
1257 "into high-speed mode!\n", 1329 "into high-speed mode!\n",
1258 mmc_hostname(host)); 1330 mmc_hostname(host));
@@ -1334,6 +1406,10 @@ static void mmc_setup(struct mmc_host *host)
1334 mmc_power_up(host); 1406 mmc_power_up(host);
1335 mmc_idle_cards(host); 1407 mmc_idle_cards(host);
1336 1408
1409 err = mmc_send_if_cond(host, host->ocr_avail, NULL);
1410 if (err != MMC_ERR_NONE) {
1411 return;
1412 }
1337 err = mmc_send_app_op_cond(host, 0, &ocr); 1413 err = mmc_send_app_op_cond(host, 0, &ocr);
1338 1414
1339 /* 1415 /*
@@ -1386,10 +1462,21 @@ static void mmc_setup(struct mmc_host *host)
1386 * all get the idea that they should be ready for CMD2. 1462 * all get the idea that they should be ready for CMD2.
1387 * (My SanDisk card seems to need this.) 1463 * (My SanDisk card seems to need this.)
1388 */ 1464 */
1389 if (host->mode == MMC_MODE_SD) 1465 if (host->mode == MMC_MODE_SD) {
1390 mmc_send_app_op_cond(host, host->ocr, NULL); 1466 int err, sd2;
1391 else 1467 err = mmc_send_if_cond(host, host->ocr, &sd2);
1468 if (err == MMC_ERR_NONE) {
1469 /*
1470 * If SD_SEND_IF_COND indicates an SD 2.0
1471 * compliant card and we should set bit 30
1472 * of the ocr to indicate that we can handle
1473 * block-addressed SDHC cards.
1474 */
1475 mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL);
1476 }
1477 } else {
1392 mmc_send_op_cond(host, host->ocr, NULL); 1478 mmc_send_op_cond(host, host->ocr, NULL);
1479 }
1393 1480
1394 mmc_discover_cards(host); 1481 mmc_discover_cards(host);
1395 1482
@@ -1519,8 +1606,11 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
1519 */ 1606 */
1520 host->max_hw_segs = 1; 1607 host->max_hw_segs = 1;
1521 host->max_phys_segs = 1; 1608 host->max_phys_segs = 1;
1522 host->max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
1523 host->max_seg_size = PAGE_CACHE_SIZE; 1609 host->max_seg_size = PAGE_CACHE_SIZE;
1610
1611 host->max_req_size = PAGE_CACHE_SIZE;
1612 host->max_blk_size = 512;
1613 host->max_blk_count = PAGE_CACHE_SIZE / 512;
1524 } 1614 }
1525 1615
1526 return host; 1616 return host;
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 87713572293f..05ba8ace70e7 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -237,13 +237,17 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
237 brq.mrq.cmd = &brq.cmd; 237 brq.mrq.cmd = &brq.cmd;
238 brq.mrq.data = &brq.data; 238 brq.mrq.data = &brq.data;
239 239
240 brq.cmd.arg = req->sector << 9; 240 brq.cmd.arg = req->sector;
241 if (!mmc_card_blockaddr(card))
242 brq.cmd.arg <<= 9;
241 brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 243 brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
242 brq.data.blksz = 1 << md->block_bits; 244 brq.data.blksz = 1 << md->block_bits;
243 brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
244 brq.stop.opcode = MMC_STOP_TRANSMISSION; 245 brq.stop.opcode = MMC_STOP_TRANSMISSION;
245 brq.stop.arg = 0; 246 brq.stop.arg = 0;
246 brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; 247 brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
248 brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
249 if (brq.data.blocks > card->host->max_blk_count)
250 brq.data.blocks = card->host->max_blk_count;
247 251
248 mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); 252 mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
249 253
@@ -375,9 +379,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
375 spin_unlock_irq(&md->lock); 379 spin_unlock_irq(&md->lock);
376 } 380 }
377 381
382flush_queue:
383
378 mmc_card_release_host(card); 384 mmc_card_release_host(card);
379 385
380flush_queue:
381 spin_lock_irq(&md->lock); 386 spin_lock_irq(&md->lock);
382 while (ret) { 387 while (ret) {
383 ret = end_that_request_chunk(req, 0, 388 ret = end_that_request_chunk(req, 0,
@@ -494,6 +499,10 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
494 struct mmc_command cmd; 499 struct mmc_command cmd;
495 int err; 500 int err;
496 501
502 /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
503 if (mmc_card_blockaddr(card))
504 return 0;
505
497 mmc_card_claim_host(card); 506 mmc_card_claim_host(card);
498 cmd.opcode = MMC_SET_BLOCKLEN; 507 cmd.opcode = MMC_SET_BLOCKLEN;
499 cmd.arg = 1 << md->block_bits; 508 cmd.arg = 1 << md->block_bits;
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c
index 3e35a43819fb..c27e42645cdb 100644
--- a/drivers/mmc/mmc_queue.c
+++ b/drivers/mmc/mmc_queue.c
@@ -147,7 +147,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
147 147
148 blk_queue_prep_rq(mq->queue, mmc_prep_request); 148 blk_queue_prep_rq(mq->queue, mmc_prep_request);
149 blk_queue_bounce_limit(mq->queue, limit); 149 blk_queue_bounce_limit(mq->queue, limit);
150 blk_queue_max_sectors(mq->queue, host->max_sectors); 150 blk_queue_max_sectors(mq->queue, host->max_req_size / 512);
151 blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); 151 blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
152 blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); 152 blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
153 blk_queue_max_segment_size(mq->queue, host->max_seg_size); 153 blk_queue_max_segment_size(mq->queue, host->max_seg_size);
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index e334acd045bc..d32698b02d7f 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -199,7 +199,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
199 memset(card, 0, sizeof(struct mmc_card)); 199 memset(card, 0, sizeof(struct mmc_card));
200 card->host = host; 200 card->host = host;
201 device_initialize(&card->dev); 201 device_initialize(&card->dev);
202 card->dev.parent = mmc_dev(host); 202 card->dev.parent = mmc_classdev(host);
203 card->dev.bus = &mmc_bus_type; 203 card->dev.bus = &mmc_bus_type;
204 card->dev.release = mmc_release_card; 204 card->dev.release = mmc_release_card;
205} 205}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index ccfe6561be24..5941dd951e82 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -524,15 +524,24 @@ static int mmci_probe(struct amba_device *dev, void *id)
524 /* 524 /*
525 * Since we only have a 16-bit data length register, we must 525 * Since we only have a 16-bit data length register, we must
526 * ensure that we don't exceed 2^16-1 bytes in a single request. 526 * ensure that we don't exceed 2^16-1 bytes in a single request.
527 * Choose 64 (512-byte) sectors as the limit.
528 */ 527 */
529 mmc->max_sectors = 64; 528 mmc->max_req_size = 65535;
530 529
531 /* 530 /*
532 * Set the maximum segment size. Since we aren't doing DMA 531 * Set the maximum segment size. Since we aren't doing DMA
533 * (yet) we are only limited by the data length register. 532 * (yet) we are only limited by the data length register.
534 */ 533 */
535 mmc->max_seg_size = mmc->max_sectors << 9; 534 mmc->max_seg_size = mmc->max_req_size;
535
536 /*
537 * Block size can be up to 2048 bytes, but must be a power of two.
538 */
539 mmc->max_blk_size = 2048;
540
541 /*
542 * No limit on the number of blocks transferred.
543 */
544 mmc->max_blk_count = mmc->max_req_size;
536 545
537 spin_lock_init(&host->lock); 546 spin_lock_init(&host->lock);
538 547
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
index d30540b27614..1e96a2f65022 100644
--- a/drivers/mmc/omap.c
+++ b/drivers/mmc/omap.c
@@ -1099,8 +1099,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1099 */ 1099 */
1100 mmc->max_phys_segs = 32; 1100 mmc->max_phys_segs = 32;
1101 mmc->max_hw_segs = 32; 1101 mmc->max_hw_segs = 32;
1102 mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */ 1102 mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */
1103 mmc->max_seg_size = mmc->max_sectors * 512; 1103 mmc->max_blk_count = 2048; /* NBLK is 11 bits (+1) */
1104 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1105 mmc->max_seg_size = mmc->max_req_size;
1104 1106
1105 if (host->power_pin >= 0) { 1107 if (host->power_pin >= 0) {
1106 if ((ret = omap_request_gpio(host->power_pin)) != 0) { 1108 if ((ret = omap_request_gpio(host->power_pin)) != 0) {
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 6073d998b11f..9774fc68b61a 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -450,6 +450,16 @@ static int pxamci_probe(struct platform_device *pdev)
450 */ 450 */
451 mmc->max_seg_size = PAGE_SIZE; 451 mmc->max_seg_size = PAGE_SIZE;
452 452
453 /*
454 * Block length register is 10 bits.
455 */
456 mmc->max_blk_size = 1023;
457
458 /*
459 * Block count register is 16 bits.
460 */
461 mmc->max_blk_count = 65535;
462
453 host = mmc_priv(mmc); 463 host = mmc_priv(mmc);
454 host->mmc = mmc; 464 host->mmc = mmc;
455 host->dma = -1; 465 host->dma = -1;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index c2d13d7e9911..4bf1fea5e2c4 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -37,6 +37,7 @@ static unsigned int debug_quirks = 0;
37#define SDHCI_QUIRK_FORCE_DMA (1<<1) 37#define SDHCI_QUIRK_FORCE_DMA (1<<1)
38/* Controller doesn't like some resets when there is no card inserted. */ 38/* Controller doesn't like some resets when there is no card inserted. */
39#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) 39#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
40#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
40 41
41static const struct pci_device_id pci_ids[] __devinitdata = { 42static const struct pci_device_id pci_ids[] __devinitdata = {
42 { 43 {
@@ -65,6 +66,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
65 .driver_data = SDHCI_QUIRK_FORCE_DMA, 66 .driver_data = SDHCI_QUIRK_FORCE_DMA,
66 }, 67 },
67 68
69 {
70 .vendor = PCI_VENDOR_ID_ENE,
71 .device = PCI_DEVICE_ID_ENE_CB712_SD,
72 .subvendor = PCI_ANY_ID,
73 .subdevice = PCI_ANY_ID,
74 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE,
75 },
76
68 { /* Generic SD host controller */ 77 { /* Generic SD host controller */
69 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 78 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
70 }, 79 },
@@ -197,15 +206,9 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
197 * * 206 * *
198\*****************************************************************************/ 207\*****************************************************************************/
199 208
200static inline char* sdhci_kmap_sg(struct sdhci_host* host) 209static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
201{ 210{
202 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ); 211 return page_address(host->cur_sg->page) + host->cur_sg->offset;
203 return host->mapped_sg + host->cur_sg->offset;
204}
205
206static inline void sdhci_kunmap_sg(struct sdhci_host* host)
207{
208 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
209} 212}
210 213
211static inline int sdhci_next_sg(struct sdhci_host* host) 214static inline int sdhci_next_sg(struct sdhci_host* host)
@@ -240,7 +243,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
240 chunk_remain = 0; 243 chunk_remain = 0;
241 data = 0; 244 data = 0;
242 245
243 buffer = sdhci_kmap_sg(host) + host->offset; 246 buffer = sdhci_sg_to_buffer(host) + host->offset;
244 247
245 while (blksize) { 248 while (blksize) {
246 if (chunk_remain == 0) { 249 if (chunk_remain == 0) {
@@ -264,16 +267,13 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
264 } 267 }
265 268
266 if (host->remain == 0) { 269 if (host->remain == 0) {
267 sdhci_kunmap_sg(host);
268 if (sdhci_next_sg(host) == 0) { 270 if (sdhci_next_sg(host) == 0) {
269 BUG_ON(blksize != 0); 271 BUG_ON(blksize != 0);
270 return; 272 return;
271 } 273 }
272 buffer = sdhci_kmap_sg(host); 274 buffer = sdhci_sg_to_buffer(host);
273 } 275 }
274 } 276 }
275
276 sdhci_kunmap_sg(host);
277} 277}
278 278
279static void sdhci_write_block_pio(struct sdhci_host *host) 279static void sdhci_write_block_pio(struct sdhci_host *host)
@@ -290,7 +290,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
290 data = 0; 290 data = 0;
291 291
292 bytes = 0; 292 bytes = 0;
293 buffer = sdhci_kmap_sg(host) + host->offset; 293 buffer = sdhci_sg_to_buffer(host) + host->offset;
294 294
295 while (blksize) { 295 while (blksize) {
296 size = min(host->size, host->remain); 296 size = min(host->size, host->remain);
@@ -314,16 +314,13 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
314 } 314 }
315 315
316 if (host->remain == 0) { 316 if (host->remain == 0) {
317 sdhci_kunmap_sg(host);
318 if (sdhci_next_sg(host) == 0) { 317 if (sdhci_next_sg(host) == 0) {
319 BUG_ON(blksize != 0); 318 BUG_ON(blksize != 0);
320 return; 319 return;
321 } 320 }
322 buffer = sdhci_kmap_sg(host); 321 buffer = sdhci_sg_to_buffer(host);
323 } 322 }
324 } 323 }
325
326 sdhci_kunmap_sg(host);
327} 324}
328 325
329static void sdhci_transfer_pio(struct sdhci_host *host) 326static void sdhci_transfer_pio(struct sdhci_host *host)
@@ -372,7 +369,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
372 369
373 /* Sanity checks */ 370 /* Sanity checks */
374 BUG_ON(data->blksz * data->blocks > 524288); 371 BUG_ON(data->blksz * data->blocks > 524288);
375 BUG_ON(data->blksz > host->max_block); 372 BUG_ON(data->blksz > host->mmc->max_blk_size);
376 BUG_ON(data->blocks > 65535); 373 BUG_ON(data->blocks > 65535);
377 374
378 /* timeout in us */ 375 /* timeout in us */
@@ -674,10 +671,17 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
674 if (host->power == power) 671 if (host->power == power)
675 return; 672 return;
676 673
677 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); 674 if (power == (unsigned short)-1) {
678 675 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
679 if (power == (unsigned short)-1)
680 goto out; 676 goto out;
677 }
678
679 /*
680 * Spec says that we should clear the power reg before setting
681 * a new value. Some controllers don't seem to like this though.
682 */
683 if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
684 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
681 685
682 pwr = SDHCI_POWER_ON; 686 pwr = SDHCI_POWER_ON;
683 687
@@ -1109,7 +1113,9 @@ static int sdhci_resume (struct pci_dev *pdev)
1109 1113
1110 pci_set_power_state(pdev, PCI_D0); 1114 pci_set_power_state(pdev, PCI_D0);
1111 pci_restore_state(pdev); 1115 pci_restore_state(pdev);
1112 pci_enable_device(pdev); 1116 ret = pci_enable_device(pdev);
1117 if (ret)
1118 return ret;
1113 1119
1114 for (i = 0;i < chip->num_slots;i++) { 1120 for (i = 0;i < chip->num_slots;i++) {
1115 if (!chip->hosts[i]) 1121 if (!chip->hosts[i])
@@ -1274,15 +1280,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1274 if (caps & SDHCI_TIMEOUT_CLK_UNIT) 1280 if (caps & SDHCI_TIMEOUT_CLK_UNIT)
1275 host->timeout_clk *= 1000; 1281 host->timeout_clk *= 1000;
1276 1282
1277 host->max_block = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
1278 if (host->max_block >= 3) {
1279 printk(KERN_ERR "%s: Invalid maximum block size.\n",
1280 host->slot_descr);
1281 ret = -ENODEV;
1282 goto unmap;
1283 }
1284 host->max_block = 512 << host->max_block;
1285
1286 /* 1283 /*
1287 * Set host parameters. 1284 * Set host parameters.
1288 */ 1285 */
@@ -1294,9 +1291,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1294 mmc->ocr_avail = 0; 1291 mmc->ocr_avail = 0;
1295 if (caps & SDHCI_CAN_VDD_330) 1292 if (caps & SDHCI_CAN_VDD_330)
1296 mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; 1293 mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
1297 else if (caps & SDHCI_CAN_VDD_300) 1294 if (caps & SDHCI_CAN_VDD_300)
1298 mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; 1295 mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
1299 else if (caps & SDHCI_CAN_VDD_180) 1296 if (caps & SDHCI_CAN_VDD_180)
1300 mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; 1297 mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;
1301 1298
1302 if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) { 1299 if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) {
@@ -1326,15 +1323,33 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1326 1323
1327 /* 1324 /*
1328 * Maximum number of sectors in one transfer. Limited by DMA boundary 1325 * Maximum number of sectors in one transfer. Limited by DMA boundary
1329 * size (512KiB), which means (512 KiB/512=) 1024 entries. 1326 * size (512KiB).
1330 */ 1327 */
1331 mmc->max_sectors = 1024; 1328 mmc->max_req_size = 524288;
1332 1329
1333 /* 1330 /*
1334 * Maximum segment size. Could be one segment with the maximum number 1331 * Maximum segment size. Could be one segment with the maximum number
1335 * of sectors. 1332 * of bytes.
1333 */
1334 mmc->max_seg_size = mmc->max_req_size;
1335
1336 /*
1337 * Maximum block size. This varies from controller to controller and
1338 * is specified in the capabilities register.
1339 */
1340 mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
1341 if (mmc->max_blk_size >= 3) {
1342 printk(KERN_ERR "%s: Invalid maximum block size.\n",
1343 host->slot_descr);
1344 ret = -ENODEV;
1345 goto unmap;
1346 }
1347 mmc->max_blk_size = 512 << mmc->max_blk_size;
1348
1349 /*
1350 * Maximum block count.
1336 */ 1351 */
1337 mmc->max_seg_size = mmc->max_sectors * 512; 1352 mmc->max_blk_count = 65535;
1338 1353
1339 /* 1354 /*
1340 * Init tasklets. 1355 * Init tasklets.
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index f9d1a0a6f03a..e324f0a623dc 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -174,7 +174,6 @@ struct sdhci_host {
174 174
175 unsigned int max_clk; /* Max possible freq (MHz) */ 175 unsigned int max_clk; /* Max possible freq (MHz) */
176 unsigned int timeout_clk; /* Timeout freq (KHz) */ 176 unsigned int timeout_clk; /* Timeout freq (KHz) */
177 unsigned int max_block; /* Max block size (bytes) */
178 177
179 unsigned int clock; /* Current clock (MHz) */ 178 unsigned int clock; /* Current clock (MHz) */
180 unsigned short power; /* Current voltage */ 179 unsigned short power; /* Current voltage */
@@ -184,7 +183,6 @@ struct sdhci_host {
184 struct mmc_data *data; /* Current data request */ 183 struct mmc_data *data; /* Current data request */
185 184
186 struct scatterlist *cur_sg; /* We're working on this */ 185 struct scatterlist *cur_sg; /* We're working on this */
187 char *mapped_sg; /* This is where it's mapped */
188 int num_sg; /* Entries left */ 186 int num_sg; /* Entries left */
189 int offset; /* Offset into current sg */ 187 int offset; /* Offset into current sg */
190 int remain; /* Bytes left in current */ 188 int remain; /* Bytes left in current */
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index fa4a52886b97..e65f8a0a9349 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -17,7 +17,7 @@
17#include <asm/io.h> 17#include <asm/io.h>
18 18
19#define DRIVER_NAME "tifm_sd" 19#define DRIVER_NAME "tifm_sd"
20#define DRIVER_VERSION "0.6" 20#define DRIVER_VERSION "0.7"
21 21
22static int no_dma = 0; 22static int no_dma = 0;
23static int fixed_timeout = 0; 23static int fixed_timeout = 0;
@@ -79,7 +79,6 @@ typedef enum {
79 79
80enum { 80enum {
81 FIFO_RDY = 0x0001, /* hardware dependent value */ 81 FIFO_RDY = 0x0001, /* hardware dependent value */
82 HOST_REG = 0x0002,
83 EJECT = 0x0004, 82 EJECT = 0x0004,
84 EJECT_DONE = 0x0008, 83 EJECT_DONE = 0x0008,
85 CARD_BUSY = 0x0010, 84 CARD_BUSY = 0x0010,
@@ -95,46 +94,53 @@ struct tifm_sd {
95 card_state_t state; 94 card_state_t state;
96 unsigned int clk_freq; 95 unsigned int clk_freq;
97 unsigned int clk_div; 96 unsigned int clk_div;
98 unsigned long timeout_jiffies; // software timeout - 2 sec 97 unsigned long timeout_jiffies;
99 98
99 struct tasklet_struct finish_tasklet;
100 struct timer_list timer;
100 struct mmc_request *req; 101 struct mmc_request *req;
101 struct work_struct cmd_handler; 102 wait_queue_head_t notify;
102 struct delayed_work abort_handler;
103 wait_queue_head_t can_eject;
104 103
105 size_t written_blocks; 104 size_t written_blocks;
106 char *buffer;
107 size_t buffer_size; 105 size_t buffer_size;
108 size_t buffer_pos; 106 size_t buffer_pos;
109 107
110}; 108};
111 109
110static char* tifm_sd_data_buffer(struct mmc_data *data)
111{
112 return page_address(data->sg->page) + data->sg->offset;
113}
114
112static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, 115static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
113 unsigned int host_status) 116 unsigned int host_status)
114{ 117{
115 struct mmc_command *cmd = host->req->cmd; 118 struct mmc_command *cmd = host->req->cmd;
116 unsigned int t_val = 0, cnt = 0; 119 unsigned int t_val = 0, cnt = 0;
120 char *buffer;
117 121
118 if (host_status & TIFM_MMCSD_BRS) { 122 if (host_status & TIFM_MMCSD_BRS) {
119 /* in non-dma rx mode BRS fires when fifo is still not empty */ 123 /* in non-dma rx mode BRS fires when fifo is still not empty */
120 if (host->buffer && (cmd->data->flags & MMC_DATA_READ)) { 124 if (no_dma && (cmd->data->flags & MMC_DATA_READ)) {
125 buffer = tifm_sd_data_buffer(host->req->data);
121 while (host->buffer_size > host->buffer_pos) { 126 while (host->buffer_size > host->buffer_pos) {
122 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 127 t_val = readl(sock->addr + SOCK_MMCSD_DATA);
123 host->buffer[host->buffer_pos++] = t_val & 0xff; 128 buffer[host->buffer_pos++] = t_val & 0xff;
124 host->buffer[host->buffer_pos++] = 129 buffer[host->buffer_pos++] =
125 (t_val >> 8) & 0xff; 130 (t_val >> 8) & 0xff;
126 } 131 }
127 } 132 }
128 return 1; 133 return 1;
129 } else if (host->buffer) { 134 } else if (no_dma) {
135 buffer = tifm_sd_data_buffer(host->req->data);
130 if ((cmd->data->flags & MMC_DATA_READ) && 136 if ((cmd->data->flags & MMC_DATA_READ) &&
131 (host_status & TIFM_MMCSD_AF)) { 137 (host_status & TIFM_MMCSD_AF)) {
132 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 138 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
133 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 139 t_val = readl(sock->addr + SOCK_MMCSD_DATA);
134 if (host->buffer_size > host->buffer_pos) { 140 if (host->buffer_size > host->buffer_pos) {
135 host->buffer[host->buffer_pos++] = 141 buffer[host->buffer_pos++] =
136 t_val & 0xff; 142 t_val & 0xff;
137 host->buffer[host->buffer_pos++] = 143 buffer[host->buffer_pos++] =
138 (t_val >> 8) & 0xff; 144 (t_val >> 8) & 0xff;
139 } 145 }
140 } 146 }
@@ -142,11 +148,12 @@ static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
142 && (host_status & TIFM_MMCSD_AE)) { 148 && (host_status & TIFM_MMCSD_AE)) {
143 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 149 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
144 if (host->buffer_size > host->buffer_pos) { 150 if (host->buffer_size > host->buffer_pos) {
145 t_val = host->buffer[host->buffer_pos++] & 0x00ff; 151 t_val = buffer[host->buffer_pos++]
146 t_val |= ((host->buffer[host->buffer_pos++]) << 8) 152 & 0x00ff;
147 & 0xff00; 153 t_val |= ((buffer[host->buffer_pos++])
154 << 8) & 0xff00;
148 writel(t_val, 155 writel(t_val,
149 sock->addr + SOCK_MMCSD_DATA); 156 sock->addr + SOCK_MMCSD_DATA);
150 } 157 }
151 } 158 }
152 } 159 }
@@ -206,7 +213,7 @@ static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd)
206 cmd_mask |= TIFM_MMCSD_READ; 213 cmd_mask |= TIFM_MMCSD_READ;
207 214
208 dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", 215 dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n",
209 cmd->opcode, cmd->arg, cmd_mask); 216 cmd->opcode, cmd->arg, cmd_mask);
210 217
211 writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); 218 writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH);
212 writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); 219 writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW);
@@ -239,65 +246,78 @@ change_state:
239 tifm_sd_fetch_resp(cmd, sock); 246 tifm_sd_fetch_resp(cmd, sock);
240 if (cmd->data) { 247 if (cmd->data) {
241 host->state = BRS; 248 host->state = BRS;
242 } else 249 } else {
243 host->state = READY; 250 host->state = READY;
251 }
244 goto change_state; 252 goto change_state;
245 } 253 }
246 break; 254 break;
247 case BRS: 255 case BRS:
248 if (tifm_sd_transfer_data(sock, host, host_status)) { 256 if (tifm_sd_transfer_data(sock, host, host_status)) {
249 if (!host->req->stop) { 257 if (cmd->data->flags & MMC_DATA_WRITE) {
250 if (cmd->data->flags & MMC_DATA_WRITE) { 258 host->state = CARD;
251 host->state = CARD; 259 } else {
260 if (no_dma) {
261 if (host->req->stop) {
262 tifm_sd_exec(host, host->req->stop);
263 host->state = SCMD;
264 } else {
265 host->state = READY;
266 }
252 } else { 267 } else {
253 host->state = 268 host->state = FIFO;
254 host->buffer ? READY : FIFO;
255 } 269 }
256 goto change_state;
257 } 270 }
258 tifm_sd_exec(host, host->req->stop); 271 goto change_state;
259 host->state = SCMD;
260 } 272 }
261 break; 273 break;
262 case SCMD: 274 case SCMD:
263 if (host_status & TIFM_MMCSD_EOC) { 275 if (host_status & TIFM_MMCSD_EOC) {
264 tifm_sd_fetch_resp(host->req->stop, sock); 276 tifm_sd_fetch_resp(host->req->stop, sock);
265 if (cmd->error) { 277 host->state = READY;
266 host->state = READY;
267 } else if (cmd->data->flags & MMC_DATA_WRITE) {
268 host->state = CARD;
269 } else {
270 host->state = host->buffer ? READY : FIFO;
271 }
272 goto change_state; 278 goto change_state;
273 } 279 }
274 break; 280 break;
275 case CARD: 281 case CARD:
282 dev_dbg(&sock->dev, "waiting for CARD, have %zd blocks\n",
283 host->written_blocks);
276 if (!(host->flags & CARD_BUSY) 284 if (!(host->flags & CARD_BUSY)
277 && (host->written_blocks == cmd->data->blocks)) { 285 && (host->written_blocks == cmd->data->blocks)) {
278 host->state = host->buffer ? READY : FIFO; 286 if (no_dma) {
287 if (host->req->stop) {
288 tifm_sd_exec(host, host->req->stop);
289 host->state = SCMD;
290 } else {
291 host->state = READY;
292 }
293 } else {
294 host->state = FIFO;
295 }
279 goto change_state; 296 goto change_state;
280 } 297 }
281 break; 298 break;
282 case FIFO: 299 case FIFO:
283 if (host->flags & FIFO_RDY) { 300 if (host->flags & FIFO_RDY) {
284 host->state = READY;
285 host->flags &= ~FIFO_RDY; 301 host->flags &= ~FIFO_RDY;
302 if (host->req->stop) {
303 tifm_sd_exec(host, host->req->stop);
304 host->state = SCMD;
305 } else {
306 host->state = READY;
307 }
286 goto change_state; 308 goto change_state;
287 } 309 }
288 break; 310 break;
289 case READY: 311 case READY:
290 queue_work(sock->wq, &host->cmd_handler); 312 tasklet_schedule(&host->finish_tasklet);
291 return; 313 return;
292 } 314 }
293 315
294 queue_delayed_work(sock->wq, &host->abort_handler,
295 host->timeout_jiffies);
296} 316}
297 317
298/* Called from interrupt handler */ 318/* Called from interrupt handler */
299static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock, 319static void tifm_sd_signal_irq(struct tifm_dev *sock,
300 unsigned int sock_irq_status) 320 unsigned int sock_irq_status)
301{ 321{
302 struct tifm_sd *host; 322 struct tifm_sd *host;
303 unsigned int host_status = 0, fifo_status = 0; 323 unsigned int host_status = 0, fifo_status = 0;
@@ -305,7 +325,6 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
305 325
306 spin_lock(&sock->lock); 326 spin_lock(&sock->lock);
307 host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); 327 host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
308 cancel_delayed_work(&host->abort_handler);
309 328
310 if (sock_irq_status & FIFO_EVENT) { 329 if (sock_irq_status & FIFO_EVENT) {
311 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); 330 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
@@ -318,19 +337,17 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
318 host_status = readl(sock->addr + SOCK_MMCSD_STATUS); 337 host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
319 writel(host_status, sock->addr + SOCK_MMCSD_STATUS); 338 writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
320 339
321 if (!(host->flags & HOST_REG))
322 queue_work(sock->wq, &host->cmd_handler);
323 if (!host->req) 340 if (!host->req)
324 goto done; 341 goto done;
325 342
326 if (host_status & TIFM_MMCSD_ERRMASK) { 343 if (host_status & TIFM_MMCSD_ERRMASK) {
327 if (host_status & TIFM_MMCSD_CERR) 344 if (host_status & TIFM_MMCSD_CERR)
328 error_code = MMC_ERR_FAILED; 345 error_code = MMC_ERR_FAILED;
329 else if (host_status & 346 else if (host_status
330 (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) 347 & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO))
331 error_code = MMC_ERR_TIMEOUT; 348 error_code = MMC_ERR_TIMEOUT;
332 else if (host_status & 349 else if (host_status
333 (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) 350 & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC))
334 error_code = MMC_ERR_BADCRC; 351 error_code = MMC_ERR_BADCRC;
335 352
336 writel(TIFM_FIFO_INT_SETALL, 353 writel(TIFM_FIFO_INT_SETALL,
@@ -340,12 +357,11 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
340 if (host->req->stop) { 357 if (host->req->stop) {
341 if (host->state == SCMD) { 358 if (host->state == SCMD) {
342 host->req->stop->error = error_code; 359 host->req->stop->error = error_code;
343 } else if(host->state == BRS) { 360 } else if (host->state == BRS
361 || host->state == CARD
362 || host->state == FIFO) {
344 host->req->cmd->error = error_code; 363 host->req->cmd->error = error_code;
345 tifm_sd_exec(host, host->req->stop); 364 tifm_sd_exec(host, host->req->stop);
346 queue_delayed_work(sock->wq,
347 &host->abort_handler,
348 host->timeout_jiffies);
349 host->state = SCMD; 365 host->state = SCMD;
350 goto done; 366 goto done;
351 } else { 367 } else {
@@ -359,8 +375,8 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
359 375
360 if (host_status & TIFM_MMCSD_CB) 376 if (host_status & TIFM_MMCSD_CB)
361 host->flags |= CARD_BUSY; 377 host->flags |= CARD_BUSY;
362 if ((host_status & TIFM_MMCSD_EOFB) && 378 if ((host_status & TIFM_MMCSD_EOFB)
363 (host->flags & CARD_BUSY)) { 379 && (host->flags & CARD_BUSY)) {
364 host->written_blocks++; 380 host->written_blocks++;
365 host->flags &= ~CARD_BUSY; 381 host->flags &= ~CARD_BUSY;
366 } 382 }
@@ -370,22 +386,22 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
370 tifm_sd_process_cmd(sock, host, host_status); 386 tifm_sd_process_cmd(sock, host, host_status);
371done: 387done:
372 dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", 388 dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n",
373 host_status, fifo_status); 389 host_status, fifo_status);
374 spin_unlock(&sock->lock); 390 spin_unlock(&sock->lock);
375 return sock_irq_status;
376} 391}
377 392
378static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd) 393static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd)
379{ 394{
380 struct tifm_dev *sock = card->dev; 395 struct tifm_dev *sock = host->dev;
381 unsigned int dest_cnt; 396 unsigned int dest_cnt;
382 397
383 /* DMA style IO */ 398 /* DMA style IO */
384 399 dev_dbg(&sock->dev, "setting dma for %d blocks\n",
400 cmd->data->blocks);
385 writel(TIFM_FIFO_INT_SETALL, 401 writel(TIFM_FIFO_INT_SETALL,
386 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); 402 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
387 writel(ilog2(cmd->data->blksz) - 2, 403 writel(ilog2(cmd->data->blksz) - 2,
388 sock->addr + SOCK_FIFO_PAGE_SIZE); 404 sock->addr + SOCK_FIFO_PAGE_SIZE);
389 writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); 405 writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
390 writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); 406 writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
391 407
@@ -399,7 +415,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
399 if (cmd->data->flags & MMC_DATA_WRITE) { 415 if (cmd->data->flags & MMC_DATA_WRITE) {
400 writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); 416 writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
401 writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, 417 writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN,
402 sock->addr + SOCK_DMA_CONTROL); 418 sock->addr + SOCK_DMA_CONTROL);
403 } else { 419 } else {
404 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); 420 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
405 writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); 421 writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL);
@@ -407,7 +423,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
407} 423}
408 424
409static void tifm_sd_set_data_timeout(struct tifm_sd *host, 425static void tifm_sd_set_data_timeout(struct tifm_sd *host,
410 struct mmc_data *data) 426 struct mmc_data *data)
411{ 427{
412 struct tifm_dev *sock = host->dev; 428 struct tifm_dev *sock = host->dev;
413 unsigned int data_timeout = data->timeout_clks; 429 unsigned int data_timeout = data->timeout_clks;
@@ -416,22 +432,21 @@ static void tifm_sd_set_data_timeout(struct tifm_sd *host,
416 return; 432 return;
417 433
418 data_timeout += data->timeout_ns / 434 data_timeout += data->timeout_ns /
419 ((1000000000 / host->clk_freq) * host->clk_div); 435 ((1000000000UL / host->clk_freq) * host->clk_div);
420 data_timeout *= 10; // call it fudge factor for now
421 436
422 if (data_timeout < 0xffff) { 437 if (data_timeout < 0xffff) {
423 writel((~TIFM_MMCSD_DPE) &
424 readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
425 sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
426 writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); 438 writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
439 writel((~TIFM_MMCSD_DPE)
440 & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
441 sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
427 } else { 442 } else {
428 writel(TIFM_MMCSD_DPE |
429 readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
430 sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
431 data_timeout = (data_timeout >> 10) + 1; 443 data_timeout = (data_timeout >> 10) + 1;
432 if(data_timeout > 0xffff) 444 if (data_timeout > 0xffff)
433 data_timeout = 0; /* set to unlimited */ 445 data_timeout = 0; /* set to unlimited */
434 writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); 446 writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
447 writel(TIFM_MMCSD_DPE
448 | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
449 sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
435 } 450 }
436} 451}
437 452
@@ -474,11 +489,10 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
474 } 489 }
475 490
476 host->req = mrq; 491 host->req = mrq;
492 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
477 host->state = CMD; 493 host->state = CMD;
478 queue_delayed_work(sock->wq, &host->abort_handler,
479 host->timeout_jiffies);
480 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 494 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
481 sock->addr + SOCK_CONTROL); 495 sock->addr + SOCK_CONTROL);
482 tifm_sd_exec(host, mrq->cmd); 496 tifm_sd_exec(host, mrq->cmd);
483 spin_unlock_irqrestore(&sock->lock, flags); 497 spin_unlock_irqrestore(&sock->lock, flags);
484 return; 498 return;
@@ -493,9 +507,9 @@ err_out:
493 mmc_request_done(mmc, mrq); 507 mmc_request_done(mmc, mrq);
494} 508}
495 509
496static void tifm_sd_end_cmd(struct work_struct *work) 510static void tifm_sd_end_cmd(unsigned long data)
497{ 511{
498 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 512 struct tifm_sd *host = (struct tifm_sd*)data;
499 struct tifm_dev *sock = host->dev; 513 struct tifm_dev *sock = host->dev;
500 struct mmc_host *mmc = tifm_get_drvdata(sock); 514 struct mmc_host *mmc = tifm_get_drvdata(sock);
501 struct mmc_request *mrq; 515 struct mmc_request *mrq;
@@ -504,6 +518,7 @@ static void tifm_sd_end_cmd(struct work_struct *work)
504 518
505 spin_lock_irqsave(&sock->lock, flags); 519 spin_lock_irqsave(&sock->lock, flags);
506 520
521 del_timer(&host->timer);
507 mrq = host->req; 522 mrq = host->req;
508 host->req = NULL; 523 host->req = NULL;
509 host->state = IDLE; 524 host->state = IDLE;
@@ -517,8 +532,8 @@ static void tifm_sd_end_cmd(struct work_struct *work)
517 r_data = mrq->cmd->data; 532 r_data = mrq->cmd->data;
518 if (r_data) { 533 if (r_data) {
519 if (r_data->flags & MMC_DATA_WRITE) { 534 if (r_data->flags & MMC_DATA_WRITE) {
520 r_data->bytes_xfered = host->written_blocks * 535 r_data->bytes_xfered = host->written_blocks
521 r_data->blksz; 536 * r_data->blksz;
522 } else { 537 } else {
523 r_data->bytes_xfered = r_data->blocks - 538 r_data->bytes_xfered = r_data->blocks -
524 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; 539 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
@@ -532,7 +547,7 @@ static void tifm_sd_end_cmd(struct work_struct *work)
532 } 547 }
533 548
534 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 549 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
535 sock->addr + SOCK_CONTROL); 550 sock->addr + SOCK_CONTROL);
536 551
537 spin_unlock_irqrestore(&sock->lock, flags); 552 spin_unlock_irqrestore(&sock->lock, flags);
538 mmc_request_done(mmc, mrq); 553 mmc_request_done(mmc, mrq);
@@ -544,15 +559,6 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
544 struct tifm_dev *sock = host->dev; 559 struct tifm_dev *sock = host->dev;
545 unsigned long flags; 560 unsigned long flags;
546 struct mmc_data *r_data = mrq->cmd->data; 561 struct mmc_data *r_data = mrq->cmd->data;
547 char *t_buffer = NULL;
548
549 if (r_data) {
550 t_buffer = kmap(r_data->sg->page);
551 if (!t_buffer) {
552 printk(KERN_ERR DRIVER_NAME ": kmap failed\n");
553 goto err_out;
554 }
555 }
556 562
557 spin_lock_irqsave(&sock->lock, flags); 563 spin_lock_irqsave(&sock->lock, flags);
558 if (host->flags & EJECT) { 564 if (host->flags & EJECT) {
@@ -569,15 +575,14 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
569 if (r_data) { 575 if (r_data) {
570 tifm_sd_set_data_timeout(host, r_data); 576 tifm_sd_set_data_timeout(host, r_data);
571 577
572 host->buffer = t_buffer + r_data->sg->offset; 578 host->buffer_size = mrq->cmd->data->blocks
573 host->buffer_size = mrq->cmd->data->blocks * 579 * mrq->cmd->data->blksz;
574 mrq->cmd->data->blksz;
575 580
576 writel(TIFM_MMCSD_BUFINT | 581 writel(TIFM_MMCSD_BUFINT
577 readl(sock->addr + SOCK_MMCSD_INT_ENABLE), 582 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
578 sock->addr + SOCK_MMCSD_INT_ENABLE); 583 sock->addr + SOCK_MMCSD_INT_ENABLE);
579 writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | 584 writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
580 (TIFM_MMCSD_FIFO_SIZE - 1), 585 | (TIFM_MMCSD_FIFO_SIZE - 1),
581 sock->addr + SOCK_MMCSD_BUFFER_CONFIG); 586 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
582 587
583 host->written_blocks = 0; 588 host->written_blocks = 0;
@@ -588,26 +593,22 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
588 } 593 }
589 594
590 host->req = mrq; 595 host->req = mrq;
596 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
591 host->state = CMD; 597 host->state = CMD;
592 queue_delayed_work(sock->wq, &host->abort_handler,
593 host->timeout_jiffies);
594 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 598 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
595 sock->addr + SOCK_CONTROL); 599 sock->addr + SOCK_CONTROL);
596 tifm_sd_exec(host, mrq->cmd); 600 tifm_sd_exec(host, mrq->cmd);
597 spin_unlock_irqrestore(&sock->lock, flags); 601 spin_unlock_irqrestore(&sock->lock, flags);
598 return; 602 return;
599 603
600err_out: 604err_out:
601 if (t_buffer)
602 kunmap(r_data->sg->page);
603
604 mrq->cmd->error = MMC_ERR_TIMEOUT; 605 mrq->cmd->error = MMC_ERR_TIMEOUT;
605 mmc_request_done(mmc, mrq); 606 mmc_request_done(mmc, mrq);
606} 607}
607 608
608static void tifm_sd_end_cmd_nodma(struct work_struct *work) 609static void tifm_sd_end_cmd_nodma(unsigned long data)
609{ 610{
610 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 611 struct tifm_sd *host = (struct tifm_sd*)data;
611 struct tifm_dev *sock = host->dev; 612 struct tifm_dev *sock = host->dev;
612 struct mmc_host *mmc = tifm_get_drvdata(sock); 613 struct mmc_host *mmc = tifm_get_drvdata(sock);
613 struct mmc_request *mrq; 614 struct mmc_request *mrq;
@@ -616,6 +617,7 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
616 617
617 spin_lock_irqsave(&sock->lock, flags); 618 spin_lock_irqsave(&sock->lock, flags);
618 619
620 del_timer(&host->timer);
619 mrq = host->req; 621 mrq = host->req;
620 host->req = NULL; 622 host->req = NULL;
621 host->state = IDLE; 623 host->state = IDLE;
@@ -633,8 +635,8 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
633 sock->addr + SOCK_MMCSD_INT_ENABLE); 635 sock->addr + SOCK_MMCSD_INT_ENABLE);
634 636
635 if (r_data->flags & MMC_DATA_WRITE) { 637 if (r_data->flags & MMC_DATA_WRITE) {
636 r_data->bytes_xfered = host->written_blocks * 638 r_data->bytes_xfered = host->written_blocks
637 r_data->blksz; 639 * r_data->blksz;
638 } else { 640 } else {
639 r_data->bytes_xfered = r_data->blocks - 641 r_data->bytes_xfered = r_data->blocks -
640 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; 642 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
@@ -642,29 +644,44 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work)
642 r_data->bytes_xfered += r_data->blksz - 644 r_data->bytes_xfered += r_data->blksz -
643 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; 645 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
644 } 646 }
645 host->buffer = NULL;
646 host->buffer_pos = 0; 647 host->buffer_pos = 0;
647 host->buffer_size = 0; 648 host->buffer_size = 0;
648 } 649 }
649 650
650 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 651 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
651 sock->addr + SOCK_CONTROL); 652 sock->addr + SOCK_CONTROL);
652 653
653 spin_unlock_irqrestore(&sock->lock, flags); 654 spin_unlock_irqrestore(&sock->lock, flags);
654 655
655 if (r_data)
656 kunmap(r_data->sg->page);
657
658 mmc_request_done(mmc, mrq); 656 mmc_request_done(mmc, mrq);
659} 657}
660 658
661static void tifm_sd_abort(struct work_struct *work) 659static void tifm_sd_terminate(struct tifm_sd *host)
660{
661 struct tifm_dev *sock = host->dev;
662 unsigned long flags;
663
664 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
665 mmiowb();
666 spin_lock_irqsave(&sock->lock, flags);
667 host->flags |= EJECT;
668 if (host->req) {
669 writel(TIFM_FIFO_INT_SETALL,
670 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
671 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
672 tasklet_schedule(&host->finish_tasklet);
673 }
674 spin_unlock_irqrestore(&sock->lock, flags);
675}
676
677static void tifm_sd_abort(unsigned long data)
662{ 678{
663 struct tifm_sd *host = 679 struct tifm_sd *host = (struct tifm_sd*)data;
664 container_of(work, struct tifm_sd, abort_handler.work);
665 680
666 printk(KERN_ERR DRIVER_NAME 681 printk(KERN_ERR DRIVER_NAME
667 ": card failed to respond for a long period of time"); 682 ": card failed to respond for a long period of time");
683
684 tifm_sd_terminate(host);
668 tifm_eject(host->dev); 685 tifm_eject(host->dev);
669} 686}
670 687
@@ -683,9 +700,9 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
683 writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), 700 writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
684 sock->addr + SOCK_MMCSD_CONFIG); 701 sock->addr + SOCK_MMCSD_CONFIG);
685 } else { 702 } else {
686 writel((~TIFM_MMCSD_4BBUS) & 703 writel((~TIFM_MMCSD_4BBUS)
687 readl(sock->addr + SOCK_MMCSD_CONFIG), 704 & readl(sock->addr + SOCK_MMCSD_CONFIG),
688 sock->addr + SOCK_MMCSD_CONFIG); 705 sock->addr + SOCK_MMCSD_CONFIG);
689 } 706 }
690 707
691 if (ios->clock) { 708 if (ios->clock) {
@@ -704,23 +721,24 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
704 if ((20000000 / clk_div1) > (24000000 / clk_div2)) { 721 if ((20000000 / clk_div1) > (24000000 / clk_div2)) {
705 host->clk_freq = 20000000; 722 host->clk_freq = 20000000;
706 host->clk_div = clk_div1; 723 host->clk_div = clk_div1;
707 writel((~TIFM_CTRL_FAST_CLK) & 724 writel((~TIFM_CTRL_FAST_CLK)
708 readl(sock->addr + SOCK_CONTROL), 725 & readl(sock->addr + SOCK_CONTROL),
709 sock->addr + SOCK_CONTROL); 726 sock->addr + SOCK_CONTROL);
710 } else { 727 } else {
711 host->clk_freq = 24000000; 728 host->clk_freq = 24000000;
712 host->clk_div = clk_div2; 729 host->clk_div = clk_div2;
713 writel(TIFM_CTRL_FAST_CLK | 730 writel(TIFM_CTRL_FAST_CLK
714 readl(sock->addr + SOCK_CONTROL), 731 | readl(sock->addr + SOCK_CONTROL),
715 sock->addr + SOCK_CONTROL); 732 sock->addr + SOCK_CONTROL);
716 } 733 }
717 } else { 734 } else {
718 host->clk_div = 0; 735 host->clk_div = 0;
719 } 736 }
720 host->clk_div &= TIFM_MMCSD_CLKMASK; 737 host->clk_div &= TIFM_MMCSD_CLKMASK;
721 writel(host->clk_div | ((~TIFM_MMCSD_CLKMASK) & 738 writel(host->clk_div
722 readl(sock->addr + SOCK_MMCSD_CONFIG)), 739 | ((~TIFM_MMCSD_CLKMASK)
723 sock->addr + SOCK_MMCSD_CONFIG); 740 & readl(sock->addr + SOCK_MMCSD_CONFIG)),
741 sock->addr + SOCK_MMCSD_CONFIG);
724 742
725 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 743 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
726 host->flags |= OPENDRAIN; 744 host->flags |= OPENDRAIN;
@@ -734,7 +752,7 @@ static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
734 // allow removal. 752 // allow removal.
735 if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { 753 if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) {
736 host->flags |= EJECT_DONE; 754 host->flags |= EJECT_DONE;
737 wake_up_all(&host->can_eject); 755 wake_up_all(&host->notify);
738 } 756 }
739 757
740 spin_unlock_irqrestore(&sock->lock, flags); 758 spin_unlock_irqrestore(&sock->lock, flags);
@@ -762,20 +780,67 @@ static struct mmc_host_ops tifm_sd_ops = {
762 .get_ro = tifm_sd_ro 780 .get_ro = tifm_sd_ro
763}; 781};
764 782
765static void tifm_sd_register_host(struct work_struct *work) 783static int tifm_sd_initialize_host(struct tifm_sd *host)
766{ 784{
767 struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); 785 int rc;
786 unsigned int host_status = 0;
768 struct tifm_dev *sock = host->dev; 787 struct tifm_dev *sock = host->dev;
769 struct mmc_host *mmc = tifm_get_drvdata(sock);
770 unsigned long flags;
771 788
772 spin_lock_irqsave(&sock->lock, flags); 789 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
773 host->flags |= HOST_REG; 790 mmiowb();
774 PREPARE_WORK(&host->cmd_handler, 791 host->clk_div = 61;
775 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd); 792 host->clk_freq = 20000000;
776 spin_unlock_irqrestore(&sock->lock, flags); 793 writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
777 dev_dbg(&sock->dev, "adding host\n"); 794 writel(host->clk_div | TIFM_MMCSD_POWER,
778 mmc_add_host(mmc); 795 sock->addr + SOCK_MMCSD_CONFIG);
796
797 /* wait up to 0.51 sec for reset */
798 for (rc = 2; rc <= 256; rc <<= 1) {
799 if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
800 rc = 0;
801 break;
802 }
803 msleep(rc);
804 }
805
806 if (rc) {
807 printk(KERN_ERR DRIVER_NAME
808 ": controller failed to reset\n");
809 return -ENODEV;
810 }
811
812 writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
813 writel(host->clk_div | TIFM_MMCSD_POWER,
814 sock->addr + SOCK_MMCSD_CONFIG);
815 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
816
817 // command timeout fixed to 64 clocks for now
818 writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO);
819 writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
820
821 /* INAB should take much less than reset */
822 for (rc = 1; rc <= 16; rc <<= 1) {
823 host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
824 writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
825 if (!(host_status & TIFM_MMCSD_ERRMASK)
826 && (host_status & TIFM_MMCSD_EOC)) {
827 rc = 0;
828 break;
829 }
830 msleep(rc);
831 }
832
833 if (rc) {
834 printk(KERN_ERR DRIVER_NAME
835 ": card not ready - probe failed on initialization\n");
836 return -ENODEV;
837 }
838
839 writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
840 sock->addr + SOCK_MMCSD_INT_ENABLE);
841 mmiowb();
842
843 return 0;
779} 844}
780 845
781static int tifm_sd_probe(struct tifm_dev *sock) 846static int tifm_sd_probe(struct tifm_dev *sock)
@@ -784,8 +849,8 @@ static int tifm_sd_probe(struct tifm_dev *sock)
784 struct tifm_sd *host; 849 struct tifm_sd *host;
785 int rc = -EIO; 850 int rc = -EIO;
786 851
787 if (!(TIFM_SOCK_STATE_OCCUPIED & 852 if (!(TIFM_SOCK_STATE_OCCUPIED
788 readl(sock->addr + SOCK_PRESENT_STATE))) { 853 & readl(sock->addr + SOCK_PRESENT_STATE))) {
789 printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); 854 printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n");
790 return rc; 855 return rc;
791 } 856 }
@@ -795,109 +860,99 @@ static int tifm_sd_probe(struct tifm_dev *sock)
795 return -ENOMEM; 860 return -ENOMEM;
796 861
797 host = mmc_priv(mmc); 862 host = mmc_priv(mmc);
798 host->dev = sock;
799 host->clk_div = 61;
800 init_waitqueue_head(&host->can_eject);
801 INIT_WORK(&host->cmd_handler, tifm_sd_register_host);
802 INIT_DELAYED_WORK(&host->abort_handler, tifm_sd_abort);
803
804 tifm_set_drvdata(sock, mmc); 863 tifm_set_drvdata(sock, mmc);
805 sock->signal_irq = tifm_sd_signal_irq; 864 host->dev = sock;
806
807 host->clk_freq = 20000000;
808 host->timeout_jiffies = msecs_to_jiffies(1000); 865 host->timeout_jiffies = msecs_to_jiffies(1000);
809 866
867 init_waitqueue_head(&host->notify);
868 tasklet_init(&host->finish_tasklet,
869 no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
870 (unsigned long)host);
871 setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
872
810 tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; 873 tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request;
811 mmc->ops = &tifm_sd_ops; 874 mmc->ops = &tifm_sd_ops;
812 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 875 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
813 mmc->caps = MMC_CAP_4_BIT_DATA; 876 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
814 mmc->f_min = 20000000 / 60; 877 mmc->f_min = 20000000 / 60;
815 mmc->f_max = 24000000; 878 mmc->f_max = 24000000;
816 mmc->max_hw_segs = 1; 879 mmc->max_hw_segs = 1;
817 mmc->max_phys_segs = 1; 880 mmc->max_phys_segs = 1;
818 mmc->max_sectors = 127; 881 // limited by DMA counter - it's safer to stick with
819 mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length 882 // block counter has 11 bits though
820 883 mmc->max_blk_count = 256;
821 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); 884 // 2k maximum hw block length
822 writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); 885 mmc->max_blk_size = 2048;
823 writel(host->clk_div | TIFM_MMCSD_POWER, 886 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
824 sock->addr + SOCK_MMCSD_CONFIG); 887 mmc->max_seg_size = mmc->max_req_size;
888 sock->signal_irq = tifm_sd_signal_irq;
889 rc = tifm_sd_initialize_host(host);
825 890
826 for (rc = 0; rc < 50; rc++) { 891 if (!rc)
827 /* Wait for reset ack */ 892 rc = mmc_add_host(mmc);
828 if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { 893 if (rc)
829 rc = 0; 894 goto out_free_mmc;
830 break;
831 }
832 msleep(10);
833 }
834 895
835 if (rc) { 896 return 0;
836 printk(KERN_ERR DRIVER_NAME 897out_free_mmc:
837 ": card not ready - probe failed\n"); 898 mmc_free_host(mmc);
838 mmc_free_host(mmc); 899 return rc;
839 return -ENODEV; 900}
840 }
841 901
842 writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); 902static void tifm_sd_remove(struct tifm_dev *sock)
843 writel(host->clk_div | TIFM_MMCSD_POWER, 903{
844 sock->addr + SOCK_MMCSD_CONFIG); 904 struct mmc_host *mmc = tifm_get_drvdata(sock);
845 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); 905 struct tifm_sd *host = mmc_priv(mmc);
846 writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
847 sock->addr + SOCK_MMCSD_INT_ENABLE);
848 906
849 writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); // command timeout 64 clocks for now 907 del_timer_sync(&host->timer);
850 writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); 908 tifm_sd_terminate(host);
851 writel(host->clk_div | TIFM_MMCSD_POWER, 909 wait_event_timeout(host->notify, host->flags & EJECT_DONE,
852 sock->addr + SOCK_MMCSD_CONFIG); 910 host->timeout_jiffies);
911 tasklet_kill(&host->finish_tasklet);
912 mmc_remove_host(mmc);
853 913
854 queue_delayed_work(sock->wq, &host->abort_handler, 914 /* The meaning of the bit majority in this constant is unknown. */
855 host->timeout_jiffies); 915 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
916 sock->addr + SOCK_CONTROL);
856 917
857 return 0; 918 tifm_set_drvdata(sock, NULL);
919 mmc_free_host(mmc);
858} 920}
859 921
860static int tifm_sd_host_is_down(struct tifm_dev *sock) 922#ifdef CONFIG_PM
923
924static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
861{ 925{
862 struct mmc_host *mmc = tifm_get_drvdata(sock); 926 struct mmc_host *mmc = tifm_get_drvdata(sock);
863 struct tifm_sd *host = mmc_priv(mmc); 927 int rc;
864 unsigned long flags;
865 int rc = 0;
866 928
867 spin_lock_irqsave(&sock->lock, flags); 929 rc = mmc_suspend_host(mmc, state);
868 rc = (host->flags & EJECT_DONE); 930 /* The meaning of the bit majority in this constant is unknown. */
869 spin_unlock_irqrestore(&sock->lock, flags); 931 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
932 sock->addr + SOCK_CONTROL);
870 return rc; 933 return rc;
871} 934}
872 935
873static void tifm_sd_remove(struct tifm_dev *sock) 936static int tifm_sd_resume(struct tifm_dev *sock)
874{ 937{
875 struct mmc_host *mmc = tifm_get_drvdata(sock); 938 struct mmc_host *mmc = tifm_get_drvdata(sock);
876 struct tifm_sd *host = mmc_priv(mmc); 939 struct tifm_sd *host = mmc_priv(mmc);
877 unsigned long flags;
878 940
879 spin_lock_irqsave(&sock->lock, flags); 941 if (sock->media_id != FM_SD
880 host->flags |= EJECT; 942 || tifm_sd_initialize_host(host)) {
881 if (host->req) 943 tifm_eject(sock);
882 queue_work(sock->wq, &host->cmd_handler); 944 return 0;
883 spin_unlock_irqrestore(&sock->lock, flags); 945 } else {
884 wait_event_timeout(host->can_eject, tifm_sd_host_is_down(sock), 946 return mmc_resume_host(mmc);
885 host->timeout_jiffies); 947 }
948}
886 949
887 if (host->flags & HOST_REG) 950#else
888 mmc_remove_host(mmc);
889 951
890 /* The meaning of the bit majority in this constant is unknown. */ 952#define tifm_sd_suspend NULL
891 writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), 953#define tifm_sd_resume NULL
892 sock->addr + SOCK_CONTROL);
893 writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
894 writel(TIFM_FIFO_INT_SETALL,
895 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
896 writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
897 954
898 tifm_set_drvdata(sock, NULL); 955#endif /* CONFIG_PM */
899 mmc_free_host(mmc);
900}
901 956
902static tifm_media_id tifm_sd_id_tbl[] = { 957static tifm_media_id tifm_sd_id_tbl[] = {
903 FM_SD, 0 958 FM_SD, 0
@@ -910,7 +965,9 @@ static struct tifm_driver tifm_sd_driver = {
910 }, 965 },
911 .id_table = tifm_sd_id_tbl, 966 .id_table = tifm_sd_id_tbl,
912 .probe = tifm_sd_probe, 967 .probe = tifm_sd_probe,
913 .remove = tifm_sd_remove 968 .remove = tifm_sd_remove,
969 .suspend = tifm_sd_suspend,
970 .resume = tifm_sd_resume
914}; 971};
915 972
916static int __init tifm_sd_init(void) 973static int __init tifm_sd_init(void)
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 7a282672f8e9..a44d8777ab9f 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver 2 * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver
3 * 3 *
4 * Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved. 4 * Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved.
5 * 5 *
6 * 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
7 * 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
@@ -272,16 +272,9 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
272 return host->num_sg; 272 return host->num_sg;
273} 273}
274 274
275static inline char *wbsd_kmap_sg(struct wbsd_host *host) 275static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
276{ 276{
277 host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + 277 return page_address(host->cur_sg->page) + host->cur_sg->offset;
278 host->cur_sg->offset;
279 return host->mapped_sg;
280}
281
282static inline void wbsd_kunmap_sg(struct wbsd_host *host)
283{
284 kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
285} 278}
286 279
287static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) 280static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -302,12 +295,11 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
302 * we do not transfer too much. 295 * we do not transfer too much.
303 */ 296 */
304 for (i = 0; i < len; i++) { 297 for (i = 0; i < len; i++) {
305 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; 298 sgbuf = page_address(sg[i].page) + sg[i].offset;
306 if (size < sg[i].length) 299 if (size < sg[i].length)
307 memcpy(dmabuf, sgbuf, size); 300 memcpy(dmabuf, sgbuf, size);
308 else 301 else
309 memcpy(dmabuf, sgbuf, sg[i].length); 302 memcpy(dmabuf, sgbuf, sg[i].length);
310 kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
311 dmabuf += sg[i].length; 303 dmabuf += sg[i].length;
312 304
313 if (size < sg[i].length) 305 if (size < sg[i].length)
@@ -347,7 +339,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
347 * we do not transfer too much. 339 * we do not transfer too much.
348 */ 340 */
349 for (i = 0; i < len; i++) { 341 for (i = 0; i < len; i++) {
350 sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; 342 sgbuf = page_address(sg[i].page) + sg[i].offset;
351 if (size < sg[i].length) 343 if (size < sg[i].length)
352 memcpy(sgbuf, dmabuf, size); 344 memcpy(sgbuf, dmabuf, size);
353 else 345 else
@@ -497,7 +489,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
497 if (data->bytes_xfered == host->size) 489 if (data->bytes_xfered == host->size)
498 return; 490 return;
499 491
500 buffer = wbsd_kmap_sg(host) + host->offset; 492 buffer = wbsd_sg_to_buffer(host) + host->offset;
501 493
502 /* 494 /*
503 * Drain the fifo. This has a tendency to loop longer 495 * Drain the fifo. This has a tendency to loop longer
@@ -526,17 +518,13 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
526 /* 518 /*
527 * Transfer done? 519 * Transfer done?
528 */ 520 */
529 if (data->bytes_xfered == host->size) { 521 if (data->bytes_xfered == host->size)
530 wbsd_kunmap_sg(host);
531 return; 522 return;
532 }
533 523
534 /* 524 /*
535 * End of scatter list entry? 525 * End of scatter list entry?
536 */ 526 */
537 if (host->remain == 0) { 527 if (host->remain == 0) {
538 wbsd_kunmap_sg(host);
539
540 /* 528 /*
541 * Get next entry. Check if last. 529 * Get next entry. Check if last.
542 */ 530 */
@@ -554,13 +542,11 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
554 return; 542 return;
555 } 543 }
556 544
557 buffer = wbsd_kmap_sg(host); 545 buffer = wbsd_sg_to_buffer(host);
558 } 546 }
559 } 547 }
560 } 548 }
561 549
562 wbsd_kunmap_sg(host);
563
564 /* 550 /*
565 * This is a very dirty hack to solve a 551 * This is a very dirty hack to solve a
566 * hardware problem. The chip doesn't trigger 552 * hardware problem. The chip doesn't trigger
@@ -583,7 +569,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
583 if (data->bytes_xfered == host->size) 569 if (data->bytes_xfered == host->size)
584 return; 570 return;
585 571
586 buffer = wbsd_kmap_sg(host) + host->offset; 572 buffer = wbsd_sg_to_buffer(host) + host->offset;
587 573
588 /* 574 /*
589 * Fill the fifo. This has a tendency to loop longer 575 * Fill the fifo. This has a tendency to loop longer
@@ -612,17 +598,13 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
612 /* 598 /*
613 * Transfer done? 599 * Transfer done?
614 */ 600 */
615 if (data->bytes_xfered == host->size) { 601 if (data->bytes_xfered == host->size)
616 wbsd_kunmap_sg(host);
617 return; 602 return;
618 }
619 603
620 /* 604 /*
621 * End of scatter list entry? 605 * End of scatter list entry?
622 */ 606 */
623 if (host->remain == 0) { 607 if (host->remain == 0) {
624 wbsd_kunmap_sg(host);
625
626 /* 608 /*
627 * Get next entry. Check if last. 609 * Get next entry. Check if last.
628 */ 610 */
@@ -640,13 +622,11 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
640 return; 622 return;
641 } 623 }
642 624
643 buffer = wbsd_kmap_sg(host); 625 buffer = wbsd_sg_to_buffer(host);
644 } 626 }
645 } 627 }
646 } 628 }
647 629
648 wbsd_kunmap_sg(host);
649
650 /* 630 /*
651 * The controller stops sending interrupts for 631 * The controller stops sending interrupts for
652 * 'FIFO empty' under certain conditions. So we 632 * 'FIFO empty' under certain conditions. So we
@@ -910,6 +890,45 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
910 */ 890 */
911 if (cmd->data && (cmd->error == MMC_ERR_NONE)) { 891 if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
912 /* 892 /*
893 * The hardware is so delightfully stupid that it has a list
894 * of "data" commands. If a command isn't on this list, it'll
895 * just go back to the idle state and won't send any data
896 * interrupts.
897 */
898 switch (cmd->opcode) {
899 case 11:
900 case 17:
901 case 18:
902 case 20:
903 case 24:
904 case 25:
905 case 26:
906 case 27:
907 case 30:
908 case 42:
909 case 56:
910 break;
911
912 /* ACMDs. We don't keep track of state, so we just treat them
913 * like any other command. */
914 case 51:
915 break;
916
917 default:
918#ifdef CONFIG_MMC_DEBUG
919 printk(KERN_WARNING "%s: Data command %d is not "
920 "supported by this controller.\n",
921 mmc_hostname(host->mmc), cmd->opcode);
922#endif
923 cmd->data->error = MMC_ERR_INVALID;
924
925 if (cmd->data->stop)
926 wbsd_send_command(host, cmd->data->stop);
927
928 goto done;
929 };
930
931 /*
913 * Dirty fix for hardware bug. 932 * Dirty fix for hardware bug.
914 */ 933 */
915 if (host->dma == -1) 934 if (host->dma == -1)
@@ -1343,16 +1362,27 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
1343 mmc->max_phys_segs = 128; 1362 mmc->max_phys_segs = 128;
1344 1363
1345 /* 1364 /*
1346 * Maximum number of sectors in one transfer. Also limited by 64kB 1365 * Maximum request size. Also limited by 64KiB buffer.
1347 * buffer.
1348 */ 1366 */
1349 mmc->max_sectors = 128; 1367 mmc->max_req_size = 65536;
1350 1368
1351 /* 1369 /*
1352 * Maximum segment size. Could be one segment with the maximum number 1370 * Maximum segment size. Could be one segment with the maximum number
1353 * of segments. 1371 * of bytes.
1372 */
1373 mmc->max_seg_size = mmc->max_req_size;
1374
1375 /*
1376 * Maximum block size. We have 12 bits (= 4095) but have to subtract
1377 * space for CRC. So the maximum is 4095 - 4*2 = 4087.
1378 */
1379 mmc->max_blk_size = 4087;
1380
1381 /*
1382 * Maximum block count. There is no real limit so the maximum
1383 * request size will be the only restriction.
1354 */ 1384 */
1355 mmc->max_seg_size = mmc->max_sectors * 512; 1385 mmc->max_blk_count = mmc->max_req_size;
1356 1386
1357 dev_set_drvdata(dev, mmc); 1387 dev_set_drvdata(dev, mmc);
1358 1388
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index 6072993f01e3..d06718b0e2ab 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -154,7 +154,6 @@ struct wbsd_host
154 154
155 struct scatterlist* cur_sg; /* Current SG entry */ 155 struct scatterlist* cur_sg; /* Current SG entry */
156 unsigned int num_sg; /* Number of entries left */ 156 unsigned int num_sg; /* Number of entries left */
157 void* mapped_sg; /* vaddr of mapped sg */
158 157
159 unsigned int offset; /* Offset into current entry */ 158 unsigned int offset; /* Offset into current entry */
160 unsigned int remain; /* Data left in curren entry */ 159 unsigned int remain; /* Data left in curren entry */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index bd1faebf61a0..fca978fb158e 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -773,13 +773,13 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
773 goto out; 773 goto out;
774 774
775 table = obj->buffer.pointer; 775 table = obj->buffer.pointer;
776 switch (((acpi_table_entry_header *)table)->type) { 776 switch (((struct acpi_subtable_header *)table)->type) {
777 case ACPI_MADT_IOSAPIC: 777 case ACPI_MADT_TYPE_IO_SAPIC:
778 *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; 778 *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base;
779 result = 0; 779 result = 0;
780 break; 780 break;
781 case ACPI_MADT_IOAPIC: 781 case ACPI_MADT_TYPE_IO_APIC:
782 *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; 782 *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base;
783 result = 0; 783 result = 0;
784 break; 784 break;
785 default: 785 default:
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 5d188c558386..78cf0711d1fa 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -28,6 +28,8 @@
28#include <asm/sn/sn_feature_sets.h> 28#include <asm/sn/sn_feature_sets.h>
29#include <asm/sn/sn_sal.h> 29#include <asm/sn/sn_sal.h>
30#include <asm/sn/types.h> 30#include <asm/sn/types.h>
31#include <linux/acpi.h>
32#include <asm/sn/acpi.h>
31 33
32#include "../pci.h" 34#include "../pci.h"
33 35
@@ -35,14 +37,17 @@ MODULE_LICENSE("GPL");
35MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); 37MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
36MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver"); 38MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
37 39
38#define PCIIO_ASIC_TYPE_TIOCA 4 40
41/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */
39#define PCI_SLOT_ALREADY_UP 2 /* slot already up */ 42#define PCI_SLOT_ALREADY_UP 2 /* slot already up */
40#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */ 43#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */
41#define PCI_L1_ERR 7 /* L1 console command error */ 44#define PCI_L1_ERR 7 /* L1 console command error */
42#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */ 45#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */
46
47
48#define PCIIO_ASIC_TYPE_TIOCA 4
43#define PCI_L1_QSIZE 128 /* our L1 message buffer size */ 49#define PCI_L1_QSIZE 128 /* our L1 message buffer size */
44#define SN_MAX_HP_SLOTS 32 /* max hotplug slots */ 50#define SN_MAX_HP_SLOTS 32 /* max hotplug slots */
45#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */
46#define SN_SLOT_NAME_SIZE 33 /* size of name string */ 51#define SN_SLOT_NAME_SIZE 33 /* size of name string */
47 52
48/* internal list head */ 53/* internal list head */
@@ -227,7 +232,7 @@ static void sn_bus_free_data(struct pci_dev *dev)
227} 232}
228 233
229static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, 234static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
230 int device_num) 235 int device_num, char **ssdt)
231{ 236{
232 struct slot *slot = bss_hotplug_slot->private; 237 struct slot *slot = bss_hotplug_slot->private;
233 struct pcibus_info *pcibus_info; 238 struct pcibus_info *pcibus_info;
@@ -240,7 +245,8 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
240 * Power-on and initialize the slot in the SN 245 * Power-on and initialize the slot in the SN
241 * PCI infrastructure. 246 * PCI infrastructure.
242 */ 247 */
243 rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp); 248 rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt);
249
244 250
245 if (rc == PCI_SLOT_ALREADY_UP) { 251 if (rc == PCI_SLOT_ALREADY_UP) {
246 dev_dbg(slot->pci_bus->self, "is already active\n"); 252 dev_dbg(slot->pci_bus->self, "is already active\n");
@@ -335,6 +341,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
335 int func, num_funcs; 341 int func, num_funcs;
336 int new_ppb = 0; 342 int new_ppb = 0;
337 int rc; 343 int rc;
344 char *ssdt = NULL;
338 void pcibios_fixup_device_resources(struct pci_dev *); 345 void pcibios_fixup_device_resources(struct pci_dev *);
339 346
340 /* Serialize the Linux PCI infrastructure */ 347 /* Serialize the Linux PCI infrastructure */
@@ -342,14 +349,29 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
342 349
343 /* 350 /*
344 * Power-on and initialize the slot in the SN 351 * Power-on and initialize the slot in the SN
345 * PCI infrastructure. 352 * PCI infrastructure. Also, retrieve the ACPI SSDT
353 * table for the slot (if ACPI capable PROM).
346 */ 354 */
347 rc = sn_slot_enable(bss_hotplug_slot, slot->device_num); 355 rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt);
348 if (rc) { 356 if (rc) {
349 mutex_unlock(&sn_hotplug_mutex); 357 mutex_unlock(&sn_hotplug_mutex);
350 return rc; 358 return rc;
351 } 359 }
352 360
361 if (ssdt)
362 ssdt = __va(ssdt);
363 /* Add the new SSDT for the slot to the ACPI namespace */
364 if (SN_ACPI_BASE_SUPPORT() && ssdt) {
365 acpi_status ret;
366
367 ret = acpi_load_table((struct acpi_table_header *)ssdt);
368 if (ACPI_FAILURE(ret)) {
369 printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n",
370 __FUNCTION__, ret);
371 /* try to continue on */
372 }
373 }
374
353 num_funcs = pci_scan_slot(slot->pci_bus, 375 num_funcs = pci_scan_slot(slot->pci_bus,
354 PCI_DEVFN(slot->device_num + 1, 0)); 376 PCI_DEVFN(slot->device_num + 1, 0));
355 if (!num_funcs) { 377 if (!num_funcs) {
@@ -374,7 +396,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
374 * pdi_host_pcidev_info). 396 * pdi_host_pcidev_info).
375 */ 397 */
376 pcibios_fixup_device_resources(dev); 398 pcibios_fixup_device_resources(dev);
377 sn_pci_fixup_slot(dev); 399 if (SN_ACPI_BASE_SUPPORT())
400 sn_acpi_slot_fixup(dev);
401 else
402 sn_io_slot_fixup(dev);
378 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 403 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
379 unsigned char sec_bus; 404 unsigned char sec_bus;
380 pci_read_config_byte(dev, PCI_SECONDARY_BUS, 405 pci_read_config_byte(dev, PCI_SECONDARY_BUS,
@@ -388,6 +413,63 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
388 } 413 }
389 } 414 }
390 415
416 /*
417 * Add the slot's devices to the ACPI infrastructure */
418 if (SN_ACPI_BASE_SUPPORT() && ssdt) {
419 unsigned long adr;
420 struct acpi_device *pdevice;
421 struct acpi_device *device;
422 acpi_handle phandle;
423 acpi_handle chandle = NULL;
424 acpi_handle rethandle;
425 acpi_status ret;
426
427 phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
428
429 if (acpi_bus_get_device(phandle, &pdevice)) {
430 dev_dbg(slot->pci_bus->self,
431 "no parent device, assuming NULL\n");
432 pdevice = NULL;
433 }
434
435 /*
436 * Walk the rootbus node's immediate children looking for
437 * the slot's device node(s). There can be more than
438 * one for multifunction devices.
439 */
440 for (;;) {
441 rethandle = NULL;
442 ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
443 phandle, chandle,
444 &rethandle);
445
446 if (ret == AE_NOT_FOUND || rethandle == NULL)
447 break;
448
449 chandle = rethandle;
450
451 ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR,
452 NULL, &adr);
453
454 if (ACPI_SUCCESS(ret) &&
455 (adr>>16) == (slot->device_num + 1)) {
456
457 ret = acpi_bus_add(&device, pdevice, chandle,
458 ACPI_BUS_TYPE_DEVICE);
459 if (ACPI_FAILURE(ret)) {
460 printk(KERN_ERR "%s: acpi_bus_add "
461 "failed (0x%x) for slot %d "
462 "func %d\n", __FUNCTION__,
463 ret, (int)(adr>>16),
464 (int)(adr&0xffff));
465 /* try to continue on */
466 } else {
467 acpi_bus_start(device);
468 }
469 }
470 }
471 }
472
391 /* Call the driver for the new device */ 473 /* Call the driver for the new device */
392 pci_bus_add_devices(slot->pci_bus); 474 pci_bus_add_devices(slot->pci_bus);
393 /* Call the drivers for the new devices subordinate to PPB */ 475 /* Call the drivers for the new devices subordinate to PPB */
@@ -412,6 +494,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
412 struct pci_dev *dev; 494 struct pci_dev *dev;
413 int func; 495 int func;
414 int rc; 496 int rc;
497 acpi_owner_id ssdt_id = 0;
415 498
416 /* Acquire update access to the bus */ 499 /* Acquire update access to the bus */
417 mutex_lock(&sn_hotplug_mutex); 500 mutex_lock(&sn_hotplug_mutex);
@@ -422,6 +505,52 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
422 if (rc) 505 if (rc)
423 goto leaving; 506 goto leaving;
424 507
508 /* free the ACPI resources for the slot */
509 if (SN_ACPI_BASE_SUPPORT() &&
510 PCI_CONTROLLER(slot->pci_bus)->acpi_handle) {
511 unsigned long adr;
512 struct acpi_device *device;
513 acpi_handle phandle;
514 acpi_handle chandle = NULL;
515 acpi_handle rethandle;
516 acpi_status ret;
517
518 /* Get the rootbus node pointer */
519 phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
520
521 /*
522 * Walk the rootbus node's immediate children looking for
523 * the slot's device node(s). There can be more than
524 * one for multifunction devices.
525 */
526 for (;;) {
527 rethandle = NULL;
528 ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
529 phandle, chandle,
530 &rethandle);
531
532 if (ret == AE_NOT_FOUND || rethandle == NULL)
533 break;
534
535 chandle = rethandle;
536
537 ret = acpi_evaluate_integer(chandle,
538 METHOD_NAME__ADR,
539 NULL, &adr);
540 if (ACPI_SUCCESS(ret) &&
541 (adr>>16) == (slot->device_num + 1)) {
542 /* retain the owner id */
543 acpi_get_id(chandle, &ssdt_id);
544
545 ret = acpi_bus_get_device(chandle,
546 &device);
547 if (ACPI_SUCCESS(ret))
548 acpi_bus_trim(device, 1);
549 }
550 }
551
552 }
553
425 /* Free the SN resources assigned to the Linux device.*/ 554 /* Free the SN resources assigned to the Linux device.*/
426 for (func = 0; func < 8; func++) { 555 for (func = 0; func < 8; func++) {
427 dev = pci_get_slot(slot->pci_bus, 556 dev = pci_get_slot(slot->pci_bus,
@@ -434,6 +563,18 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
434 } 563 }
435 } 564 }
436 565
566 /* Remove the SSDT for the slot from the ACPI namespace */
567 if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {
568 acpi_status ret;
569 ret = acpi_unload_table_id(ssdt_id);
570 if (ACPI_FAILURE(ret)) {
571 printk(KERN_ERR "%s: acpi_unload_table_id "
572 "failed (0x%x) for id %d\n",
573 __FUNCTION__, ret, ssdt_id);
574 /* try to continue on */
575 }
576 }
577
437 /* free the collected sysdata pointers */ 578 /* free the collected sysdata pointers */
438 sn_bus_free_sysdata(); 579 sn_bus_free_sysdata();
439 580
diff --git a/drivers/pnp/pnpacpi/Kconfig b/drivers/pnp/pnpacpi/Kconfig
index b1854171b963..ad27e5e0101f 100644
--- a/drivers/pnp/pnpacpi/Kconfig
+++ b/drivers/pnp/pnpacpi/Kconfig
@@ -2,8 +2,8 @@
2# Plug and Play ACPI configuration 2# Plug and Play ACPI configuration
3# 3#
4config PNPACPI 4config PNPACPI
5 bool "Plug and Play ACPI support (EXPERIMENTAL)" 5 bool "Plug and Play ACPI support"
6 depends on PNP && ACPI && EXPERIMENTAL 6 depends on PNP && ACPI
7 default y 7 default y
8 ---help--- 8 ---help---
9 Linux uses the PNPACPI to autodetect built-in 9 Linux uses the PNPACPI to autodetect built-in
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index d42015c382af..2065e74bb63f 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -3,7 +3,8 @@
3 * 3 *
4 * Some code is based on pnpbios_core.c 4 * Some code is based on pnpbios_core.c
5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com> 5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
6 * 6 * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
7 */ 8 */
8 9
9#include <linux/pnp.h> 10#include <linux/pnp.h>
@@ -21,18 +22,21 @@ static const struct pnp_device_id pnp_dev_table[] = {
21 { "", 0 } 22 { "", 0 }
22}; 23};
23 24
24static void reserve_ioport_range(char *pnpid, int start, int end) 25static void reserve_range(char *pnpid, int start, int end, int port)
25{ 26{
26 struct resource *res; 27 struct resource *res;
27 char *regionid; 28 char *regionid;
28 29
29 regionid = kmalloc(16, GFP_KERNEL); 30 regionid = kmalloc(16, GFP_KERNEL);
30 if ( regionid == NULL ) 31 if (regionid == NULL)
31 return; 32 return;
32 snprintf(regionid, 16, "pnp %s", pnpid); 33 snprintf(regionid, 16, "pnp %s", pnpid);
33 res = request_region(start,end-start+1,regionid); 34 if (port)
34 if ( res == NULL ) 35 res = request_region(start,end-start+1,regionid);
35 kfree( regionid ); 36 else
37 res = request_mem_region(start,end-start+1,regionid);
38 if (res == NULL)
39 kfree(regionid);
36 else 40 else
37 res->flags &= ~IORESOURCE_BUSY; 41 res->flags &= ~IORESOURCE_BUSY;
38 /* 42 /*
@@ -41,26 +45,20 @@ static void reserve_ioport_range(char *pnpid, int start, int end)
41 * have double reservations. 45 * have double reservations.
42 */ 46 */
43 printk(KERN_INFO 47 printk(KERN_INFO
44 "pnp: %s: ioport range 0x%x-0x%x %s reserved\n", 48 "pnp: %s: %s range 0x%x-0x%x %s reserved\n",
45 pnpid, start, end, 49 pnpid, port ? "ioport" : "iomem", start, end,
46 NULL != res ? "has been" : "could not be" 50 NULL != res ? "has been" : "could not be");
47 );
48
49 return;
50} 51}
51 52
52static void reserve_resources_of_dev( struct pnp_dev *dev ) 53static void reserve_resources_of_dev(struct pnp_dev *dev)
53{ 54{
54 int i; 55 int i;
55 56
56 for (i=0;i<PNP_MAX_PORT;i++) { 57 for (i = 0; i < PNP_MAX_PORT; i++) {
57 if (!pnp_port_valid(dev, i)) 58 if (!pnp_port_valid(dev, i))
58 /* end of resources */
59 continue; 59 continue;
60 if (pnp_port_start(dev, i) == 0) 60 if (pnp_port_start(dev, i) == 0)
61 /* disabled */ 61 continue; /* disabled */
62 /* Do nothing */
63 continue;
64 if (pnp_port_start(dev, i) < 0x100) 62 if (pnp_port_start(dev, i) < 0x100)
65 /* 63 /*
66 * Below 0x100 is only standard PC hardware 64 * Below 0x100 is only standard PC hardware
@@ -72,14 +70,18 @@ static void reserve_resources_of_dev( struct pnp_dev *dev )
72 */ 70 */
73 continue; 71 continue;
74 if (pnp_port_end(dev, i) < pnp_port_start(dev, i)) 72 if (pnp_port_end(dev, i) < pnp_port_start(dev, i))
75 /* invalid endpoint */ 73 continue; /* invalid */
76 /* Do nothing */ 74
75 reserve_range(dev->dev.bus_id, pnp_port_start(dev, i),
76 pnp_port_end(dev, i), 1);
77 }
78
79 for (i = 0; i < PNP_MAX_MEM; i++) {
80 if (!pnp_mem_valid(dev, i))
77 continue; 81 continue;
78 reserve_ioport_range( 82
79 dev->dev.bus_id, 83 reserve_range(dev->dev.bus_id, pnp_mem_start(dev, i),
80 pnp_port_start(dev, i), 84 pnp_mem_end(dev, i), 0);
81 pnp_port_end(dev, i)
82 );
83 } 85 }
84 86
85 return; 87 return;
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
index ae89b9b88743..165af398fdea 100644
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -103,14 +103,8 @@ config CCW_CONSOLE
103 depends on TN3215_CONSOLE || TN3270_CONSOLE 103 depends on TN3215_CONSOLE || TN3270_CONSOLE
104 default y 104 default y
105 105
106config SCLP
107 bool "Support for SCLP"
108 help
109 Include support for the SCLP interface to the service element.
110
111config SCLP_TTY 106config SCLP_TTY
112 bool "Support for SCLP line mode terminal" 107 bool "Support for SCLP line mode terminal"
113 depends on SCLP
114 help 108 help
115 Include support for IBM SCLP line-mode terminals. 109 Include support for IBM SCLP line-mode terminals.
116 110
@@ -123,7 +117,6 @@ config SCLP_CONSOLE
123 117
124config SCLP_VT220_TTY 118config SCLP_VT220_TTY
125 bool "Support for SCLP VT220-compatible terminal" 119 bool "Support for SCLP VT220-compatible terminal"
126 depends on SCLP
127 help 120 help
128 Include support for an IBM SCLP VT220-compatible terminal. 121 Include support for an IBM SCLP VT220-compatible terminal.
129 122
@@ -136,7 +129,6 @@ config SCLP_VT220_CONSOLE
136 129
137config SCLP_CPI 130config SCLP_CPI
138 tristate "Control-Program Identification" 131 tristate "Control-Program Identification"
139 depends on SCLP
140 help 132 help
141 This option enables the hardware console interface for system 133 This option enables the hardware console interface for system
142 identification. This is commonly used for workload management and 134 identification. This is commonly used for workload management and
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
index 9803c9352d78..5a888704a8d0 100644
--- a/drivers/s390/Makefile
+++ b/drivers/s390/Makefile
@@ -2,6 +2,8 @@
2# Makefile for the S/390 specific device drivers 2# Makefile for the S/390 specific device drivers
3# 3#
4 4
5CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
6
5obj-y += s390mach.o sysinfo.o s390_rdev.o 7obj-y += s390mach.o sysinfo.o s390_rdev.o
6obj-y += cio/ block/ char/ crypto/ net/ scsi/ 8obj-y += cio/ block/ char/ crypto/ net/ scsi/
7 9
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 492b68bcd7cc..eb5dc62f0d9c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -37,6 +37,7 @@
37 */ 37 */
38debug_info_t *dasd_debug_area; 38debug_info_t *dasd_debug_area;
39struct dasd_discipline *dasd_diag_discipline_pointer; 39struct dasd_discipline *dasd_diag_discipline_pointer;
40void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
40 41
41MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>"); 42MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
42MODULE_DESCRIPTION("Linux on S/390 DASD device driver," 43MODULE_DESCRIPTION("Linux on S/390 DASD device driver,"
@@ -51,7 +52,6 @@ static int dasd_alloc_queue(struct dasd_device * device);
51static void dasd_setup_queue(struct dasd_device * device); 52static void dasd_setup_queue(struct dasd_device * device);
52static void dasd_free_queue(struct dasd_device * device); 53static void dasd_free_queue(struct dasd_device * device);
53static void dasd_flush_request_queue(struct dasd_device *); 54static void dasd_flush_request_queue(struct dasd_device *);
54static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
55static int dasd_flush_ccw_queue(struct dasd_device *, int); 55static int dasd_flush_ccw_queue(struct dasd_device *, int);
56static void dasd_tasklet(struct dasd_device *); 56static void dasd_tasklet(struct dasd_device *);
57static void do_kick_device(struct work_struct *); 57static void do_kick_device(struct work_struct *);
@@ -483,7 +483,7 @@ unsigned int dasd_profile_level = DASD_PROFILE_OFF;
483/* 483/*
484 * Add profiling information for cqr before execution. 484 * Add profiling information for cqr before execution.
485 */ 485 */
486static inline void 486static void
487dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr, 487dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
488 struct request *req) 488 struct request *req)
489{ 489{
@@ -505,7 +505,7 @@ dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr,
505/* 505/*
506 * Add profiling information for cqr after execution. 506 * Add profiling information for cqr after execution.
507 */ 507 */
508static inline void 508static void
509dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr, 509dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr,
510 struct request *req) 510 struct request *req)
511{ 511{
@@ -1022,8 +1022,6 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1022 irb->scsw.cstat == 0 && 1022 irb->scsw.cstat == 0 &&
1023 !irb->esw.esw0.erw.cons) 1023 !irb->esw.esw0.erw.cons)
1024 era = dasd_era_none; 1024 era = dasd_era_none;
1025 else if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags))
1026 era = dasd_era_fatal; /* don't recover this request */
1027 else if (irb->esw.esw0.erw.cons) 1025 else if (irb->esw.esw0.erw.cons)
1028 era = device->discipline->examine_error(cqr, irb); 1026 era = device->discipline->examine_error(cqr, irb);
1029 else 1027 else
@@ -1104,7 +1102,7 @@ __dasd_process_erp(struct dasd_device *device, struct dasd_ccw_req *cqr)
1104/* 1102/*
1105 * Process ccw request queue. 1103 * Process ccw request queue.
1106 */ 1104 */
1107static inline void 1105static void
1108__dasd_process_ccw_queue(struct dasd_device * device, 1106__dasd_process_ccw_queue(struct dasd_device * device,
1109 struct list_head *final_queue) 1107 struct list_head *final_queue)
1110{ 1108{
@@ -1127,7 +1125,9 @@ restart:
1127 cqr->status = DASD_CQR_FAILED; 1125 cqr->status = DASD_CQR_FAILED;
1128 cqr->stopclk = get_clock(); 1126 cqr->stopclk = get_clock();
1129 } else { 1127 } else {
1130 if (cqr->irb.esw.esw0.erw.cons) { 1128 if (cqr->irb.esw.esw0.erw.cons &&
1129 test_bit(DASD_CQR_FLAGS_USE_ERP,
1130 &cqr->flags)) {
1131 erp_fn = device->discipline-> 1131 erp_fn = device->discipline->
1132 erp_action(cqr); 1132 erp_action(cqr);
1133 erp_fn(cqr); 1133 erp_fn(cqr);
@@ -1181,7 +1181,7 @@ dasd_end_request_cb(struct dasd_ccw_req * cqr, void *data)
1181/* 1181/*
1182 * Fetch requests from the block device queue. 1182 * Fetch requests from the block device queue.
1183 */ 1183 */
1184static inline void 1184static void
1185__dasd_process_blk_queue(struct dasd_device * device) 1185__dasd_process_blk_queue(struct dasd_device * device)
1186{ 1186{
1187 request_queue_t *queue; 1187 request_queue_t *queue;
@@ -1232,6 +1232,19 @@ __dasd_process_blk_queue(struct dasd_device * device)
1232 if (IS_ERR(cqr)) { 1232 if (IS_ERR(cqr)) {
1233 if (PTR_ERR(cqr) == -ENOMEM) 1233 if (PTR_ERR(cqr) == -ENOMEM)
1234 break; /* terminate request queue loop */ 1234 break; /* terminate request queue loop */
1235 if (PTR_ERR(cqr) == -EAGAIN) {
1236 /*
1237 * The current request cannot be build right
1238 * now, we have to try later. If this request
1239 * is the head-of-queue we stop the device
1240 * for 1/2 second.
1241 */
1242 if (!list_empty(&device->ccw_queue))
1243 break;
1244 device->stopped |= DASD_STOPPED_PENDING;
1245 dasd_set_timer(device, HZ/2);
1246 break;
1247 }
1235 DBF_DEV_EVENT(DBF_ERR, device, 1248 DBF_DEV_EVENT(DBF_ERR, device,
1236 "CCW creation failed (rc=%ld) " 1249 "CCW creation failed (rc=%ld) "
1237 "on request %p", 1250 "on request %p",
@@ -1254,7 +1267,7 @@ __dasd_process_blk_queue(struct dasd_device * device)
1254 * Take a look at the first request on the ccw queue and check 1267 * Take a look at the first request on the ccw queue and check
1255 * if it reached its expire time. If so, terminate the IO. 1268 * if it reached its expire time. If so, terminate the IO.
1256 */ 1269 */
1257static inline void 1270static void
1258__dasd_check_expire(struct dasd_device * device) 1271__dasd_check_expire(struct dasd_device * device)
1259{ 1272{
1260 struct dasd_ccw_req *cqr; 1273 struct dasd_ccw_req *cqr;
@@ -1285,7 +1298,7 @@ __dasd_check_expire(struct dasd_device * device)
1285 * Take a look at the first request on the ccw queue and check 1298 * Take a look at the first request on the ccw queue and check
1286 * if it needs to be started. 1299 * if it needs to be started.
1287 */ 1300 */
1288static inline void 1301static void
1289__dasd_start_head(struct dasd_device * device) 1302__dasd_start_head(struct dasd_device * device)
1290{ 1303{
1291 struct dasd_ccw_req *cqr; 1304 struct dasd_ccw_req *cqr;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 4d01040c2c63..8b9d68f6e016 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -170,7 +170,6 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
170 /* log the erp chain if fatal error occurred */ 170 /* log the erp chain if fatal error occurred */
171 if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) { 171 if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) {
172 dasd_log_sense(cqr, irb); 172 dasd_log_sense(cqr, irb);
173 dasd_log_ccw(cqr, 0, irb->scsw.cpa);
174 } 173 }
175 174
176 return era; 175 return era;
@@ -2640,7 +2639,6 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2640 2639
2641 struct dasd_ccw_req *erp = NULL; 2640 struct dasd_ccw_req *erp = NULL;
2642 struct dasd_device *device = cqr->device; 2641 struct dasd_device *device = cqr->device;
2643 __u32 cpa = cqr->irb.scsw.cpa;
2644 struct dasd_ccw_req *temp_erp = NULL; 2642 struct dasd_ccw_req *temp_erp = NULL;
2645 2643
2646 if (device->features & DASD_FEATURE_ERPLOG) { 2644 if (device->features & DASD_FEATURE_ERPLOG) {
@@ -2706,9 +2704,6 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2706 } 2704 }
2707 } 2705 }
2708 2706
2709 if (erp->status == DASD_CQR_FAILED)
2710 dasd_log_ccw(erp, 1, cpa);
2711
2712 /* enqueue added ERP request */ 2707 /* enqueue added ERP request */
2713 if (erp->status == DASD_CQR_FILLED) { 2708 if (erp->status == DASD_CQR_FILLED) {
2714 erp->status = DASD_CQR_QUEUED; 2709 erp->status = DASD_CQR_QUEUED;
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 5943266152f5..ed70852cc915 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -136,7 +136,7 @@ __setup ("dasd=", dasd_call_setup);
136/* 136/*
137 * Read a device busid/devno from a string. 137 * Read a device busid/devno from a string.
138 */ 138 */
139static inline int 139static int
140dasd_busid(char **str, int *id0, int *id1, int *devno) 140dasd_busid(char **str, int *id0, int *id1, int *devno)
141{ 141{
142 int val, old_style; 142 int val, old_style;
@@ -182,7 +182,7 @@ dasd_busid(char **str, int *id0, int *id1, int *devno)
182 * only one: "ro" for read-only devices. The default feature set 182 * only one: "ro" for read-only devices. The default feature set
183 * is empty (value 0). 183 * is empty (value 0).
184 */ 184 */
185static inline int 185static int
186dasd_feature_list(char *str, char **endp) 186dasd_feature_list(char *str, char **endp)
187{ 187{
188 int features, len, rc; 188 int features, len, rc;
@@ -341,7 +341,7 @@ dasd_parse_range( char *parsestring ) {
341 return ERR_PTR(-EINVAL); 341 return ERR_PTR(-EINVAL);
342} 342}
343 343
344static inline char * 344static char *
345dasd_parse_next_element( char *parsestring ) { 345dasd_parse_next_element( char *parsestring ) {
346 char * residual_str; 346 char * residual_str;
347 residual_str = dasd_parse_keyword(parsestring); 347 residual_str = dasd_parse_keyword(parsestring);
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 53db58a68617..ab782bb46ac1 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
43#define DIAG_MAX_RETRIES 32 43#define DIAG_MAX_RETRIES 32
44#define DIAG_TIMEOUT 50 * HZ 44#define DIAG_TIMEOUT 50 * HZ
45 45
46struct dasd_discipline dasd_diag_discipline; 46static struct dasd_discipline dasd_diag_discipline;
47 47
48struct dasd_diag_private { 48struct dasd_diag_private {
49 struct dasd_diag_characteristics rdc_data; 49 struct dasd_diag_characteristics rdc_data;
@@ -90,7 +90,7 @@ static inline int dia250(void *iob, int cmd)
90 * block offset. On success, return zero and set end_block to contain the 90 * block offset. On success, return zero and set end_block to contain the
91 * number of blocks on the device minus the specified offset. Return non-zero 91 * number of blocks on the device minus the specified offset. Return non-zero
92 * otherwise. */ 92 * otherwise. */
93static __inline__ int 93static inline int
94mdsk_init_io(struct dasd_device *device, unsigned int blocksize, 94mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
95 blocknum_t offset, blocknum_t *end_block) 95 blocknum_t offset, blocknum_t *end_block)
96{ 96{
@@ -117,7 +117,7 @@ mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
117 117
118/* Remove block I/O environment for device. Return zero on success, non-zero 118/* Remove block I/O environment for device. Return zero on success, non-zero
119 * otherwise. */ 119 * otherwise. */
120static __inline__ int 120static inline int
121mdsk_term_io(struct dasd_device * device) 121mdsk_term_io(struct dasd_device * device)
122{ 122{
123 struct dasd_diag_private *private; 123 struct dasd_diag_private *private;
@@ -576,7 +576,7 @@ dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
576 "dump sense not available for DIAG data"); 576 "dump sense not available for DIAG data");
577} 577}
578 578
579struct dasd_discipline dasd_diag_discipline = { 579static struct dasd_discipline dasd_diag_discipline = {
580 .owner = THIS_MODULE, 580 .owner = THIS_MODULE,
581 .name = "DIAG", 581 .name = "DIAG",
582 .ebcname = "DIAG", 582 .ebcname = "DIAG",
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index fdaa471e845f..cecab2274a6e 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -134,44 +134,7 @@ ceil_quot(unsigned int d1, unsigned int d2)
134 return (d1 + (d2 - 1)) / d2; 134 return (d1 + (d2 - 1)) / d2;
135} 135}
136 136
137static inline int 137static unsigned int
138bytes_per_record(struct dasd_eckd_characteristics *rdc, int kl, int dl)
139{
140 unsigned int fl1, fl2, int1, int2;
141 int bpr;
142
143 switch (rdc->formula) {
144 case 0x01:
145 fl1 = round_up_multiple(ECKD_F2(rdc) + dl, ECKD_F1(rdc));
146 fl2 = round_up_multiple(kl ? ECKD_F2(rdc) + kl : 0,
147 ECKD_F1(rdc));
148 bpr = fl1 + fl2;
149 break;
150 case 0x02:
151 int1 = ceil_quot(dl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
152 int2 = ceil_quot(kl + ECKD_F6(rdc), ECKD_F5(rdc) << 1);
153 fl1 = round_up_multiple(ECKD_F1(rdc) * ECKD_F2(rdc) + dl +
154 ECKD_F6(rdc) + ECKD_F4(rdc) * int1,
155 ECKD_F1(rdc));
156 fl2 = round_up_multiple(ECKD_F1(rdc) * ECKD_F3(rdc) + kl +
157 ECKD_F6(rdc) + ECKD_F4(rdc) * int2,
158 ECKD_F1(rdc));
159 bpr = fl1 + fl2;
160 break;
161 default:
162 bpr = 0;
163 break;
164 }
165 return bpr;
166}
167
168static inline unsigned int
169bytes_per_track(struct dasd_eckd_characteristics *rdc)
170{
171 return *(unsigned int *) (rdc->byte_per_track) >> 8;
172}
173
174static inline unsigned int
175recs_per_track(struct dasd_eckd_characteristics * rdc, 138recs_per_track(struct dasd_eckd_characteristics * rdc,
176 unsigned int kl, unsigned int dl) 139 unsigned int kl, unsigned int dl)
177{ 140{
@@ -204,37 +167,39 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
204 return 0; 167 return 0;
205} 168}
206 169
207static inline void 170static int
208check_XRC (struct ccw1 *de_ccw, 171check_XRC (struct ccw1 *de_ccw,
209 struct DE_eckd_data *data, 172 struct DE_eckd_data *data,
210 struct dasd_device *device) 173 struct dasd_device *device)
211{ 174{
212 struct dasd_eckd_private *private; 175 struct dasd_eckd_private *private;
176 int rc;
213 177
214 private = (struct dasd_eckd_private *) device->private; 178 private = (struct dasd_eckd_private *) device->private;
179 if (!private->rdc_data.facilities.XRC_supported)
180 return 0;
215 181
216 /* switch on System Time Stamp - needed for XRC Support */ 182 /* switch on System Time Stamp - needed for XRC Support */
217 if (private->rdc_data.facilities.XRC_supported) { 183 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
218 184 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
219 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
220 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
221
222 data->ep_sys_time = get_clock ();
223
224 de_ccw->count = sizeof (struct DE_eckd_data);
225 de_ccw->flags |= CCW_FLAG_SLI;
226 }
227 185
228 return; 186 rc = get_sync_clock(&data->ep_sys_time);
187 /* Ignore return code if sync clock is switched off. */
188 if (rc == -ENOSYS || rc == -EACCES)
189 rc = 0;
229 190
230} /* end check_XRC */ 191 de_ccw->count = sizeof (struct DE_eckd_data);
192 de_ccw->flags |= CCW_FLAG_SLI;
193 return rc;
194}
231 195
232static inline void 196static int
233define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, 197define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
234 int totrk, int cmd, struct dasd_device * device) 198 int totrk, int cmd, struct dasd_device * device)
235{ 199{
236 struct dasd_eckd_private *private; 200 struct dasd_eckd_private *private;
237 struct ch_t geo, beg, end; 201 struct ch_t geo, beg, end;
202 int rc = 0;
238 203
239 private = (struct dasd_eckd_private *) device->private; 204 private = (struct dasd_eckd_private *) device->private;
240 205
@@ -263,12 +228,12 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
263 case DASD_ECKD_CCW_WRITE_KD_MT: 228 case DASD_ECKD_CCW_WRITE_KD_MT:
264 data->mask.perm = 0x02; 229 data->mask.perm = 0x02;
265 data->attributes.operation = private->attrib.operation; 230 data->attributes.operation = private->attrib.operation;
266 check_XRC (ccw, data, device); 231 rc = check_XRC (ccw, data, device);
267 break; 232 break;
268 case DASD_ECKD_CCW_WRITE_CKD: 233 case DASD_ECKD_CCW_WRITE_CKD:
269 case DASD_ECKD_CCW_WRITE_CKD_MT: 234 case DASD_ECKD_CCW_WRITE_CKD_MT:
270 data->attributes.operation = DASD_BYPASS_CACHE; 235 data->attributes.operation = DASD_BYPASS_CACHE;
271 check_XRC (ccw, data, device); 236 rc = check_XRC (ccw, data, device);
272 break; 237 break;
273 case DASD_ECKD_CCW_ERASE: 238 case DASD_ECKD_CCW_ERASE:
274 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: 239 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
@@ -276,7 +241,7 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
276 data->mask.perm = 0x3; 241 data->mask.perm = 0x3;
277 data->mask.auth = 0x1; 242 data->mask.auth = 0x1;
278 data->attributes.operation = DASD_BYPASS_CACHE; 243 data->attributes.operation = DASD_BYPASS_CACHE;
279 check_XRC (ccw, data, device); 244 rc = check_XRC (ccw, data, device);
280 break; 245 break;
281 default: 246 default:
282 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd); 247 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
@@ -312,9 +277,10 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
312 data->beg_ext.head = beg.head; 277 data->beg_ext.head = beg.head;
313 data->end_ext.cyl = end.cyl; 278 data->end_ext.cyl = end.cyl;
314 data->end_ext.head = end.head; 279 data->end_ext.head = end.head;
280 return rc;
315} 281}
316 282
317static inline void 283static void
318locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, 284locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
319 int rec_on_trk, int no_rec, int cmd, 285 int rec_on_trk, int no_rec, int cmd,
320 struct dasd_device * device, int reclen) 286 struct dasd_device * device, int reclen)
@@ -548,7 +514,7 @@ dasd_eckd_read_conf(struct dasd_device *device)
548/* 514/*
549 * Build CP for Perform Subsystem Function - SSC. 515 * Build CP for Perform Subsystem Function - SSC.
550 */ 516 */
551struct dasd_ccw_req * 517static struct dasd_ccw_req *
552dasd_eckd_build_psf_ssc(struct dasd_device *device) 518dasd_eckd_build_psf_ssc(struct dasd_device *device)
553{ 519{
554 struct dasd_ccw_req *cqr; 520 struct dasd_ccw_req *cqr;
@@ -1200,7 +1166,12 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
1200 return cqr; 1166 return cqr;
1201 ccw = cqr->cpaddr; 1167 ccw = cqr->cpaddr;
1202 /* First ccw is define extent. */ 1168 /* First ccw is define extent. */
1203 define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device); 1169 if (define_extent(ccw++, cqr->data, first_trk,
1170 last_trk, cmd, device) == -EAGAIN) {
1171 /* Clock not in sync and XRC is enabled. Try again later. */
1172 dasd_sfree_request(cqr, device);
1173 return ERR_PTR(-EAGAIN);
1174 }
1204 /* Build locate_record+read/write/ccws. */ 1175 /* Build locate_record+read/write/ccws. */
1205 idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data)); 1176 idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data));
1206 LO_data = (struct LO_eckd_data *) (idaws + cidaw); 1177 LO_data = (struct LO_eckd_data *) (idaws + cidaw);
@@ -1380,7 +1351,7 @@ dasd_eckd_release(struct dasd_device *device)
1380 cqr->device = device; 1351 cqr->device = device;
1381 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1352 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1382 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1353 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
1383 cqr->retries = 0; 1354 cqr->retries = 2; /* set retry counter to enable basic ERP */
1384 cqr->expires = 2 * HZ; 1355 cqr->expires = 2 * HZ;
1385 cqr->buildclk = get_clock(); 1356 cqr->buildclk = get_clock();
1386 cqr->status = DASD_CQR_FILLED; 1357 cqr->status = DASD_CQR_FILLED;
@@ -1420,7 +1391,7 @@ dasd_eckd_reserve(struct dasd_device *device)
1420 cqr->device = device; 1391 cqr->device = device;
1421 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1392 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1422 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1393 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
1423 cqr->retries = 0; 1394 cqr->retries = 2; /* set retry counter to enable basic ERP */
1424 cqr->expires = 2 * HZ; 1395 cqr->expires = 2 * HZ;
1425 cqr->buildclk = get_clock(); 1396 cqr->buildclk = get_clock();
1426 cqr->status = DASD_CQR_FILLED; 1397 cqr->status = DASD_CQR_FILLED;
@@ -1459,7 +1430,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
1459 cqr->device = device; 1430 cqr->device = device;
1460 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1431 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
1461 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1432 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
1462 cqr->retries = 0; 1433 cqr->retries = 2; /* set retry counter to enable basic ERP */
1463 cqr->expires = 2 * HZ; 1434 cqr->expires = 2 * HZ;
1464 cqr->buildclk = get_clock(); 1435 cqr->buildclk = get_clock();
1465 cqr->status = DASD_CQR_FILLED; 1436 cqr->status = DASD_CQR_FILLED;
@@ -1609,7 +1580,7 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
1609 * Dump the range of CCWs into 'page' buffer 1580 * Dump the range of CCWs into 'page' buffer
1610 * and return number of printed chars. 1581 * and return number of printed chars.
1611 */ 1582 */
1612static inline int 1583static int
1613dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) 1584dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
1614{ 1585{
1615 int len, count; 1586 int len, count;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index e0bf30ebb215..6cedc914077e 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -658,18 +658,24 @@ static struct file_operations dasd_eer_fops = {
658 .owner = THIS_MODULE, 658 .owner = THIS_MODULE,
659}; 659};
660 660
661static struct miscdevice dasd_eer_dev = { 661static struct miscdevice *dasd_eer_dev = NULL;
662 .minor = MISC_DYNAMIC_MINOR,
663 .name = "dasd_eer",
664 .fops = &dasd_eer_fops,
665};
666 662
667int __init dasd_eer_init(void) 663int __init dasd_eer_init(void)
668{ 664{
669 int rc; 665 int rc;
670 666
671 rc = misc_register(&dasd_eer_dev); 667 dasd_eer_dev = kzalloc(sizeof(*dasd_eer_dev), GFP_KERNEL);
668 if (!dasd_eer_dev)
669 return -ENOMEM;
670
671 dasd_eer_dev->minor = MISC_DYNAMIC_MINOR;
672 dasd_eer_dev->name = "dasd_eer";
673 dasd_eer_dev->fops = &dasd_eer_fops;
674
675 rc = misc_register(dasd_eer_dev);
672 if (rc) { 676 if (rc) {
677 kfree(dasd_eer_dev);
678 dasd_eer_dev = NULL;
673 MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " 679 MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
674 "register misc device"); 680 "register misc device");
675 return rc; 681 return rc;
@@ -680,5 +686,9 @@ int __init dasd_eer_init(void)
680 686
681void dasd_eer_exit(void) 687void dasd_eer_exit(void)
682{ 688{
683 WARN_ON(misc_deregister(&dasd_eer_dev) != 0); 689 if (dasd_eer_dev) {
690 WARN_ON(misc_deregister(dasd_eer_dev) != 0);
691 kfree(dasd_eer_dev);
692 dasd_eer_dev = NULL;
693 }
684} 694}
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 58a65097922b..caa5d91420f8 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -152,25 +152,6 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr)
152 152
153} /* end default_erp_postaction */ 153} /* end default_erp_postaction */
154 154
155/*
156 * Print the hex dump of the memory used by a request. This includes
157 * all error recovery ccws that have been chained in from of the
158 * real request.
159 */
160static inline void
161hex_dump_memory(struct dasd_device *device, void *data, int len)
162{
163 int *pint;
164
165 pint = (int *) data;
166 while (len > 0) {
167 DEV_MESSAGE(KERN_ERR, device, "%p: %08x %08x %08x %08x",
168 pint, pint[0], pint[1], pint[2], pint[3]);
169 pint += 4;
170 len -= 16;
171 }
172}
173
174void 155void
175dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb) 156dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
176{ 157{
@@ -182,69 +163,8 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
182 device->discipline->dump_sense(device, cqr, irb); 163 device->discipline->dump_sense(device, cqr, irb);
183} 164}
184 165
185void
186dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa)
187{
188 struct dasd_device *device;
189 struct dasd_ccw_req *lcqr;
190 struct ccw1 *ccw;
191 int cplength;
192
193 device = cqr->device;
194 /* log the channel program */
195 for (lcqr = cqr; lcqr != NULL; lcqr = lcqr->refers) {
196 DEV_MESSAGE(KERN_ERR, device,
197 "(%s) ERP chain report for req: %p",
198 caller == 0 ? "EXAMINE" : "ACTION", lcqr);
199 hex_dump_memory(device, lcqr, sizeof(struct dasd_ccw_req));
200
201 cplength = 1;
202 ccw = lcqr->cpaddr;
203 while (ccw++->flags & (CCW_FLAG_DC | CCW_FLAG_CC))
204 cplength++;
205
206 if (cplength > 40) { /* log only parts of the CP */
207 DEV_MESSAGE(KERN_ERR, device, "%s",
208 "Start of channel program:");
209 hex_dump_memory(device, lcqr->cpaddr,
210 40*sizeof(struct ccw1));
211
212 DEV_MESSAGE(KERN_ERR, device, "%s",
213 "End of channel program:");
214 hex_dump_memory(device, lcqr->cpaddr + cplength - 10,
215 10*sizeof(struct ccw1));
216 } else { /* log the whole CP */
217 DEV_MESSAGE(KERN_ERR, device, "%s",
218 "Channel program (complete):");
219 hex_dump_memory(device, lcqr->cpaddr,
220 cplength*sizeof(struct ccw1));
221 }
222
223 if (lcqr != cqr)
224 continue;
225
226 /*
227 * Log bytes arround failed CCW but only if we did
228 * not log the whole CP of the CCW is outside the
229 * logged CP.
230 */
231 if (cplength > 40 ||
232 ((addr_t) cpa < (addr_t) lcqr->cpaddr &&
233 (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) {
234
235 DEV_MESSAGE(KERN_ERR, device,
236 "Failed CCW (%p) (area):",
237 (void *) (long) cpa);
238 hex_dump_memory(device, cqr->cpaddr - 10,
239 20*sizeof(struct ccw1));
240 }
241 }
242
243} /* end log_erp_chain */
244
245EXPORT_SYMBOL(dasd_default_erp_action); 166EXPORT_SYMBOL(dasd_default_erp_action);
246EXPORT_SYMBOL(dasd_default_erp_postaction); 167EXPORT_SYMBOL(dasd_default_erp_postaction);
247EXPORT_SYMBOL(dasd_alloc_erp_request); 168EXPORT_SYMBOL(dasd_alloc_erp_request);
248EXPORT_SYMBOL(dasd_free_erp_request); 169EXPORT_SYMBOL(dasd_free_erp_request);
249EXPORT_SYMBOL(dasd_log_sense); 170EXPORT_SYMBOL(dasd_log_sense);
250EXPORT_SYMBOL(dasd_log_ccw);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index b857fd5893fd..be0909e39226 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -75,7 +75,7 @@ static struct ccw_driver dasd_fba_driver = {
75 .notify = dasd_generic_notify, 75 .notify = dasd_generic_notify,
76}; 76};
77 77
78static inline void 78static void
79define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw, 79define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw,
80 int blksize, int beg, int nr) 80 int blksize, int beg, int nr)
81{ 81{
@@ -95,7 +95,7 @@ define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw,
95 data->ext_end = nr - 1; 95 data->ext_end = nr - 1;
96} 96}
97 97
98static inline void 98static void
99locate_record(struct ccw1 * ccw, struct LO_fba_data *data, int rw, 99locate_record(struct ccw1 * ccw, struct LO_fba_data *data, int rw,
100 int block_nr, int block_ct) 100 int block_nr, int block_ct)
101{ 101{
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index d163632101d2..47ba4462708d 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -147,7 +147,7 @@ dasd_destroy_partitions(struct dasd_device * device)
147 */ 147 */
148 memset(&bpart, 0, sizeof(struct blkpg_partition)); 148 memset(&bpart, 0, sizeof(struct blkpg_partition));
149 memset(&barg, 0, sizeof(struct blkpg_ioctl_arg)); 149 memset(&barg, 0, sizeof(struct blkpg_ioctl_arg));
150 barg.data = (void __user *) &bpart; 150 barg.data = (void __force __user *) &bpart;
151 barg.op = BLKPG_DEL_PARTITION; 151 barg.op = BLKPG_DEL_PARTITION;
152 for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--) 152 for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--)
153 ioctl_by_bdev(bdev, BLKPG, (unsigned long) &barg); 153 ioctl_by_bdev(bdev, BLKPG, (unsigned long) &barg);
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index fb725e3b08fe..a2cc69e11410 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -559,7 +559,6 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
559 struct dasd_device *); 559 struct dasd_device *);
560void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *); 560void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
561void dasd_log_sense(struct dasd_ccw_req *, struct irb *); 561void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
562void dasd_log_ccw(struct dasd_ccw_req *, int, __u32);
563 562
564/* externals in dasd_3370_erp.c */ 563/* externals in dasd_3370_erp.c */
565dasd_era_t dasd_3370_erp_examine(struct dasd_ccw_req *, struct irb *); 564dasd_era_t dasd_3370_erp_examine(struct dasd_ccw_req *, struct irb *);
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index bfa010f6dab2..8b7e11815d70 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -28,7 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL;
28static struct proc_dir_entry *dasd_devices_entry = NULL; 28static struct proc_dir_entry *dasd_devices_entry = NULL;
29static struct proc_dir_entry *dasd_statistics_entry = NULL; 29static struct proc_dir_entry *dasd_statistics_entry = NULL;
30 30
31static inline char * 31static char *
32dasd_get_user_string(const char __user *user_buf, size_t user_len) 32dasd_get_user_string(const char __user *user_buf, size_t user_len)
33{ 33{
34 char *buffer; 34 char *buffer;
@@ -154,7 +154,7 @@ static struct file_operations dasd_devices_file_ops = {
154 .release = seq_release, 154 .release = seq_release,
155}; 155};
156 156
157static inline int 157static int
158dasd_calc_metrics(char *page, char **start, off_t off, 158dasd_calc_metrics(char *page, char **start, off_t off,
159 int count, int *eof, int len) 159 int count, int *eof, int len)
160{ 160{
@@ -167,8 +167,8 @@ dasd_calc_metrics(char *page, char **start, off_t off,
167 return len; 167 return len;
168} 168}
169 169
170static inline char * 170static char *
171dasd_statistics_array(char *str, int *array, int shift) 171dasd_statistics_array(char *str, unsigned int *array, int shift)
172{ 172{
173 int i; 173 int i;
174 174
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index be9b05347b4f..1340451ea408 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -102,7 +102,7 @@ dcssblk_release_segment(struct device *dev)
102 * device needs to be enqueued before the semaphore is 102 * device needs to be enqueued before the semaphore is
103 * freed. 103 * freed.
104 */ 104 */
105static inline int 105static int
106dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info) 106dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
107{ 107{
108 int minor, found; 108 int minor, found;
@@ -230,7 +230,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
230 SEGMENT_SHARED); 230 SEGMENT_SHARED);
231 if (rc < 0) { 231 if (rc < 0) {
232 BUG_ON(rc == -EINVAL); 232 BUG_ON(rc == -EINVAL);
233 if (rc == -EIO || rc == -ENOENT) 233 if (rc != -EAGAIN)
234 goto removeseg; 234 goto removeseg;
235 } else { 235 } else {
236 dev_info->is_shared = 1; 236 dev_info->is_shared = 1;
@@ -253,7 +253,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
253 SEGMENT_EXCLUSIVE); 253 SEGMENT_EXCLUSIVE);
254 if (rc < 0) { 254 if (rc < 0) {
255 BUG_ON(rc == -EINVAL); 255 BUG_ON(rc == -EINVAL);
256 if (rc == -EIO || rc == -ENOENT) 256 if (rc != -EAGAIN)
257 goto removeseg; 257 goto removeseg;
258 } else { 258 } else {
259 dev_info->is_shared = 0; 259 dev_info->is_shared = 0;
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index c3e97b4fc186..293e667b50f2 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -2,7 +2,8 @@
2# S/390 character devices 2# S/390 character devices
3# 3#
4 4
5obj-y += ctrlchar.o keyboard.o defkeymap.o 5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
6 sclp_info.o
6 7
7obj-$(CONFIG_TN3270) += raw3270.o 8obj-$(CONFIG_TN3270) += raw3270.o
8obj-$(CONFIG_TN3270_CONSOLE) += con3270.o 9obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
@@ -11,7 +12,6 @@ obj-$(CONFIG_TN3270_FS) += fs3270.o
11 12
12obj-$(CONFIG_TN3215) += con3215.o 13obj-$(CONFIG_TN3215) += con3215.o
13 14
14obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o sclp_quiesce.o
15obj-$(CONFIG_SCLP_TTY) += sclp_tty.o 15obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
16obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o 16obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
17obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o 17obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 25b5d7a66417..9a328f14a641 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -1121,7 +1121,7 @@ static const struct tty_operations tty3215_ops = {
1121 * 3215 tty registration code called from tty_init(). 1121 * 3215 tty registration code called from tty_init().
1122 * Most kernel services (incl. kmalloc) are available at this poimt. 1122 * Most kernel services (incl. kmalloc) are available at this poimt.
1123 */ 1123 */
1124int __init 1124static int __init
1125tty3215_init(void) 1125tty3215_init(void)
1126{ 1126{
1127 struct tty_driver *driver; 1127 struct tty_driver *driver;
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 7566be890688..8e7f2d7633d6 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -69,8 +69,7 @@ static void con3270_update(struct con3270 *);
69/* 69/*
70 * Setup timeout for a device. On timeout trigger an update. 70 * Setup timeout for a device. On timeout trigger an update.
71 */ 71 */
72void 72static void con3270_set_timer(struct con3270 *cp, int expires)
73con3270_set_timer(struct con3270 *cp, int expires)
74{ 73{
75 if (expires == 0) { 74 if (expires == 0) {
76 if (timer_pending(&cp->timer)) 75 if (timer_pending(&cp->timer))
diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c
index 17027d918cf7..564baca01b7c 100644
--- a/drivers/s390/char/defkeymap.c
+++ b/drivers/s390/char/defkeymap.c
@@ -5,6 +5,8 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/keyboard.h> 6#include <linux/keyboard.h>
7#include <linux/kd.h> 7#include <linux/kd.h>
8#include <linux/kbd_kern.h>
9#include <linux/kbd_diacr.h>
8 10
9u_short plain_map[NR_KEYS] = { 11u_short plain_map[NR_KEYS] = {
10 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 12 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000,
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 0893d306ae80..e1a746269c4c 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -23,7 +23,7 @@
23#include "raw3270.h" 23#include "raw3270.h"
24#include "ctrlchar.h" 24#include "ctrlchar.h"
25 25
26struct raw3270_fn fs3270_fn; 26static struct raw3270_fn fs3270_fn;
27 27
28struct fs3270 { 28struct fs3270 {
29 struct raw3270_view view; 29 struct raw3270_view view;
@@ -401,7 +401,7 @@ fs3270_release(struct raw3270_view *view)
401} 401}
402 402
403/* View to a 3270 device. Can be console, tty or fullscreen. */ 403/* View to a 3270 device. Can be console, tty or fullscreen. */
404struct raw3270_fn fs3270_fn = { 404static struct raw3270_fn fs3270_fn = {
405 .activate = fs3270_activate, 405 .activate = fs3270_activate,
406 .deactivate = fs3270_deactivate, 406 .deactivate = fs3270_deactivate,
407 .intv = (void *) fs3270_irq, 407 .intv = (void *) fs3270_irq,
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 3e86fd1756e5..f62f9a4e8950 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -148,6 +148,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
148 } 148 }
149} 149}
150 150
151#if 0
151/* 152/*
152 * Generate ebcdic -> ascii translation table from kbd_data. 153 * Generate ebcdic -> ascii translation table from kbd_data.
153 */ 154 */
@@ -173,6 +174,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
173 } 174 }
174 } 175 }
175} 176}
177#endif
176 178
177/* 179/*
178 * We have a combining character DIACR here, followed by the character CH. 180 * We have a combining character DIACR here, followed by the character CH.
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index cdb24f528112..9e451acc6491 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -67,8 +67,8 @@ static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
67 return -EINVAL; 67 return -EINVAL;
68} 68}
69 69
70static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv, 70static struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
71 struct monwrite_hdr *monhdr) 71 struct monwrite_hdr *monhdr)
72{ 72{
73 struct mon_buf *entry, *next; 73 struct mon_buf *entry, *next;
74 74
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 7a84014f2037..8facd14adb7c 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -29,7 +29,7 @@
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/mutex.h> 30#include <linux/mutex.h>
31 31
32struct class *class3270; 32static struct class *class3270;
33 33
34/* The main 3270 data structure. */ 34/* The main 3270 data structure. */
35struct raw3270 { 35struct raw3270 {
@@ -86,7 +86,7 @@ DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue);
86/* 86/*
87 * Encode array for 12 bit 3270 addresses. 87 * Encode array for 12 bit 3270 addresses.
88 */ 88 */
89unsigned char raw3270_ebcgraf[64] = { 89static unsigned char raw3270_ebcgraf[64] = {
90 0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 90 0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
91 0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 91 0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
92 0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 92 0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 8a056df09d6b..f171de3b0b11 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -59,7 +59,8 @@ static volatile enum sclp_init_state_t {
59/* Internal state: is a request active at the sclp? */ 59/* Internal state: is a request active at the sclp? */
60static volatile enum sclp_running_state_t { 60static volatile enum sclp_running_state_t {
61 sclp_running_state_idle, 61 sclp_running_state_idle,
62 sclp_running_state_running 62 sclp_running_state_running,
63 sclp_running_state_reset_pending
63} sclp_running_state = sclp_running_state_idle; 64} sclp_running_state = sclp_running_state_idle;
64 65
65/* Internal state: is a read request pending? */ 66/* Internal state: is a read request pending? */
@@ -88,15 +89,15 @@ static volatile enum sclp_mask_state_t {
88 89
89/* Timeout intervals in seconds.*/ 90/* Timeout intervals in seconds.*/
90#define SCLP_BUSY_INTERVAL 10 91#define SCLP_BUSY_INTERVAL 10
91#define SCLP_RETRY_INTERVAL 15 92#define SCLP_RETRY_INTERVAL 30
92 93
93static void sclp_process_queue(void); 94static void sclp_process_queue(void);
94static int sclp_init_mask(int calculate); 95static int sclp_init_mask(int calculate);
95static int sclp_init(void); 96static int sclp_init(void);
96 97
97/* Perform service call. Return 0 on success, non-zero otherwise. */ 98/* Perform service call. Return 0 on success, non-zero otherwise. */
98static int 99int
99service_call(sclp_cmdw_t command, void *sccb) 100sclp_service_call(sclp_cmdw_t command, void *sccb)
100{ 101{
101 int cc; 102 int cc;
102 103
@@ -113,19 +114,17 @@ service_call(sclp_cmdw_t command, void *sccb)
113 return 0; 114 return 0;
114} 115}
115 116
116/* Request timeout handler. Restart the request queue. If DATA is non-zero, 117static inline void __sclp_make_read_req(void);
117 * force restart of running request. */ 118
118static void 119static void
119sclp_request_timeout(unsigned long data) 120__sclp_queue_read_req(void)
120{ 121{
121 unsigned long flags; 122 if (sclp_reading_state == sclp_reading_state_idle) {
122 123 sclp_reading_state = sclp_reading_state_reading;
123 if (data) { 124 __sclp_make_read_req();
124 spin_lock_irqsave(&sclp_lock, flags); 125 /* Add request to head of queue */
125 sclp_running_state = sclp_running_state_idle; 126 list_add(&sclp_read_req.list, &sclp_req_queue);
126 spin_unlock_irqrestore(&sclp_lock, flags);
127 } 127 }
128 sclp_process_queue();
129} 128}
130 129
131/* Set up request retry timer. Called while sclp_lock is locked. */ 130/* Set up request retry timer. Called while sclp_lock is locked. */
@@ -140,6 +139,29 @@ __sclp_set_request_timer(unsigned long time, void (*function)(unsigned long),
140 add_timer(&sclp_request_timer); 139 add_timer(&sclp_request_timer);
141} 140}
142 141
142/* Request timeout handler. Restart the request queue. If DATA is non-zero,
143 * force restart of running request. */
144static void
145sclp_request_timeout(unsigned long data)
146{
147 unsigned long flags;
148
149 spin_lock_irqsave(&sclp_lock, flags);
150 if (data) {
151 if (sclp_running_state == sclp_running_state_running) {
152 /* Break running state and queue NOP read event request
153 * to get a defined interface state. */
154 __sclp_queue_read_req();
155 sclp_running_state = sclp_running_state_idle;
156 }
157 } else {
158 __sclp_set_request_timer(SCLP_BUSY_INTERVAL * HZ,
159 sclp_request_timeout, 0);
160 }
161 spin_unlock_irqrestore(&sclp_lock, flags);
162 sclp_process_queue();
163}
164
143/* Try to start a request. Return zero if the request was successfully 165/* Try to start a request. Return zero if the request was successfully
144 * started or if it will be started at a later time. Return non-zero otherwise. 166 * started or if it will be started at a later time. Return non-zero otherwise.
145 * Called while sclp_lock is locked. */ 167 * Called while sclp_lock is locked. */
@@ -151,7 +173,7 @@ __sclp_start_request(struct sclp_req *req)
151 if (sclp_running_state != sclp_running_state_idle) 173 if (sclp_running_state != sclp_running_state_idle)
152 return 0; 174 return 0;
153 del_timer(&sclp_request_timer); 175 del_timer(&sclp_request_timer);
154 rc = service_call(req->command, req->sccb); 176 rc = sclp_service_call(req->command, req->sccb);
155 req->start_count++; 177 req->start_count++;
156 178
157 if (rc == 0) { 179 if (rc == 0) {
@@ -191,7 +213,15 @@ sclp_process_queue(void)
191 rc = __sclp_start_request(req); 213 rc = __sclp_start_request(req);
192 if (rc == 0) 214 if (rc == 0)
193 break; 215 break;
194 /* Request failed. */ 216 /* Request failed */
217 if (req->start_count > 1) {
218 /* Cannot abort already submitted request - could still
219 * be active at the SCLP */
220 __sclp_set_request_timer(SCLP_BUSY_INTERVAL * HZ,
221 sclp_request_timeout, 0);
222 break;
223 }
224 /* Post-processing for aborted request */
195 list_del(&req->list); 225 list_del(&req->list);
196 if (req->callback) { 226 if (req->callback) {
197 spin_unlock_irqrestore(&sclp_lock, flags); 227 spin_unlock_irqrestore(&sclp_lock, flags);
@@ -221,7 +251,8 @@ sclp_add_request(struct sclp_req *req)
221 list_add_tail(&req->list, &sclp_req_queue); 251 list_add_tail(&req->list, &sclp_req_queue);
222 rc = 0; 252 rc = 0;
223 /* Start if request is first in list */ 253 /* Start if request is first in list */
224 if (req->list.prev == &sclp_req_queue) { 254 if (sclp_running_state == sclp_running_state_idle &&
255 req->list.prev == &sclp_req_queue) {
225 rc = __sclp_start_request(req); 256 rc = __sclp_start_request(req);
226 if (rc) 257 if (rc)
227 list_del(&req->list); 258 list_del(&req->list);
@@ -294,7 +325,7 @@ __sclp_make_read_req(void)
294 sccb = (struct sccb_header *) sclp_read_sccb; 325 sccb = (struct sccb_header *) sclp_read_sccb;
295 clear_page(sccb); 326 clear_page(sccb);
296 memset(&sclp_read_req, 0, sizeof(struct sclp_req)); 327 memset(&sclp_read_req, 0, sizeof(struct sclp_req));
297 sclp_read_req.command = SCLP_CMDW_READDATA; 328 sclp_read_req.command = SCLP_CMDW_READ_EVENT_DATA;
298 sclp_read_req.status = SCLP_REQ_QUEUED; 329 sclp_read_req.status = SCLP_REQ_QUEUED;
299 sclp_read_req.start_count = 0; 330 sclp_read_req.start_count = 0;
300 sclp_read_req.callback = sclp_read_cb; 331 sclp_read_req.callback = sclp_read_cb;
@@ -334,6 +365,8 @@ sclp_interrupt_handler(__u16 code)
334 finished_sccb = S390_lowcore.ext_params & 0xfffffff8; 365 finished_sccb = S390_lowcore.ext_params & 0xfffffff8;
335 evbuf_pending = S390_lowcore.ext_params & 0x3; 366 evbuf_pending = S390_lowcore.ext_params & 0x3;
336 if (finished_sccb) { 367 if (finished_sccb) {
368 del_timer(&sclp_request_timer);
369 sclp_running_state = sclp_running_state_reset_pending;
337 req = __sclp_find_req(finished_sccb); 370 req = __sclp_find_req(finished_sccb);
338 if (req) { 371 if (req) {
339 /* Request post-processing */ 372 /* Request post-processing */
@@ -348,13 +381,8 @@ sclp_interrupt_handler(__u16 code)
348 sclp_running_state = sclp_running_state_idle; 381 sclp_running_state = sclp_running_state_idle;
349 } 382 }
350 if (evbuf_pending && sclp_receive_mask != 0 && 383 if (evbuf_pending && sclp_receive_mask != 0 &&
351 sclp_reading_state == sclp_reading_state_idle && 384 sclp_activation_state == sclp_activation_state_active)
352 sclp_activation_state == sclp_activation_state_active ) { 385 __sclp_queue_read_req();
353 sclp_reading_state = sclp_reading_state_reading;
354 __sclp_make_read_req();
355 /* Add request to head of queue */
356 list_add(&sclp_read_req.list, &sclp_req_queue);
357 }
358 spin_unlock(&sclp_lock); 386 spin_unlock(&sclp_lock);
359 sclp_process_queue(); 387 sclp_process_queue();
360} 388}
@@ -374,6 +402,7 @@ sclp_sync_wait(void)
374 unsigned long flags; 402 unsigned long flags;
375 unsigned long cr0, cr0_sync; 403 unsigned long cr0, cr0_sync;
376 u64 timeout; 404 u64 timeout;
405 int irq_context;
377 406
378 /* We'll be disabling timer interrupts, so we need a custom timeout 407 /* We'll be disabling timer interrupts, so we need a custom timeout
379 * mechanism */ 408 * mechanism */
@@ -386,7 +415,9 @@ sclp_sync_wait(void)
386 } 415 }
387 local_irq_save(flags); 416 local_irq_save(flags);
388 /* Prevent bottom half from executing once we force interrupts open */ 417 /* Prevent bottom half from executing once we force interrupts open */
389 local_bh_disable(); 418 irq_context = in_interrupt();
419 if (!irq_context)
420 local_bh_disable();
390 /* Enable service-signal interruption, disable timer interrupts */ 421 /* Enable service-signal interruption, disable timer interrupts */
391 trace_hardirqs_on(); 422 trace_hardirqs_on();
392 __ctl_store(cr0, 0, 0); 423 __ctl_store(cr0, 0, 0);
@@ -402,19 +433,19 @@ sclp_sync_wait(void)
402 get_clock() > timeout && 433 get_clock() > timeout &&
403 del_timer(&sclp_request_timer)) 434 del_timer(&sclp_request_timer))
404 sclp_request_timer.function(sclp_request_timer.data); 435 sclp_request_timer.function(sclp_request_timer.data);
405 barrier();
406 cpu_relax(); 436 cpu_relax();
407 } 437 }
408 local_irq_disable(); 438 local_irq_disable();
409 __ctl_load(cr0, 0, 0); 439 __ctl_load(cr0, 0, 0);
410 _local_bh_enable(); 440 if (!irq_context)
441 _local_bh_enable();
411 local_irq_restore(flags); 442 local_irq_restore(flags);
412} 443}
413 444
414EXPORT_SYMBOL(sclp_sync_wait); 445EXPORT_SYMBOL(sclp_sync_wait);
415 446
416/* Dispatch changes in send and receive mask to registered listeners. */ 447/* Dispatch changes in send and receive mask to registered listeners. */
417static inline void 448static void
418sclp_dispatch_state_change(void) 449sclp_dispatch_state_change(void)
419{ 450{
420 struct list_head *l; 451 struct list_head *l;
@@ -597,7 +628,7 @@ __sclp_make_init_req(u32 receive_mask, u32 send_mask)
597 sccb = (struct init_sccb *) sclp_init_sccb; 628 sccb = (struct init_sccb *) sclp_init_sccb;
598 clear_page(sccb); 629 clear_page(sccb);
599 memset(&sclp_init_req, 0, sizeof(struct sclp_req)); 630 memset(&sclp_init_req, 0, sizeof(struct sclp_req));
600 sclp_init_req.command = SCLP_CMDW_WRITEMASK; 631 sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK;
601 sclp_init_req.status = SCLP_REQ_FILLED; 632 sclp_init_req.status = SCLP_REQ_FILLED;
602 sclp_init_req.start_count = 0; 633 sclp_init_req.start_count = 0;
603 sclp_init_req.callback = NULL; 634 sclp_init_req.callback = NULL;
@@ -800,7 +831,7 @@ sclp_check_interface(void)
800 for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) { 831 for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) {
801 __sclp_make_init_req(0, 0); 832 __sclp_make_init_req(0, 0);
802 sccb = (struct init_sccb *) sclp_init_req.sccb; 833 sccb = (struct init_sccb *) sclp_init_req.sccb;
803 rc = service_call(sclp_init_req.command, sccb); 834 rc = sclp_service_call(sclp_init_req.command, sccb);
804 if (rc == -EIO) 835 if (rc == -EIO)
805 break; 836 break;
806 sclp_init_req.status = SCLP_REQ_RUNNING; 837 sclp_init_req.status = SCLP_REQ_RUNNING;
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 2c71d6ee7b5b..7d29ab45a6ed 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -12,7 +12,7 @@
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/list.h> 14#include <linux/list.h>
15 15#include <asm/sclp.h>
16#include <asm/ebcdic.h> 16#include <asm/ebcdic.h>
17 17
18/* maximum number of pages concerning our own memory management */ 18/* maximum number of pages concerning our own memory management */
@@ -49,9 +49,11 @@
49 49
50typedef unsigned int sclp_cmdw_t; 50typedef unsigned int sclp_cmdw_t;
51 51
52#define SCLP_CMDW_READDATA 0x00770005 52#define SCLP_CMDW_READ_EVENT_DATA 0x00770005
53#define SCLP_CMDW_WRITEDATA 0x00760005 53#define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005
54#define SCLP_CMDW_WRITEMASK 0x00780005 54#define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005
55#define SCLP_CMDW_READ_SCP_INFO 0x00020001
56#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
55 57
56#define GDS_ID_MDSMU 0x1310 58#define GDS_ID_MDSMU 0x1310
57#define GDS_ID_MDSRouteInfo 0x1311 59#define GDS_ID_MDSRouteInfo 0x1311
@@ -66,13 +68,6 @@ typedef unsigned int sclp_cmdw_t;
66 68
67typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ 69typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
68 70
69struct sccb_header {
70 u16 length;
71 u8 function_code;
72 u8 control_mask[3];
73 u16 response_code;
74} __attribute__((packed));
75
76struct gds_subvector { 71struct gds_subvector {
77 u8 length; 72 u8 length;
78 u8 key; 73 u8 key;
@@ -131,6 +126,7 @@ void sclp_unregister(struct sclp_register *reg);
131int sclp_remove_processed(struct sccb_header *sccb); 126int sclp_remove_processed(struct sccb_header *sccb);
132int sclp_deactivate(void); 127int sclp_deactivate(void);
133int sclp_reactivate(void); 128int sclp_reactivate(void);
129int sclp_service_call(sclp_cmdw_t command, void *sccb);
134 130
135/* useful inlines */ 131/* useful inlines */
136 132
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index 86864f641716..ead1043d788e 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -66,7 +66,7 @@ sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
66 } while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback)); 66 } while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback));
67} 67}
68 68
69static inline void 69static void
70sclp_conbuf_emit(void) 70sclp_conbuf_emit(void)
71{ 71{
72 struct sclp_buffer* buffer; 72 struct sclp_buffer* buffer;
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
index 4f873ae148b7..65aa2c85737f 100644
--- a/drivers/s390/char/sclp_cpi.c
+++ b/drivers/s390/char/sclp_cpi.c
@@ -169,7 +169,7 @@ cpi_prepare_req(void)
169 } 169 }
170 170
171 /* prepare request data structure presented to SCLP driver */ 171 /* prepare request data structure presented to SCLP driver */
172 req->command = SCLP_CMDW_WRITEDATA; 172 req->command = SCLP_CMDW_WRITE_EVENT_DATA;
173 req->sccb = sccb; 173 req->sccb = sccb;
174 req->status = SCLP_REQ_FILLED; 174 req->status = SCLP_REQ_FILLED;
175 req->callback = cpi_callback; 175 req->callback = cpi_callback;
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c
new file mode 100644
index 000000000000..7bcbe643b087
--- /dev/null
+++ b/drivers/s390/char/sclp_info.c
@@ -0,0 +1,57 @@
1/*
2 * drivers/s390/char/sclp_info.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#include <linux/init.h>
9#include <linux/errno.h>
10#include <linux/string.h>
11#include <asm/sclp.h>
12#include "sclp.h"
13
14struct sclp_readinfo_sccb s390_readinfo_sccb;
15
16void __init sclp_readinfo_early(void)
17{
18 sclp_cmdw_t command;
19 struct sccb_header *sccb;
20 int ret;
21
22 __ctl_set_bit(0, 9); /* enable service signal subclass mask */
23
24 sccb = &s390_readinfo_sccb.header;
25 command = SCLP_CMDW_READ_SCP_INFO_FORCED;
26 while (1) {
27 u16 response;
28
29 memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb));
30 sccb->length = sizeof(s390_readinfo_sccb);
31 sccb->control_mask[2] = 0x80;
32
33 ret = sclp_service_call(command, &s390_readinfo_sccb);
34
35 if (ret == -EIO)
36 goto out;
37 if (ret == -EBUSY)
38 continue;
39
40 __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
41 PSW_MASK_WAIT | PSW_DEFAULT_KEY);
42 local_irq_disable();
43 barrier();
44
45 response = sccb->response_code;
46
47 if (response == 0x10)
48 break;
49
50 if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO)
51 break;
52
53 command = SCLP_CMDW_READ_SCP_INFO;
54 }
55out:
56 __ctl_clear_bit(0, 9); /* disable service signal subclass mask */
57}
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
index 0c92d3909cca..2486783ea58e 100644
--- a/drivers/s390/char/sclp_rw.c
+++ b/drivers/s390/char/sclp_rw.c
@@ -460,7 +460,7 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
460 sccb->msg_buf.header.type = EvTyp_PMsgCmd; 460 sccb->msg_buf.header.type = EvTyp_PMsgCmd;
461 else 461 else
462 return -ENOSYS; 462 return -ENOSYS;
463 buffer->request.command = SCLP_CMDW_WRITEDATA; 463 buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
464 buffer->request.status = SCLP_REQ_FILLED; 464 buffer->request.status = SCLP_REQ_FILLED;
465 buffer->request.callback = sclp_writedata_callback; 465 buffer->request.callback = sclp_writedata_callback;
466 buffer->request.callback_data = buffer; 466 buffer->request.callback_data = buffer;
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 2d173e5c8a09..90536f60bf50 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -721,7 +721,7 @@ static const struct tty_operations sclp_ops = {
721 .ioctl = sclp_tty_ioctl, 721 .ioctl = sclp_tty_ioctl,
722}; 722};
723 723
724int __init 724static int __init
725sclp_tty_init(void) 725sclp_tty_init(void)
726{ 726{
727 struct tty_driver *driver; 727 struct tty_driver *driver;
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 723bf4191bfe..544f137d70d7 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -207,7 +207,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request)
207 request->sclp_req.status = SCLP_REQ_FAILED; 207 request->sclp_req.status = SCLP_REQ_FAILED;
208 return -EIO; 208 return -EIO;
209 } 209 }
210 request->sclp_req.command = SCLP_CMDW_WRITEDATA; 210 request->sclp_req.command = SCLP_CMDW_WRITE_EVENT_DATA;
211 request->sclp_req.status = SCLP_REQ_FILLED; 211 request->sclp_req.status = SCLP_REQ_FILLED;
212 request->sclp_req.callback = sclp_vt220_callback; 212 request->sclp_req.callback = sclp_vt220_callback;
213 request->sclp_req.callback_data = (void *) request; 213 request->sclp_req.callback_data = (void *) request;
@@ -669,7 +669,7 @@ static const struct tty_operations sclp_vt220_ops = {
669/* 669/*
670 * Register driver with SCLP and Linux and initialize internal tty structures. 670 * Register driver with SCLP and Linux and initialize internal tty structures.
671 */ 671 */
672int __init 672static int __init
673sclp_vt220_tty_init(void) 673sclp_vt220_tty_init(void)
674{ 674{
675 struct tty_driver *driver; 675 struct tty_driver *driver;
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index c9f1c4c8bb13..bb4ff537729d 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -3,7 +3,7 @@
3 * tape device driver for 3480/3490E/3590 tapes. 3 * tape device driver for 3480/3490E/3590 tapes.
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright IBM Corp. 2001,2006
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 8 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
9 * Martin Schwidefsky <schwidefsky@de.ibm.com> 9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -99,7 +99,11 @@ enum tape_op {
99 TO_DIS, /* Tape display */ 99 TO_DIS, /* Tape display */
100 TO_ASSIGN, /* Assign tape to channel path */ 100 TO_ASSIGN, /* Assign tape to channel path */
101 TO_UNASSIGN, /* Unassign tape from channel path */ 101 TO_UNASSIGN, /* Unassign tape from channel path */
102 TO_SIZE /* #entries in tape_op_t */ 102 TO_CRYPT_ON, /* Enable encrpytion */
103 TO_CRYPT_OFF, /* Disable encrpytion */
104 TO_KEKL_SET, /* Set KEK label */
105 TO_KEKL_QUERY, /* Query KEK label */
106 TO_SIZE, /* #entries in tape_op_t */
103}; 107};
104 108
105/* Forward declaration */ 109/* Forward declaration */
@@ -112,6 +116,7 @@ enum tape_request_status {
112 TAPE_REQUEST_IN_IO, /* request is currently in IO */ 116 TAPE_REQUEST_IN_IO, /* request is currently in IO */
113 TAPE_REQUEST_DONE, /* request is completed. */ 117 TAPE_REQUEST_DONE, /* request is completed. */
114 TAPE_REQUEST_CANCEL, /* request should be canceled. */ 118 TAPE_REQUEST_CANCEL, /* request should be canceled. */
119 TAPE_REQUEST_LONG_BUSY, /* request has to be restarted after long busy */
115}; 120};
116 121
117/* Tape CCW request */ 122/* Tape CCW request */
@@ -164,10 +169,11 @@ struct tape_discipline {
164 * The discipline irq function either returns an error code (<0) which 169 * The discipline irq function either returns an error code (<0) which
165 * means that the request has failed with an error or one of the following: 170 * means that the request has failed with an error or one of the following:
166 */ 171 */
167#define TAPE_IO_SUCCESS 0 /* request successful */ 172#define TAPE_IO_SUCCESS 0 /* request successful */
168#define TAPE_IO_PENDING 1 /* request still running */ 173#define TAPE_IO_PENDING 1 /* request still running */
169#define TAPE_IO_RETRY 2 /* retry to current request */ 174#define TAPE_IO_RETRY 2 /* retry to current request */
170#define TAPE_IO_STOP 3 /* stop the running request */ 175#define TAPE_IO_STOP 3 /* stop the running request */
176#define TAPE_IO_LONG_BUSY 4 /* delay the running request */
171 177
172/* Char Frontend Data */ 178/* Char Frontend Data */
173struct tape_char_data { 179struct tape_char_data {
@@ -242,6 +248,10 @@ struct tape_device {
242 248
243 /* Function to start or stop the next request later. */ 249 /* Function to start or stop the next request later. */
244 struct delayed_work tape_dnr; 250 struct delayed_work tape_dnr;
251
252 /* Timer for long busy */
253 struct timer_list lb_timeout;
254
245}; 255};
246 256
247/* Externals from tape_core.c */ 257/* Externals from tape_core.c */
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 9df912f63188..50f5edab83d7 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_3590.c 2 * drivers/s390/char/tape_3590.c
3 * tape device discipline for 3590 tapes. 3 * tape device discipline for 3590 tapes.
4 * 4 *
5 * Copyright (C) IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001,2006
6 * Author(s): Stefan Bader <shbader@de.ibm.com> 6 * Author(s): Stefan Bader <shbader@de.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/bio.h> 13#include <linux/bio.h>
14#include <asm/ebcdic.h>
14 15
15#define TAPE_DBF_AREA tape_3590_dbf 16#define TAPE_DBF_AREA tape_3590_dbf
16 17
@@ -30,7 +31,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
30 * - Read Device (buffered) log: BRA 31 * - Read Device (buffered) log: BRA
31 * - Read Library log: BRA 32 * - Read Library log: BRA
32 * - Swap Devices: BRA 33 * - Swap Devices: BRA
33 * - Long Busy: BRA 34 * - Long Busy: implemented
34 * - Special Intercept: BRA 35 * - Special Intercept: BRA
35 * - Read Alternate: implemented 36 * - Read Alternate: implemented
36 *******************************************************************/ 37 *******************************************************************/
@@ -94,6 +95,332 @@ static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
94 [0xae] = "Subsystem environmental alert", 95 [0xae] = "Subsystem environmental alert",
95}; 96};
96 97
98static int crypt_supported(struct tape_device *device)
99{
100 return TAPE390_CRYPT_SUPPORTED(TAPE_3590_CRYPT_INFO(device));
101}
102
103static int crypt_enabled(struct tape_device *device)
104{
105 return TAPE390_CRYPT_ON(TAPE_3590_CRYPT_INFO(device));
106}
107
108static void ext_to_int_kekl(struct tape390_kekl *in,
109 struct tape3592_kekl *out)
110{
111 int i;
112
113 memset(out, 0, sizeof(*out));
114 if (in->type == TAPE390_KEKL_TYPE_HASH)
115 out->flags |= 0x40;
116 if (in->type_on_tape == TAPE390_KEKL_TYPE_HASH)
117 out->flags |= 0x80;
118 strncpy(out->label, in->label, 64);
119 for (i = strlen(in->label); i < sizeof(out->label); i++)
120 out->label[i] = ' ';
121 ASCEBC(out->label, sizeof(out->label));
122}
123
124static void int_to_ext_kekl(struct tape3592_kekl *in,
125 struct tape390_kekl *out)
126{
127 memset(out, 0, sizeof(*out));
128 if(in->flags & 0x40)
129 out->type = TAPE390_KEKL_TYPE_HASH;
130 else
131 out->type = TAPE390_KEKL_TYPE_LABEL;
132 if(in->flags & 0x80)
133 out->type_on_tape = TAPE390_KEKL_TYPE_HASH;
134 else
135 out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
136 memcpy(out->label, in->label, sizeof(in->label));
137 EBCASC(out->label, sizeof(in->label));
138 strstrip(out->label);
139}
140
141static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
142 struct tape390_kekl_pair *out)
143{
144 if (in->count == 0) {
145 out->kekl[0].type = TAPE390_KEKL_TYPE_NONE;
146 out->kekl[0].type_on_tape = TAPE390_KEKL_TYPE_NONE;
147 out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
148 out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
149 } else if (in->count == 1) {
150 int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
151 out->kekl[1].type = TAPE390_KEKL_TYPE_NONE;
152 out->kekl[1].type_on_tape = TAPE390_KEKL_TYPE_NONE;
153 } else if (in->count == 2) {
154 int_to_ext_kekl(&in->kekl[0], &out->kekl[0]);
155 int_to_ext_kekl(&in->kekl[1], &out->kekl[1]);
156 } else {
157 printk("Invalid KEKL number: %d\n", in->count);
158 BUG();
159 }
160}
161
162static int check_ext_kekl(struct tape390_kekl *kekl)
163{
164 if (kekl->type == TAPE390_KEKL_TYPE_NONE)
165 goto invalid;
166 if (kekl->type > TAPE390_KEKL_TYPE_HASH)
167 goto invalid;
168 if (kekl->type_on_tape == TAPE390_KEKL_TYPE_NONE)
169 goto invalid;
170 if (kekl->type_on_tape > TAPE390_KEKL_TYPE_HASH)
171 goto invalid;
172 if ((kekl->type == TAPE390_KEKL_TYPE_HASH) &&
173 (kekl->type_on_tape == TAPE390_KEKL_TYPE_LABEL))
174 goto invalid;
175
176 return 0;
177invalid:
178 return -EINVAL;
179}
180
181static int check_ext_kekl_pair(struct tape390_kekl_pair *kekls)
182{
183 if (check_ext_kekl(&kekls->kekl[0]))
184 goto invalid;
185 if (check_ext_kekl(&kekls->kekl[1]))
186 goto invalid;
187
188 return 0;
189invalid:
190 return -EINVAL;
191}
192
193/*
194 * Query KEKLs
195 */
196static int tape_3592_kekl_query(struct tape_device *device,
197 struct tape390_kekl_pair *ext_kekls)
198{
199 struct tape_request *request;
200 struct tape3592_kekl_query_order *order;
201 struct tape3592_kekl_query_data *int_kekls;
202 int rc;
203
204 DBF_EVENT(6, "tape3592_kekl_query\n");
205 int_kekls = kmalloc(sizeof(*int_kekls), GFP_KERNEL|GFP_DMA);
206 if (!int_kekls)
207 return -ENOMEM;
208 request = tape_alloc_request(2, sizeof(*order));
209 if (IS_ERR(request)) {
210 rc = PTR_ERR(request);
211 goto fail_malloc;
212 }
213 order = request->cpdata;
214 memset(order,0,sizeof(*order));
215 order->code = 0xe2;
216 order->max_count = 2;
217 request->op = TO_KEKL_QUERY;
218 tape_ccw_cc(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
219 tape_ccw_end(request->cpaddr + 1, READ_SS_DATA, sizeof(*int_kekls),
220 int_kekls);
221 rc = tape_do_io(device, request);
222 if (rc)
223 goto fail_request;
224 int_to_ext_kekl_pair(&int_kekls->kekls, ext_kekls);
225
226 rc = 0;
227fail_request:
228 tape_free_request(request);
229fail_malloc:
230 kfree(int_kekls);
231 return rc;
232}
233
234/*
235 * IOCTL: Query KEKLs
236 */
237static int tape_3592_ioctl_kekl_query(struct tape_device *device,
238 unsigned long arg)
239{
240 int rc;
241 struct tape390_kekl_pair *ext_kekls;
242
243 DBF_EVENT(6, "tape_3592_ioctl_kekl_query\n");
244 if (!crypt_supported(device))
245 return -ENOSYS;
246 if (!crypt_enabled(device))
247 return -EUNATCH;
248 ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL);
249 if (!ext_kekls)
250 return -ENOMEM;
251 rc = tape_3592_kekl_query(device, ext_kekls);
252 if (rc != 0)
253 goto fail;
254 if (copy_to_user((char __user *) arg, ext_kekls, sizeof(*ext_kekls))) {
255 rc = -EFAULT;
256 goto fail;
257 }
258 rc = 0;
259fail:
260 kfree(ext_kekls);
261 return rc;
262}
263
264static int tape_3590_mttell(struct tape_device *device, int mt_count);
265
266/*
267 * Set KEKLs
268 */
269static int tape_3592_kekl_set(struct tape_device *device,
270 struct tape390_kekl_pair *ext_kekls)
271{
272 struct tape_request *request;
273 struct tape3592_kekl_set_order *order;
274
275 DBF_EVENT(6, "tape3592_kekl_set\n");
276 if (check_ext_kekl_pair(ext_kekls)) {
277 DBF_EVENT(6, "invalid kekls\n");
278 return -EINVAL;
279 }
280 if (tape_3590_mttell(device, 0) != 0)
281 return -EBADSLT;
282 request = tape_alloc_request(1, sizeof(*order));
283 if (IS_ERR(request))
284 return PTR_ERR(request);
285 order = request->cpdata;
286 memset(order, 0, sizeof(*order));
287 order->code = 0xe3;
288 order->kekls.count = 2;
289 ext_to_int_kekl(&ext_kekls->kekl[0], &order->kekls.kekl[0]);
290 ext_to_int_kekl(&ext_kekls->kekl[1], &order->kekls.kekl[1]);
291 request->op = TO_KEKL_SET;
292 tape_ccw_end(request->cpaddr, PERF_SUBSYS_FUNC, sizeof(*order), order);
293
294 return tape_do_io_free(device, request);
295}
296
297/*
298 * IOCTL: Set KEKLs
299 */
300static int tape_3592_ioctl_kekl_set(struct tape_device *device,
301 unsigned long arg)
302{
303 int rc;
304 struct tape390_kekl_pair *ext_kekls;
305
306 DBF_EVENT(6, "tape_3592_ioctl_kekl_set\n");
307 if (!crypt_supported(device))
308 return -ENOSYS;
309 if (!crypt_enabled(device))
310 return -EUNATCH;
311 ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL);
312 if (!ext_kekls)
313 return -ENOMEM;
314 if (copy_from_user(ext_kekls, (char __user *)arg, sizeof(*ext_kekls))) {
315 rc = -EFAULT;
316 goto out;
317 }
318 rc = tape_3592_kekl_set(device, ext_kekls);
319out:
320 kfree(ext_kekls);
321 return rc;
322}
323
324/*
325 * Enable encryption
326 */
327static int tape_3592_enable_crypt(struct tape_device *device)
328{
329 struct tape_request *request;
330 char *data;
331
332 DBF_EVENT(6, "tape_3592_enable_crypt\n");
333 if (!crypt_supported(device))
334 return -ENOSYS;
335 request = tape_alloc_request(2, 72);
336 if (IS_ERR(request))
337 return PTR_ERR(request);
338 data = request->cpdata;
339 memset(data,0,72);
340
341 data[0] = 0x05;
342 data[36 + 0] = 0x03;
343 data[36 + 1] = 0x03;
344 data[36 + 4] = 0x40;
345 data[36 + 6] = 0x01;
346 data[36 + 14] = 0x2f;
347 data[36 + 18] = 0xc3;
348 data[36 + 35] = 0x72;
349 request->op = TO_CRYPT_ON;
350 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
351 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
352 return tape_do_io_free(device, request);
353}
354
355/*
356 * Disable encryption
357 */
358static int tape_3592_disable_crypt(struct tape_device *device)
359{
360 struct tape_request *request;
361 char *data;
362
363 DBF_EVENT(6, "tape_3592_disable_crypt\n");
364 if (!crypt_supported(device))
365 return -ENOSYS;
366 request = tape_alloc_request(2, 72);
367 if (IS_ERR(request))
368 return PTR_ERR(request);
369 data = request->cpdata;
370 memset(data,0,72);
371
372 data[0] = 0x05;
373 data[36 + 0] = 0x03;
374 data[36 + 1] = 0x03;
375 data[36 + 35] = 0x32;
376
377 request->op = TO_CRYPT_OFF;
378 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
379 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
380
381 return tape_do_io_free(device, request);
382}
383
384/*
385 * IOCTL: Set encryption status
386 */
387static int tape_3592_ioctl_crypt_set(struct tape_device *device,
388 unsigned long arg)
389{
390 struct tape390_crypt_info info;
391
392 DBF_EVENT(6, "tape_3592_ioctl_crypt_set\n");
393 if (!crypt_supported(device))
394 return -ENOSYS;
395 if (copy_from_user(&info, (char __user *)arg, sizeof(info)))
396 return -EFAULT;
397 if (info.status & ~TAPE390_CRYPT_ON_MASK)
398 return -EINVAL;
399 if (info.status & TAPE390_CRYPT_ON_MASK)
400 return tape_3592_enable_crypt(device);
401 else
402 return tape_3592_disable_crypt(device);
403}
404
405static int tape_3590_sense_medium(struct tape_device *device);
406
407/*
408 * IOCTL: Query enryption status
409 */
410static int tape_3592_ioctl_crypt_query(struct tape_device *device,
411 unsigned long arg)
412{
413 DBF_EVENT(6, "tape_3592_ioctl_crypt_query\n");
414 if (!crypt_supported(device))
415 return -ENOSYS;
416 tape_3590_sense_medium(device);
417 if (copy_to_user((char __user *) arg, &TAPE_3590_CRYPT_INFO(device),
418 sizeof(TAPE_3590_CRYPT_INFO(device))))
419 return -EFAULT;
420 else
421 return 0;
422}
423
97/* 424/*
98 * 3590 IOCTL Overload 425 * 3590 IOCTL Overload
99 */ 426 */
@@ -109,6 +436,14 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
109 436
110 return tape_std_display(device, &disp); 437 return tape_std_display(device, &disp);
111 } 438 }
439 case TAPE390_KEKL_SET:
440 return tape_3592_ioctl_kekl_set(device, arg);
441 case TAPE390_KEKL_QUERY:
442 return tape_3592_ioctl_kekl_query(device, arg);
443 case TAPE390_CRYPT_SET:
444 return tape_3592_ioctl_crypt_set(device, arg);
445 case TAPE390_CRYPT_QUERY:
446 return tape_3592_ioctl_crypt_query(device, arg);
112 default: 447 default:
113 return -EINVAL; /* no additional ioctls */ 448 return -EINVAL; /* no additional ioctls */
114 } 449 }
@@ -248,6 +583,12 @@ tape_3590_work_handler(struct work_struct *work)
248 case TO_READ_ATTMSG: 583 case TO_READ_ATTMSG:
249 tape_3590_read_attmsg(p->device); 584 tape_3590_read_attmsg(p->device);
250 break; 585 break;
586 case TO_CRYPT_ON:
587 tape_3592_enable_crypt(p->device);
588 break;
589 case TO_CRYPT_OFF:
590 tape_3592_disable_crypt(p->device);
591 break;
251 default: 592 default:
252 DBF_EVENT(3, "T3590: work handler undefined for " 593 DBF_EVENT(3, "T3590: work handler undefined for "
253 "operation 0x%02x\n", p->op); 594 "operation 0x%02x\n", p->op);
@@ -365,6 +706,33 @@ tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
365} 706}
366#endif 707#endif
367 708
709static void tape_3590_med_state_set(struct tape_device *device,
710 struct tape_3590_med_sense *sense)
711{
712 struct tape390_crypt_info *c_info;
713
714 c_info = &TAPE_3590_CRYPT_INFO(device);
715
716 if (sense->masst == MSENSE_UNASSOCIATED) {
717 tape_med_state_set(device, MS_UNLOADED);
718 TAPE_3590_CRYPT_INFO(device).medium_status = 0;
719 return;
720 }
721 if (sense->masst != MSENSE_ASSOCIATED_MOUNT) {
722 PRINT_ERR("Unknown medium state: %x\n", sense->masst);
723 return;
724 }
725 tape_med_state_set(device, MS_LOADED);
726 c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
727 if (sense->flags & MSENSE_CRYPT_MASK) {
728 PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
729 c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
730 } else {
731 DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
732 c_info->medium_status &= ~TAPE390_MEDIUM_ENCRYPTED_MASK;
733 }
734}
735
368/* 736/*
369 * The done handler is called at device/channel end and wakes up the sleeping 737 * The done handler is called at device/channel end and wakes up the sleeping
370 * process 738 * process
@@ -372,9 +740,10 @@ tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
372static int 740static int
373tape_3590_done(struct tape_device *device, struct tape_request *request) 741tape_3590_done(struct tape_device *device, struct tape_request *request)
374{ 742{
375 struct tape_3590_med_sense *sense; 743 struct tape_3590_disc_data *disc_data;
376 744
377 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); 745 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
746 disc_data = device->discdata;
378 747
379 switch (request->op) { 748 switch (request->op) {
380 case TO_BSB: 749 case TO_BSB:
@@ -394,13 +763,20 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
394 break; 763 break;
395 case TO_RUN: 764 case TO_RUN:
396 tape_med_state_set(device, MS_UNLOADED); 765 tape_med_state_set(device, MS_UNLOADED);
766 tape_3590_schedule_work(device, TO_CRYPT_OFF);
397 break; 767 break;
398 case TO_MSEN: 768 case TO_MSEN:
399 sense = (struct tape_3590_med_sense *) request->cpdata; 769 tape_3590_med_state_set(device, request->cpdata);
400 if (sense->masst == MSENSE_UNASSOCIATED) 770 break;
401 tape_med_state_set(device, MS_UNLOADED); 771 case TO_CRYPT_ON:
402 if (sense->masst == MSENSE_ASSOCIATED_MOUNT) 772 TAPE_3590_CRYPT_INFO(device).status
403 tape_med_state_set(device, MS_LOADED); 773 |= TAPE390_CRYPT_ON_MASK;
774 *(device->modeset_byte) |= 0x03;
775 break;
776 case TO_CRYPT_OFF:
777 TAPE_3590_CRYPT_INFO(device).status
778 &= ~TAPE390_CRYPT_ON_MASK;
779 *(device->modeset_byte) &= ~0x03;
404 break; 780 break;
405 case TO_RBI: /* RBI seems to succeed even without medium loaded. */ 781 case TO_RBI: /* RBI seems to succeed even without medium loaded. */
406 case TO_NOP: /* Same to NOP. */ 782 case TO_NOP: /* Same to NOP. */
@@ -409,8 +785,9 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
409 case TO_DIS: 785 case TO_DIS:
410 case TO_ASSIGN: 786 case TO_ASSIGN:
411 case TO_UNASSIGN: 787 case TO_UNASSIGN:
412 break;
413 case TO_SIZE: 788 case TO_SIZE:
789 case TO_KEKL_SET:
790 case TO_KEKL_QUERY:
414 break; 791 break;
415 } 792 }
416 return TAPE_IO_SUCCESS; 793 return TAPE_IO_SUCCESS;
@@ -540,10 +917,8 @@ static int
540tape_3590_erp_long_busy(struct tape_device *device, 917tape_3590_erp_long_busy(struct tape_device *device,
541 struct tape_request *request, struct irb *irb) 918 struct tape_request *request, struct irb *irb)
542{ 919{
543 /* FIXME: how about WAITING for a minute ? */ 920 DBF_EVENT(6, "Device is busy\n");
544 PRINT_WARN("(%s): Device is busy! Please wait a minute!\n", 921 return TAPE_IO_LONG_BUSY;
545 device->cdev->dev.bus_id);
546 return tape_3590_erp_basic(device, request, irb, -EBUSY);
547} 922}
548 923
549/* 924/*
@@ -951,6 +1326,34 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
951 device->cdev->dev.bus_id, sense->mc); 1326 device->cdev->dev.bus_id, sense->mc);
952} 1327}
953 1328
1329static int tape_3590_crypt_error(struct tape_device *device,
1330 struct tape_request *request, struct irb *irb)
1331{
1332 u8 cu_rc, ekm_rc1;
1333 u16 ekm_rc2;
1334 u32 drv_rc;
1335 char *bus_id, *sense;
1336
1337 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
1338 bus_id = device->cdev->dev.bus_id;
1339 cu_rc = sense[0];
1340 drv_rc = *((u32*) &sense[5]) & 0xffffff;
1341 ekm_rc1 = sense[9];
1342 ekm_rc2 = *((u16*) &sense[10]);
1343 if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
1344 /* key not defined on EKM */
1345 return tape_3590_erp_basic(device, request, irb, -EKEYREJECTED);
1346 if ((cu_rc == 1) || (cu_rc == 2))
1347 /* No connection to EKM */
1348 return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
1349
1350 PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
1351 PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
1352 drv_rc, ekm_rc1, ekm_rc2);
1353
1354 return tape_3590_erp_basic(device, request, irb, -ENOKEY);
1355}
1356
954/* 1357/*
955 * 3590 error Recovery routine: 1358 * 3590 error Recovery routine:
956 * If possible, it tries to recover from the error. If this is not possible, 1359 * If possible, it tries to recover from the error. If this is not possible,
@@ -979,6 +1382,8 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
979 1382
980 sense = (struct tape_3590_sense *) irb->ecw; 1383 sense = (struct tape_3590_sense *) irb->ecw;
981 1384
1385 DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc);
1386
982 /* 1387 /*
983 * First check all RC-QRCs where we want to do something special 1388 * First check all RC-QRCs where we want to do something special
984 * - "break": basic error recovery is done 1389 * - "break": basic error recovery is done
@@ -999,6 +1404,8 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
999 case 0x2231: 1404 case 0x2231:
1000 tape_3590_print_era_msg(device, irb); 1405 tape_3590_print_era_msg(device, irb);
1001 return tape_3590_erp_special_interrupt(device, request, irb); 1406 return tape_3590_erp_special_interrupt(device, request, irb);
1407 case 0x2240:
1408 return tape_3590_crypt_error(device, request, irb);
1002 1409
1003 case 0x3010: 1410 case 0x3010:
1004 DBF_EVENT(2, "(%08x): Backward at Beginning of Partition\n", 1411 DBF_EVENT(2, "(%08x): Backward at Beginning of Partition\n",
@@ -1020,6 +1427,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1020 DBF_EVENT(2, "(%08x): Rewind Unload complete\n", 1427 DBF_EVENT(2, "(%08x): Rewind Unload complete\n",
1021 device->cdev_id); 1428 device->cdev_id);
1022 tape_med_state_set(device, MS_UNLOADED); 1429 tape_med_state_set(device, MS_UNLOADED);
1430 tape_3590_schedule_work(device, TO_CRYPT_OFF);
1023 return tape_3590_erp_basic(device, request, irb, 0); 1431 return tape_3590_erp_basic(device, request, irb, 0);
1024 1432
1025 case 0x4010: 1433 case 0x4010:
@@ -1030,9 +1438,15 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1030 PRINT_WARN("(%s): Tape operation when medium not loaded\n", 1438 PRINT_WARN("(%s): Tape operation when medium not loaded\n",
1031 device->cdev->dev.bus_id); 1439 device->cdev->dev.bus_id);
1032 tape_med_state_set(device, MS_UNLOADED); 1440 tape_med_state_set(device, MS_UNLOADED);
1441 tape_3590_schedule_work(device, TO_CRYPT_OFF);
1033 return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM); 1442 return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
1034 case 0x4012: /* Device Long Busy */ 1443 case 0x4012: /* Device Long Busy */
1444 /* XXX: Also use long busy handling here? */
1445 DBF_EVENT(6, "(%08x): LONG BUSY\n", device->cdev_id);
1035 tape_3590_print_era_msg(device, irb); 1446 tape_3590_print_era_msg(device, irb);
1447 return tape_3590_erp_basic(device, request, irb, -EBUSY);
1448 case 0x4014:
1449 DBF_EVENT(6, "(%08x): Crypto LONG BUSY\n", device->cdev_id);
1036 return tape_3590_erp_long_busy(device, request, irb); 1450 return tape_3590_erp_long_busy(device, request, irb);
1037 1451
1038 case 0x5010: 1452 case 0x5010:
@@ -1064,6 +1478,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1064 case 0x5120: 1478 case 0x5120:
1065 case 0x1120: 1479 case 0x1120:
1066 tape_med_state_set(device, MS_UNLOADED); 1480 tape_med_state_set(device, MS_UNLOADED);
1481 tape_3590_schedule_work(device, TO_CRYPT_OFF);
1067 return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM); 1482 return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
1068 1483
1069 case 0x6020: 1484 case 0x6020:
@@ -1142,21 +1557,47 @@ tape_3590_setup_device(struct tape_device *device)
1142{ 1557{
1143 int rc; 1558 int rc;
1144 struct tape_3590_disc_data *data; 1559 struct tape_3590_disc_data *data;
1560 char *rdc_data;
1145 1561
1146 DBF_EVENT(6, "3590 device setup\n"); 1562 DBF_EVENT(6, "3590 device setup\n");
1147 data = kmalloc(sizeof(struct tape_3590_disc_data), 1563 data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA);
1148 GFP_KERNEL | GFP_DMA);
1149 if (data == NULL) 1564 if (data == NULL)
1150 return -ENOMEM; 1565 return -ENOMEM;
1151 data->read_back_op = READ_PREVIOUS; 1566 data->read_back_op = READ_PREVIOUS;
1152 device->discdata = data; 1567 device->discdata = data;
1153 1568
1154 if ((rc = tape_std_assign(device)) == 0) { 1569 rdc_data = kmalloc(64, GFP_KERNEL | GFP_DMA);
1155 /* Try to find out if medium is loaded */ 1570 if (!rdc_data) {
1156 if ((rc = tape_3590_sense_medium(device)) != 0) 1571 rc = -ENOMEM;
1157 DBF_LH(3, "3590 medium sense returned %d\n", rc); 1572 goto fail_kmalloc;
1573 }
1574 rc = read_dev_chars(device->cdev, (void**)&rdc_data, 64);
1575 if (rc) {
1576 DBF_LH(3, "Read device characteristics failed!\n");
1577 goto fail_kmalloc;
1578 }
1579 rc = tape_std_assign(device);
1580 if (rc)
1581 goto fail_rdc_data;
1582 if (rdc_data[31] == 0x13) {
1583 PRINT_INFO("Device has crypto support\n");
1584 data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
1585 tape_3592_disable_crypt(device);
1586 } else {
1587 DBF_EVENT(6, "Device has NO crypto support\n");
1158 } 1588 }
1589 /* Try to find out if medium is loaded */
1590 rc = tape_3590_sense_medium(device);
1591 if (rc) {
1592 DBF_LH(3, "3590 medium sense returned %d\n", rc);
1593 goto fail_rdc_data;
1594 }
1595 return 0;
1159 1596
1597fail_rdc_data:
1598 kfree(rdc_data);
1599fail_kmalloc:
1600 kfree(data);
1160 return rc; 1601 return rc;
1161} 1602}
1162 1603
diff --git a/drivers/s390/char/tape_3590.h b/drivers/s390/char/tape_3590.h
index cf274b9445a6..aa5138807af1 100644
--- a/drivers/s390/char/tape_3590.h
+++ b/drivers/s390/char/tape_3590.h
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_3590.h 2 * drivers/s390/char/tape_3590.h
3 * tape device discipline for 3590 tapes. 3 * tape device discipline for 3590 tapes.
4 * 4 *
5 * Copyright (C) IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001,2006
6 * Author(s): Stefan Bader <shbader@de.ibm.com> 6 * Author(s): Stefan Bader <shbader@de.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -38,16 +38,22 @@
38#define MSENSE_UNASSOCIATED 0x00 38#define MSENSE_UNASSOCIATED 0x00
39#define MSENSE_ASSOCIATED_MOUNT 0x01 39#define MSENSE_ASSOCIATED_MOUNT 0x01
40#define MSENSE_ASSOCIATED_UMOUNT 0x02 40#define MSENSE_ASSOCIATED_UMOUNT 0x02
41#define MSENSE_CRYPT_MASK 0x00000010
41 42
42#define TAPE_3590_MAX_MSG 0xb0 43#define TAPE_3590_MAX_MSG 0xb0
43 44
44/* Datatypes */ 45/* Datatypes */
45 46
46struct tape_3590_disc_data { 47struct tape_3590_disc_data {
47 unsigned char modeset_byte; 48 struct tape390_crypt_info crypt_info;
48 int read_back_op; 49 int read_back_op;
49}; 50};
50 51
52#define TAPE_3590_CRYPT_INFO(device) \
53 ((struct tape_3590_disc_data*)(device->discdata))->crypt_info
54#define TAPE_3590_READ_BACK_OP(device) \
55 ((struct tape_3590_disc_data*)(device->discdata))->read_back_op
56
51struct tape_3590_sense { 57struct tape_3590_sense {
52 58
53 unsigned int command_rej:1; 59 unsigned int command_rej:1;
@@ -118,7 +124,48 @@ struct tape_3590_sense {
118struct tape_3590_med_sense { 124struct tape_3590_med_sense {
119 unsigned int macst:4; 125 unsigned int macst:4;
120 unsigned int masst:4; 126 unsigned int masst:4;
121 char pad[127]; 127 char pad1[7];
128 unsigned int flags;
129 char pad2[116];
130} __attribute__ ((packed));
131
132/* Datastructures for 3592 encryption support */
133
134struct tape3592_kekl {
135 __u8 flags;
136 char label[64];
137} __attribute__ ((packed));
138
139struct tape3592_kekl_pair {
140 __u8 count;
141 struct tape3592_kekl kekl[2];
142} __attribute__ ((packed));
143
144struct tape3592_kekl_query_data {
145 __u16 len;
146 __u8 fmt;
147 __u8 mc;
148 __u32 id;
149 __u8 flags;
150 struct tape3592_kekl_pair kekls;
151 char reserved[116];
152} __attribute__ ((packed));
153
154struct tape3592_kekl_query_order {
155 __u8 code;
156 __u8 flags;
157 char reserved1[2];
158 __u8 max_count;
159 char reserved2[35];
160} __attribute__ ((packed));
161
162struct tape3592_kekl_set_order {
163 __u8 code;
164 __u8 flags;
165 char reserved1[2];
166 __u8 op;
167 struct tape3592_kekl_pair kekls;
168 char reserved2[120];
122} __attribute__ ((packed)); 169} __attribute__ ((packed));
123 170
124#endif /* _TAPE_3590_H */ 171#endif /* _TAPE_3590_H */
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index c8a89b3b87d4..dd0ecaed592e 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -73,7 +73,7 @@ tapeblock_trigger_requeue(struct tape_device *device)
73/* 73/*
74 * Post finished request. 74 * Post finished request.
75 */ 75 */
76static inline void 76static void
77tapeblock_end_request(struct request *req, int uptodate) 77tapeblock_end_request(struct request *req, int uptodate)
78{ 78{
79 if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) 79 if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
@@ -108,7 +108,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
108/* 108/*
109 * Feed the tape device CCW queue with requests supplied in a list. 109 * Feed the tape device CCW queue with requests supplied in a list.
110 */ 110 */
111static inline int 111static int
112tapeblock_start_request(struct tape_device *device, struct request *req) 112tapeblock_start_request(struct tape_device *device, struct request *req)
113{ 113{
114 struct tape_request * ccw_req; 114 struct tape_request * ccw_req;
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 31198c8f2718..9faea04e11e9 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -3,7 +3,7 @@
3 * character device frontend for tape device driver 3 * character device frontend for tape device driver
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright IBM Corp. 2001,2006
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com> 8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
@@ -89,22 +89,7 @@ tapechar_cleanup_device(struct tape_device *device)
89 device->nt = NULL; 89 device->nt = NULL;
90} 90}
91 91
92/* 92static int
93 * Terminate write command (we write two TMs and skip backward over last)
94 * This ensures that the tape is always correctly terminated.
95 * When the user writes afterwards a new file, he will overwrite the
96 * second TM and therefore one TM will remain to separate the
97 * two files on the tape...
98 */
99static inline void
100tapechar_terminate_write(struct tape_device *device)
101{
102 if (tape_mtop(device, MTWEOF, 1) == 0 &&
103 tape_mtop(device, MTWEOF, 1) == 0)
104 tape_mtop(device, MTBSR, 1);
105}
106
107static inline int
108tapechar_check_idalbuffer(struct tape_device *device, size_t block_size) 93tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
109{ 94{
110 struct idal_buffer *new; 95 struct idal_buffer *new;
@@ -137,7 +122,7 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
137/* 122/*
138 * Tape device read function 123 * Tape device read function
139 */ 124 */
140ssize_t 125static ssize_t
141tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) 126tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
142{ 127{
143 struct tape_device *device; 128 struct tape_device *device;
@@ -201,7 +186,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
201/* 186/*
202 * Tape device write function 187 * Tape device write function
203 */ 188 */
204ssize_t 189static ssize_t
205tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos) 190tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos)
206{ 191{
207 struct tape_device *device; 192 struct tape_device *device;
@@ -291,7 +276,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
291/* 276/*
292 * Character frontend tape device open function. 277 * Character frontend tape device open function.
293 */ 278 */
294int 279static int
295tapechar_open (struct inode *inode, struct file *filp) 280tapechar_open (struct inode *inode, struct file *filp)
296{ 281{
297 struct tape_device *device; 282 struct tape_device *device;
@@ -326,7 +311,7 @@ tapechar_open (struct inode *inode, struct file *filp)
326 * Character frontend tape device release function. 311 * Character frontend tape device release function.
327 */ 312 */
328 313
329int 314static int
330tapechar_release(struct inode *inode, struct file *filp) 315tapechar_release(struct inode *inode, struct file *filp)
331{ 316{
332 struct tape_device *device; 317 struct tape_device *device;
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index c6c2e918b990..e2a8a1a04bab 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -3,7 +3,7 @@
3 * basic function of the tape device driver 3 * basic function of the tape device driver
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright IBM Corp. 2001,2006
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com> 8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
@@ -26,9 +26,11 @@
26#include "tape_std.h" 26#include "tape_std.h"
27 27
28#define PRINTK_HEADER "TAPE_CORE: " 28#define PRINTK_HEADER "TAPE_CORE: "
29#define LONG_BUSY_TIMEOUT 180 /* seconds */
29 30
30static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *); 31static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
31static void tape_delayed_next_request(struct work_struct *); 32static void tape_delayed_next_request(struct work_struct *);
33static void tape_long_busy_timeout(unsigned long data);
32 34
33/* 35/*
34 * One list to contain all tape devices of all disciplines, so 36 * One list to contain all tape devices of all disciplines, so
@@ -69,10 +71,12 @@ const char *tape_op_verbose[TO_SIZE] =
69 [TO_LOAD] = "LOA", [TO_READ_CONFIG] = "RCF", 71 [TO_LOAD] = "LOA", [TO_READ_CONFIG] = "RCF",
70 [TO_READ_ATTMSG] = "RAT", 72 [TO_READ_ATTMSG] = "RAT",
71 [TO_DIS] = "DIS", [TO_ASSIGN] = "ASS", 73 [TO_DIS] = "DIS", [TO_ASSIGN] = "ASS",
72 [TO_UNASSIGN] = "UAS" 74 [TO_UNASSIGN] = "UAS", [TO_CRYPT_ON] = "CON",
75 [TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS",
76 [TO_KEKL_QUERY] = "KLQ",
73}; 77};
74 78
75static inline int 79static int
76busid_to_int(char *bus_id) 80busid_to_int(char *bus_id)
77{ 81{
78 int dec; 82 int dec;
@@ -252,7 +256,7 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
252/* 256/*
253 * Stop running ccw. Has to be called with the device lock held. 257 * Stop running ccw. Has to be called with the device lock held.
254 */ 258 */
255static inline int 259static int
256__tape_cancel_io(struct tape_device *device, struct tape_request *request) 260__tape_cancel_io(struct tape_device *device, struct tape_request *request)
257{ 261{
258 int retries; 262 int retries;
@@ -346,6 +350,9 @@ tape_generic_online(struct tape_device *device,
346 return -EINVAL; 350 return -EINVAL;
347 } 351 }
348 352
353 init_timer(&device->lb_timeout);
354 device->lb_timeout.function = tape_long_busy_timeout;
355
349 /* Let the discipline have a go at the device. */ 356 /* Let the discipline have a go at the device. */
350 device->discipline = discipline; 357 device->discipline = discipline;
351 if (!try_module_get(discipline->owner)) { 358 if (!try_module_get(discipline->owner)) {
@@ -385,7 +392,7 @@ out:
385 return rc; 392 return rc;
386} 393}
387 394
388static inline void 395static void
389tape_cleanup_device(struct tape_device *device) 396tape_cleanup_device(struct tape_device *device)
390{ 397{
391 tapeblock_cleanup_device(device); 398 tapeblock_cleanup_device(device);
@@ -563,7 +570,7 @@ tape_generic_probe(struct ccw_device *cdev)
563 return ret; 570 return ret;
564} 571}
565 572
566static inline void 573static void
567__tape_discard_requests(struct tape_device *device) 574__tape_discard_requests(struct tape_device *device)
568{ 575{
569 struct tape_request * request; 576 struct tape_request * request;
@@ -703,7 +710,7 @@ tape_free_request (struct tape_request * request)
703 kfree(request); 710 kfree(request);
704} 711}
705 712
706static inline int 713static int
707__tape_start_io(struct tape_device *device, struct tape_request *request) 714__tape_start_io(struct tape_device *device, struct tape_request *request)
708{ 715{
709 int rc; 716 int rc;
@@ -733,7 +740,7 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
733 return rc; 740 return rc;
734} 741}
735 742
736static inline void 743static void
737__tape_start_next_request(struct tape_device *device) 744__tape_start_next_request(struct tape_device *device)
738{ 745{
739 struct list_head *l, *n; 746 struct list_head *l, *n;
@@ -801,7 +808,23 @@ tape_delayed_next_request(struct work_struct *work)
801 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 808 spin_unlock_irq(get_ccwdev_lock(device->cdev));
802} 809}
803 810
804static inline void 811static void tape_long_busy_timeout(unsigned long data)
812{
813 struct tape_request *request;
814 struct tape_device *device;
815
816 device = (struct tape_device *) data;
817 spin_lock_irq(get_ccwdev_lock(device->cdev));
818 request = list_entry(device->req_queue.next, struct tape_request, list);
819 if (request->status != TAPE_REQUEST_LONG_BUSY)
820 BUG();
821 DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
822 __tape_start_next_request(device);
823 device->lb_timeout.data = (unsigned long) tape_put_device(device);
824 spin_unlock_irq(get_ccwdev_lock(device->cdev));
825}
826
827static void
805__tape_end_request( 828__tape_end_request(
806 struct tape_device * device, 829 struct tape_device * device,
807 struct tape_request * request, 830 struct tape_request * request,
@@ -878,7 +901,7 @@ tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
878 * and starts it if the tape is idle. Has to be called with 901 * and starts it if the tape is idle. Has to be called with
879 * the device lock held. 902 * the device lock held.
880 */ 903 */
881static inline int 904static int
882__tape_start_request(struct tape_device *device, struct tape_request *request) 905__tape_start_request(struct tape_device *device, struct tape_request *request)
883{ 906{
884 int rc; 907 int rc;
@@ -1094,7 +1117,22 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1094 /* May be an unsolicited irq */ 1117 /* May be an unsolicited irq */
1095 if(request != NULL) 1118 if(request != NULL)
1096 request->rescnt = irb->scsw.count; 1119 request->rescnt = irb->scsw.count;
1097 1120 else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) &&
1121 !list_empty(&device->req_queue)) {
1122 /* Not Ready to Ready after long busy ? */
1123 struct tape_request *req;
1124 req = list_entry(device->req_queue.next,
1125 struct tape_request, list);
1126 if (req->status == TAPE_REQUEST_LONG_BUSY) {
1127 DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
1128 if (del_timer(&device->lb_timeout)) {
1129 device->lb_timeout.data = (unsigned long)
1130 tape_put_device(device);
1131 __tape_start_next_request(device);
1132 }
1133 return;
1134 }
1135 }
1098 if (irb->scsw.dstat != 0x0c) { 1136 if (irb->scsw.dstat != 0x0c) {
1099 /* Set the 'ONLINE' flag depending on sense byte 1 */ 1137 /* Set the 'ONLINE' flag depending on sense byte 1 */
1100 if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE) 1138 if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
@@ -1142,6 +1180,15 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1142 break; 1180 break;
1143 case TAPE_IO_PENDING: 1181 case TAPE_IO_PENDING:
1144 break; 1182 break;
1183 case TAPE_IO_LONG_BUSY:
1184 device->lb_timeout.data =
1185 (unsigned long)tape_get_device_reference(device);
1186 device->lb_timeout.expires = jiffies +
1187 LONG_BUSY_TIMEOUT * HZ;
1188 DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
1189 add_timer(&device->lb_timeout);
1190 request->status = TAPE_REQUEST_LONG_BUSY;
1191 break;
1145 case TAPE_IO_RETRY: 1192 case TAPE_IO_RETRY:
1146 rc = __tape_start_io(device, request); 1193 rc = __tape_start_io(device, request);
1147 if (rc) 1194 if (rc)
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 09844621edc0..bc33068b9ce2 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -36,7 +36,7 @@
36struct tty_driver *tty3270_driver; 36struct tty_driver *tty3270_driver;
37static int tty3270_max_index; 37static int tty3270_max_index;
38 38
39struct raw3270_fn tty3270_fn; 39static struct raw3270_fn tty3270_fn;
40 40
41struct tty3270_cell { 41struct tty3270_cell {
42 unsigned char character; 42 unsigned char character;
@@ -119,8 +119,7 @@ static void tty3270_update(struct tty3270 *);
119/* 119/*
120 * Setup timeout for a device. On timeout trigger an update. 120 * Setup timeout for a device. On timeout trigger an update.
121 */ 121 */
122void 122static void tty3270_set_timer(struct tty3270 *tp, int expires)
123tty3270_set_timer(struct tty3270 *tp, int expires)
124{ 123{
125 if (expires == 0) { 124 if (expires == 0) {
126 if (timer_pending(&tp->timer) && del_timer(&tp->timer)) 125 if (timer_pending(&tp->timer) && del_timer(&tp->timer))
@@ -841,7 +840,7 @@ tty3270_del_views(void)
841 } 840 }
842} 841}
843 842
844struct raw3270_fn tty3270_fn = { 843static struct raw3270_fn tty3270_fn = {
845 .activate = tty3270_activate, 844 .activate = tty3270_activate,
846 .deactivate = tty3270_deactivate, 845 .deactivate = tty3270_deactivate,
847 .intv = (void *) tty3270_irq, 846 .intv = (void *) tty3270_irq,
@@ -1754,8 +1753,7 @@ static const struct tty_operations tty3270_ops = {
1754 .set_termios = tty3270_set_termios 1753 .set_termios = tty3270_set_termios
1755}; 1754};
1756 1755
1757void 1756static void tty3270_notifier(int index, int active)
1758tty3270_notifier(int index, int active)
1759{ 1757{
1760 if (active) 1758 if (active)
1761 tty_register_device(tty3270_driver, index, NULL); 1759 tty_register_device(tty3270_driver, index, NULL);
@@ -1767,8 +1765,7 @@ tty3270_notifier(int index, int active)
1767 * 3270 tty registration code called from tty_init(). 1765 * 3270 tty registration code called from tty_init().
1768 * Most kernel services (incl. kmalloc) are available at this poimt. 1766 * Most kernel services (incl. kmalloc) are available at this poimt.
1769 */ 1767 */
1770int __init 1768static int __init tty3270_init(void)
1771tty3270_init(void)
1772{ 1769{
1773 struct tty_driver *driver; 1770 struct tty_driver *driver;
1774 int ret; 1771 int ret;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 6cb23040954b..4f894dc2373b 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -128,9 +128,8 @@ static iucv_interrupt_ops_t vmlogrdr_iucvops = {
128 .MessagePending = vmlogrdr_iucv_MessagePending, 128 .MessagePending = vmlogrdr_iucv_MessagePending,
129}; 129};
130 130
131 131static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
132DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue); 132static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
133DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
134 133
135/* 134/*
136 * pointer to system service private structure 135 * pointer to system service private structure
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 12c2d6b746e6..aa65df4dfced 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -43,7 +43,7 @@ typedef enum {add, free} range_action;
43 * Function: blacklist_range 43 * Function: blacklist_range
44 * (Un-)blacklist the devices from-to 44 * (Un-)blacklist the devices from-to
45 */ 45 */
46static inline void 46static void
47blacklist_range (range_action action, unsigned int from, unsigned int to, 47blacklist_range (range_action action, unsigned int from, unsigned int to,
48 unsigned int ssid) 48 unsigned int ssid)
49{ 49{
@@ -69,7 +69,7 @@ blacklist_range (range_action action, unsigned int from, unsigned int to,
69 * Get devno/busid from given string. 69 * Get devno/busid from given string.
70 * Shamelessly grabbed from dasd_devmap.c. 70 * Shamelessly grabbed from dasd_devmap.c.
71 */ 71 */
72static inline int 72static int
73blacklist_busid(char **str, int *id0, int *ssid, int *devno) 73blacklist_busid(char **str, int *id0, int *ssid, int *devno)
74{ 74{
75 int val, old_style; 75 int val, old_style;
@@ -123,10 +123,10 @@ confused:
123 return 1; 123 return 1;
124} 124}
125 125
126static inline int 126static int
127blacklist_parse_parameters (char *str, range_action action) 127blacklist_parse_parameters (char *str, range_action action)
128{ 128{
129 unsigned int from, to, from_id0, to_id0, from_ssid, to_ssid; 129 int from, to, from_id0, to_id0, from_ssid, to_ssid;
130 130
131 while (*str != 0 && *str != '\n') { 131 while (*str != 0 && *str != '\n') {
132 range_action ra = action; 132 range_action ra = action;
@@ -227,7 +227,7 @@ is_blacklisted (int ssid, int devno)
227 * Function: blacklist_parse_proc_parameters 227 * Function: blacklist_parse_proc_parameters
228 * parse the stuff which is piped to /proc/cio_ignore 228 * parse the stuff which is piped to /proc/cio_ignore
229 */ 229 */
230static inline void 230static void
231blacklist_parse_proc_parameters (char *buf) 231blacklist_parse_proc_parameters (char *buf)
232{ 232{
233 if (strncmp (buf, "free ", 5) == 0) { 233 if (strncmp (buf, "free ", 5) == 0) {
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 38954f5cd14c..d48e3ca4752c 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -53,7 +53,7 @@ ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
53 53
54static struct bus_type ccwgroup_bus_type; 54static struct bus_type ccwgroup_bus_type;
55 55
56static inline void 56static void
57__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) 57__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
58{ 58{
59 int i; 59 int i;
@@ -104,7 +104,7 @@ ccwgroup_release (struct device *dev)
104 kfree(gdev); 104 kfree(gdev);
105} 105}
106 106
107static inline int 107static int
108__ccwgroup_create_symlinks(struct ccwgroup_device *gdev) 108__ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
109{ 109{
110 char str[8]; 110 char str[8];
@@ -424,7 +424,7 @@ ccwgroup_probe_ccwdev(struct ccw_device *cdev)
424 return 0; 424 return 0;
425} 425}
426 426
427static inline struct ccwgroup_device * 427static struct ccwgroup_device *
428__ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) 428__ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
429{ 429{
430 struct ccwgroup_device *gdev; 430 struct ccwgroup_device *gdev;
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index cbab8d2ce5cf..6f05a44e3817 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -93,7 +93,7 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
93 u16 sch; /* subchannel */ 93 u16 sch; /* subchannel */
94 u8 chpid[8]; /* chpids 0-7 */ 94 u8 chpid[8]; /* chpids 0-7 */
95 u16 fla[8]; /* full link addresses 0-7 */ 95 u16 fla[8]; /* full link addresses 0-7 */
96 } *ssd_area; 96 } __attribute__ ((packed)) *ssd_area;
97 97
98 ssd_area = page; 98 ssd_area = page;
99 99
@@ -277,7 +277,7 @@ out_unreg:
277 return 0; 277 return 0;
278} 278}
279 279
280static inline void 280static void
281s390_set_chpid_offline( __u8 chpid) 281s390_set_chpid_offline( __u8 chpid)
282{ 282{
283 char dbf_txt[15]; 283 char dbf_txt[15];
@@ -338,7 +338,7 @@ s390_process_res_acc_sch(struct res_acc_data *res_data, struct subchannel *sch)
338 return 0x80 >> chp; 338 return 0x80 >> chp;
339} 339}
340 340
341static inline int 341static int
342s390_process_res_acc_new_sch(struct subchannel_id schid) 342s390_process_res_acc_new_sch(struct subchannel_id schid)
343{ 343{
344 struct schib schib; 344 struct schib schib;
@@ -444,7 +444,7 @@ __get_chpid_from_lir(void *data)
444 u32 andesc[28]; 444 u32 andesc[28];
445 /* incident-specific information */ 445 /* incident-specific information */
446 u32 isinfo[28]; 446 u32 isinfo[28];
447 } *lir; 447 } __attribute__ ((packed)) *lir;
448 448
449 lir = data; 449 lir = data;
450 if (!(lir->iq&0x80)) 450 if (!(lir->iq&0x80))
@@ -461,154 +461,146 @@ __get_chpid_from_lir(void *data)
461 return (u16) (lir->indesc[0]&0x000000ff); 461 return (u16) (lir->indesc[0]&0x000000ff);
462} 462}
463 463
464int 464struct chsc_sei_area {
465chsc_process_crw(void) 465 struct chsc_header request;
466 u32 reserved1;
467 u32 reserved2;
468 u32 reserved3;
469 struct chsc_header response;
470 u32 reserved4;
471 u8 flags;
472 u8 vf; /* validity flags */
473 u8 rs; /* reporting source */
474 u8 cc; /* content code */
475 u16 fla; /* full link address */
476 u16 rsid; /* reporting source id */
477 u32 reserved5;
478 u32 reserved6;
479 u8 ccdf[4096 - 16 - 24]; /* content-code dependent field */
480 /* ccdf has to be big enough for a link-incident record */
481} __attribute__ ((packed));
482
483static int chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
484{
485 int chpid;
486
487 CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x)\n",
488 sei_area->rs, sei_area->rsid);
489 if (sei_area->rs != 4)
490 return 0;
491 chpid = __get_chpid_from_lir(sei_area->ccdf);
492 if (chpid < 0)
493 CIO_CRW_EVENT(4, "chsc: link incident - invalid LIR\n");
494 else
495 s390_set_chpid_offline(chpid);
496
497 return 0;
498}
499
500static int chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
466{ 501{
467 int chpid, ret;
468 struct res_acc_data res_data; 502 struct res_acc_data res_data;
469 struct { 503 struct device *dev;
470 struct chsc_header request; 504 int status;
471 u32 reserved1; 505 int rc;
472 u32 reserved2; 506
473 u32 reserved3; 507 CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, "
474 struct chsc_header response; 508 "rs_id=%04x)\n", sei_area->rs, sei_area->rsid);
475 u32 reserved4; 509 if (sei_area->rs != 4)
476 u8 flags; 510 return 0;
477 u8 vf; /* validity flags */ 511 /* allocate a new channel path structure, if needed */
478 u8 rs; /* reporting source */ 512 status = get_chp_status(sei_area->rsid);
479 u8 cc; /* content code */ 513 if (status < 0)
480 u16 fla; /* full link address */ 514 new_channel_path(sei_area->rsid);
481 u16 rsid; /* reporting source id */ 515 else if (!status)
482 u32 reserved5; 516 return 0;
483 u32 reserved6; 517 dev = get_device(&css[0]->chps[sei_area->rsid]->dev);
484 u32 ccdf[96]; /* content-code dependent field */ 518 memset(&res_data, 0, sizeof(struct res_acc_data));
485 /* ccdf has to be big enough for a link-incident record */ 519 res_data.chp = to_channelpath(dev);
486 } *sei_area; 520 if ((sei_area->vf & 0xc0) != 0) {
521 res_data.fla = sei_area->fla;
522 if ((sei_area->vf & 0xc0) == 0xc0)
523 /* full link address */
524 res_data.fla_mask = 0xffff;
525 else
526 /* link address */
527 res_data.fla_mask = 0xff00;
528 }
529 rc = s390_process_res_acc(&res_data);
530 put_device(dev);
531
532 return rc;
533}
534
535static int chsc_process_sei(struct chsc_sei_area *sei_area)
536{
537 int rc;
538
539 /* Check if we might have lost some information. */
540 if (sei_area->flags & 0x40)
541 CIO_CRW_EVENT(2, "chsc: event overflow\n");
542 /* which kind of information was stored? */
543 rc = 0;
544 switch (sei_area->cc) {
545 case 1: /* link incident*/
546 rc = chsc_process_sei_link_incident(sei_area);
547 break;
548 case 2: /* i/o resource accessibiliy */
549 rc = chsc_process_sei_res_acc(sei_area);
550 break;
551 default: /* other stuff */
552 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n",
553 sei_area->cc);
554 break;
555 }
556
557 return rc;
558}
559
560int chsc_process_crw(void)
561{
562 struct chsc_sei_area *sei_area;
563 int ret;
564 int rc;
487 565
488 if (!sei_page) 566 if (!sei_page)
489 return 0; 567 return 0;
490 /* 568 /* Access to sei_page is serialized through machine check handler
491 * build the chsc request block for store event information 569 * thread, so no need for locking. */
492 * and do the call
493 * This function is only called by the machine check handler thread,
494 * so we don't need locking for the sei_page.
495 */
496 sei_area = sei_page; 570 sei_area = sei_page;
497 571
498 CIO_TRACE_EVENT( 2, "prcss"); 572 CIO_TRACE_EVENT( 2, "prcss");
499 ret = 0; 573 ret = 0;
500 do { 574 do {
501 int ccode, status;
502 struct device *dev;
503 memset(sei_area, 0, sizeof(*sei_area)); 575 memset(sei_area, 0, sizeof(*sei_area));
504 memset(&res_data, 0, sizeof(struct res_acc_data));
505 sei_area->request.length = 0x0010; 576 sei_area->request.length = 0x0010;
506 sei_area->request.code = 0x000e; 577 sei_area->request.code = 0x000e;
578 if (chsc(sei_area))
579 break;
507 580
508 ccode = chsc(sei_area); 581 if (sei_area->response.code == 0x0001) {
509 if (ccode > 0) 582 CIO_CRW_EVENT(4, "chsc: sei successful\n");
510 return 0; 583 rc = chsc_process_sei(sei_area);
511 584 if (rc)
512 switch (sei_area->response.code) { 585 ret = rc;
513 /* for debug purposes, check for problems */ 586 } else {
514 case 0x0001: 587 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
515 CIO_CRW_EVENT(4, "chsc_process_crw: event information "
516 "successfully stored\n");
517 break; /* everything ok */
518 case 0x0002:
519 CIO_CRW_EVENT(2,
520 "chsc_process_crw: invalid command!\n");
521 return 0;
522 case 0x0003:
523 CIO_CRW_EVENT(2, "chsc_process_crw: error in chsc "
524 "request block!\n");
525 return 0;
526 case 0x0005:
527 CIO_CRW_EVENT(2, "chsc_process_crw: no event "
528 "information stored\n");
529 return 0;
530 default:
531 CIO_CRW_EVENT(2, "chsc_process_crw: chsc response %d\n",
532 sei_area->response.code); 588 sei_area->response.code);
533 return 0; 589 ret = 0;
534 }
535
536 /* Check if we might have lost some information. */
537 if (sei_area->flags & 0x40)
538 CIO_CRW_EVENT(2, "chsc_process_crw: Event information "
539 "has been lost due to overflow!\n");
540
541 if (sei_area->rs != 4) {
542 CIO_CRW_EVENT(2, "chsc_process_crw: reporting source "
543 "(%04X) isn't a chpid!\n",
544 sei_area->rsid);
545 continue;
546 }
547
548 /* which kind of information was stored? */
549 switch (sei_area->cc) {
550 case 1: /* link incident*/
551 CIO_CRW_EVENT(4, "chsc_process_crw: "
552 "channel subsystem reports link incident,"
553 " reporting source is chpid %x\n",
554 sei_area->rsid);
555 chpid = __get_chpid_from_lir(sei_area->ccdf);
556 if (chpid < 0)
557 CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n",
558 __FUNCTION__);
559 else
560 s390_set_chpid_offline(chpid);
561 break;
562
563 case 2: /* i/o resource accessibiliy */
564 CIO_CRW_EVENT(4, "chsc_process_crw: "
565 "channel subsystem reports some I/O "
566 "devices may have become accessible\n");
567 pr_debug("Data received after sei: \n");
568 pr_debug("Validity flags: %x\n", sei_area->vf);
569
570 /* allocate a new channel path structure, if needed */
571 status = get_chp_status(sei_area->rsid);
572 if (status < 0)
573 new_channel_path(sei_area->rsid);
574 else if (!status)
575 break;
576 dev = get_device(&css[0]->chps[sei_area->rsid]->dev);
577 res_data.chp = to_channelpath(dev);
578 pr_debug("chpid: %x", sei_area->rsid);
579 if ((sei_area->vf & 0xc0) != 0) {
580 res_data.fla = sei_area->fla;
581 if ((sei_area->vf & 0xc0) == 0xc0) {
582 pr_debug(" full link addr: %x",
583 sei_area->fla);
584 res_data.fla_mask = 0xffff;
585 } else {
586 pr_debug(" link addr: %x",
587 sei_area->fla);
588 res_data.fla_mask = 0xff00;
589 }
590 }
591 ret = s390_process_res_acc(&res_data);
592 pr_debug("\n\n");
593 put_device(dev);
594 break;
595
596 default: /* other stuff */
597 CIO_CRW_EVENT(4, "chsc_process_crw: event %d\n",
598 sei_area->cc);
599 break; 590 break;
600 } 591 }
601 } while (sei_area->flags & 0x80); 592 } while (sei_area->flags & 0x80);
593
602 return ret; 594 return ret;
603} 595}
604 596
605static inline int 597static int
606__chp_add_new_sch(struct subchannel_id schid) 598__chp_add_new_sch(struct subchannel_id schid)
607{ 599{
608 struct schib schib; 600 struct schib schib;
609 int ret; 601 int ret;
610 602
611 if (stsch(schid, &schib)) 603 if (stsch_err(schid, &schib))
612 /* We're through */ 604 /* We're through */
613 return need_rescan ? -EAGAIN : -ENXIO; 605 return need_rescan ? -EAGAIN : -ENXIO;
614 606
@@ -709,7 +701,7 @@ chp_process_crw(int chpid, int on)
709 return chp_add(chpid); 701 return chp_add(chpid);
710} 702}
711 703
712static inline int check_for_io_on_path(struct subchannel *sch, int index) 704static int check_for_io_on_path(struct subchannel *sch, int index)
713{ 705{
714 int cc; 706 int cc;
715 707
@@ -741,7 +733,7 @@ static void terminate_internal_io(struct subchannel *sch)
741 sch->driver->termination(&sch->dev); 733 sch->driver->termination(&sch->dev);
742} 734}
743 735
744static inline void 736static void
745__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) 737__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
746{ 738{
747 int chp, old_lpm; 739 int chp, old_lpm;
@@ -967,8 +959,8 @@ static struct bin_attribute chp_measurement_attr = {
967static void 959static void
968chsc_remove_chp_cmg_attr(struct channel_path *chp) 960chsc_remove_chp_cmg_attr(struct channel_path *chp)
969{ 961{
970 sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_chars_attr); 962 device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
971 sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_attr); 963 device_remove_bin_file(&chp->dev, &chp_measurement_attr);
972} 964}
973 965
974static int 966static int
@@ -976,14 +968,12 @@ chsc_add_chp_cmg_attr(struct channel_path *chp)
976{ 968{
977 int ret; 969 int ret;
978 970
979 ret = sysfs_create_bin_file(&chp->dev.kobj, 971 ret = device_create_bin_file(&chp->dev, &chp_measurement_chars_attr);
980 &chp_measurement_chars_attr);
981 if (ret) 972 if (ret)
982 return ret; 973 return ret;
983 ret = sysfs_create_bin_file(&chp->dev.kobj, &chp_measurement_attr); 974 ret = device_create_bin_file(&chp->dev, &chp_measurement_attr);
984 if (ret) 975 if (ret)
985 sysfs_remove_bin_file(&chp->dev.kobj, 976 device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
986 &chp_measurement_chars_attr);
987 return ret; 977 return ret;
988} 978}
989 979
@@ -1042,7 +1032,7 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
1042 u32 : 4; 1032 u32 : 4;
1043 u32 fmt : 4; 1033 u32 fmt : 4;
1044 u32 : 16; 1034 u32 : 16;
1045 } *secm_area; 1035 } __attribute__ ((packed)) *secm_area;
1046 int ret, ccode; 1036 int ret, ccode;
1047 1037
1048 secm_area = page; 1038 secm_area = page;
@@ -1253,7 +1243,7 @@ chsc_determine_channel_path_description(int chpid,
1253 struct chsc_header response; 1243 struct chsc_header response;
1254 u32 zeroes2; 1244 u32 zeroes2;
1255 struct channel_path_desc desc; 1245 struct channel_path_desc desc;
1256 } *scpd_area; 1246 } __attribute__ ((packed)) *scpd_area;
1257 1247
1258 scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 1248 scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1259 if (!scpd_area) 1249 if (!scpd_area)
@@ -1350,7 +1340,7 @@ chsc_get_channel_measurement_chars(struct channel_path *chp)
1350 u32 cmg : 8; 1340 u32 cmg : 8;
1351 u32 zeroes3; 1341 u32 zeroes3;
1352 u32 data[NR_MEASUREMENT_CHARS]; 1342 u32 data[NR_MEASUREMENT_CHARS];
1353 } *scmc_area; 1343 } __attribute__ ((packed)) *scmc_area;
1354 1344
1355 scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 1345 scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1356 if (!scmc_area) 1346 if (!scmc_area)
@@ -1517,7 +1507,7 @@ chsc_enable_facility(int operation_code)
1517 u32 reserved5:4; 1507 u32 reserved5:4;
1518 u32 format2:4; 1508 u32 format2:4;
1519 u32 reserved6:24; 1509 u32 reserved6:24;
1520 } *sda_area; 1510 } __attribute__ ((packed)) *sda_area;
1521 1511
1522 sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); 1512 sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
1523 if (!sda_area) 1513 if (!sda_area)
@@ -1569,7 +1559,7 @@ chsc_determine_css_characteristics(void)
1569 u32 reserved4; 1559 u32 reserved4;
1570 u32 general_char[510]; 1560 u32 general_char[510];
1571 u32 chsc_char[518]; 1561 u32 chsc_char[518];
1572 } *scsc_area; 1562 } __attribute__ ((packed)) *scsc_area;
1573 1563
1574 scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 1564 scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1575 if (!scsc_area) { 1565 if (!scsc_area) {
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index a259245780ae..0fb2b024208f 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -10,17 +10,17 @@
10struct chsc_header { 10struct chsc_header {
11 u16 length; 11 u16 length;
12 u16 code; 12 u16 code;
13}; 13} __attribute__ ((packed));
14 14
15#define NR_MEASUREMENT_CHARS 5 15#define NR_MEASUREMENT_CHARS 5
16struct cmg_chars { 16struct cmg_chars {
17 u32 values[NR_MEASUREMENT_CHARS]; 17 u32 values[NR_MEASUREMENT_CHARS];
18}; 18} __attribute__ ((packed));
19 19
20#define NR_MEASUREMENT_ENTRIES 8 20#define NR_MEASUREMENT_ENTRIES 8
21struct cmg_entry { 21struct cmg_entry {
22 u32 values[NR_MEASUREMENT_ENTRIES]; 22 u32 values[NR_MEASUREMENT_ENTRIES];
23}; 23} __attribute__ ((packed));
24 24
25struct channel_path_desc { 25struct channel_path_desc {
26 u8 flags; 26 u8 flags;
@@ -31,7 +31,7 @@ struct channel_path_desc {
31 u8 zeroes; 31 u8 zeroes;
32 u8 chla; 32 u8 chla;
33 u8 chpp; 33 u8 chpp;
34}; 34} __attribute__ ((packed));
35 35
36struct channel_path { 36struct channel_path {
37 int id; 37 int id;
@@ -47,6 +47,9 @@ struct channel_path {
47extern void s390_process_css( void ); 47extern void s390_process_css( void );
48extern void chsc_validate_chpids(struct subchannel *); 48extern void chsc_validate_chpids(struct subchannel *);
49extern void chpid_is_actually_online(int); 49extern void chpid_is_actually_online(int);
50extern int css_get_ssd_info(struct subchannel *);
51extern int chsc_process_crw(void);
52extern int chp_process_crw(int, int);
50 53
51struct css_general_char { 54struct css_general_char {
52 u64 : 41; 55 u64 : 41;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index ae1bf231d089..b3a56dc5f68a 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -122,7 +122,7 @@ cio_get_options (struct subchannel *sch)
122 * Use tpi to get a pending interrupt, call the interrupt handler and 122 * Use tpi to get a pending interrupt, call the interrupt handler and
123 * return a pointer to the subchannel structure. 123 * return a pointer to the subchannel structure.
124 */ 124 */
125static inline int 125static int
126cio_tpi(void) 126cio_tpi(void)
127{ 127{
128 struct tpi_info *tpi_info; 128 struct tpi_info *tpi_info;
@@ -152,7 +152,7 @@ cio_tpi(void)
152 return 1; 152 return 1;
153} 153}
154 154
155static inline int 155static int
156cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) 156cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
157{ 157{
158 char dbf_text[15]; 158 char dbf_text[15];
@@ -585,7 +585,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
585 * This device must not be known to Linux. So we simply 585 * This device must not be known to Linux. So we simply
586 * say that there is no device and return ENODEV. 586 * say that there is no device and return ENODEV.
587 */ 587 */
588 CIO_MSG_EVENT(0, "Blacklisted device detected " 588 CIO_MSG_EVENT(4, "Blacklisted device detected "
589 "at devno %04X, subchannel set %x\n", 589 "at devno %04X, subchannel set %x\n",
590 sch->schib.pmcw.dev, sch->schid.ssid); 590 sch->schib.pmcw.dev, sch->schid.ssid);
591 err = -ENODEV; 591 err = -ENODEV;
@@ -646,7 +646,7 @@ do_IRQ (struct pt_regs *regs)
646 * Make sure that the i/o interrupt did not "overtake" 646 * Make sure that the i/o interrupt did not "overtake"
647 * the last HZ timer interrupt. 647 * the last HZ timer interrupt.
648 */ 648 */
649 account_ticks(); 649 account_ticks(S390_lowcore.int_clock);
650 /* 650 /*
651 * Get interrupt information from lowcore 651 * Get interrupt information from lowcore
652 */ 652 */
@@ -832,7 +832,7 @@ cio_get_console_subchannel(void)
832} 832}
833 833
834#endif 834#endif
835static inline int 835static int
836__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) 836__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
837{ 837{
838 int retry, cc; 838 int retry, cc;
@@ -850,7 +850,20 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
850 return -EBUSY; /* uhm... */ 850 return -EBUSY; /* uhm... */
851} 851}
852 852
853static inline int 853/* we can't use the normal udelay here, since it enables external interrupts */
854
855static void udelay_reset(unsigned long usecs)
856{
857 uint64_t start_cc, end_cc;
858
859 asm volatile ("STCK %0" : "=m" (start_cc));
860 do {
861 cpu_relax();
862 asm volatile ("STCK %0" : "=m" (end_cc));
863 } while (((end_cc - start_cc)/4096) < usecs);
864}
865
866static int
854__clear_subchannel_easy(struct subchannel_id schid) 867__clear_subchannel_easy(struct subchannel_id schid)
855{ 868{
856 int retry; 869 int retry;
@@ -865,7 +878,7 @@ __clear_subchannel_easy(struct subchannel_id schid)
865 if (schid_equal(&ti.schid, &schid)) 878 if (schid_equal(&ti.schid, &schid))
866 return 0; 879 return 0;
867 } 880 }
868 udelay(100); 881 udelay_reset(100);
869 } 882 }
870 return -EBUSY; 883 return -EBUSY;
871} 884}
@@ -882,11 +895,11 @@ static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr)
882 int rc; 895 int rc;
883 896
884 pgm_check_occured = 0; 897 pgm_check_occured = 0;
885 s390_reset_pgm_handler = cio_reset_pgm_check_handler; 898 s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
886 rc = stsch(schid, addr); 899 rc = stsch(schid, addr);
887 s390_reset_pgm_handler = NULL; 900 s390_base_pgm_handler_fn = NULL;
888 901
889 /* The program check handler could have changed pgm_check_occured */ 902 /* The program check handler could have changed pgm_check_occured. */
890 barrier(); 903 barrier();
891 904
892 if (pgm_check_occured) 905 if (pgm_check_occured)
@@ -944,7 +957,7 @@ static void css_reset(void)
944 /* Reset subchannels. */ 957 /* Reset subchannels. */
945 for_each_subchannel(__shutdown_subchannel_easy, NULL); 958 for_each_subchannel(__shutdown_subchannel_easy, NULL);
946 /* Reset channel paths. */ 959 /* Reset channel paths. */
947 s390_reset_mcck_handler = s390_reset_chpids_mcck_handler; 960 s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler;
948 /* Enable channel report machine checks. */ 961 /* Enable channel report machine checks. */
949 __ctl_set_bit(14, 28); 962 __ctl_set_bit(14, 28);
950 /* Temporarily reenable machine checks. */ 963 /* Temporarily reenable machine checks. */
@@ -969,7 +982,7 @@ static void css_reset(void)
969 local_mcck_disable(); 982 local_mcck_disable();
970 /* Disable channel report machine checks. */ 983 /* Disable channel report machine checks. */
971 __ctl_clear_bit(14, 28); 984 __ctl_clear_bit(14, 28);
972 s390_reset_mcck_handler = NULL; 985 s390_base_mcck_handler_fn = NULL;
973} 986}
974 987
975static struct reset_call css_reset_call = { 988static struct reset_call css_reset_call = {
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 828b2d334f0a..90b22faabbf7 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -519,8 +519,8 @@ struct cmb {
519/* insert a single device into the cmb_area list 519/* insert a single device into the cmb_area list
520 * called with cmb_area.lock held from alloc_cmb 520 * called with cmb_area.lock held from alloc_cmb
521 */ 521 */
522static inline int alloc_cmb_single (struct ccw_device *cdev, 522static int alloc_cmb_single(struct ccw_device *cdev,
523 struct cmb_data *cmb_data) 523 struct cmb_data *cmb_data)
524{ 524{
525 struct cmb *cmb; 525 struct cmb *cmb;
526 struct ccw_device_private *node; 526 struct ccw_device_private *node;
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 9d6c02446863..fe0ace7aece8 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -30,7 +30,7 @@ struct channel_subsystem *css[__MAX_CSSID + 1];
30 30
31int css_characteristics_avail = 0; 31int css_characteristics_avail = 0;
32 32
33inline int 33int
34for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) 34for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
35{ 35{
36 struct subchannel_id schid; 36 struct subchannel_id schid;
@@ -108,9 +108,6 @@ css_subchannel_release(struct device *dev)
108 } 108 }
109} 109}
110 110
111extern int css_get_ssd_info(struct subchannel *sch);
112
113
114int css_sch_device_register(struct subchannel *sch) 111int css_sch_device_register(struct subchannel *sch)
115{ 112{
116 int ret; 113 int ret;
@@ -187,7 +184,7 @@ get_subchannel_by_schid(struct subchannel_id schid)
187 return dev ? to_subchannel(dev) : NULL; 184 return dev ? to_subchannel(dev) : NULL;
188} 185}
189 186
190static inline int css_get_subchannel_status(struct subchannel *sch) 187static int css_get_subchannel_status(struct subchannel *sch)
191{ 188{
192 struct schib schib; 189 struct schib schib;
193 190
@@ -299,7 +296,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
299 /* Will be done on the slow path. */ 296 /* Will be done on the slow path. */
300 return -EAGAIN; 297 return -EAGAIN;
301 } 298 }
302 if (stsch(schid, &schib) || !schib.pmcw.dnv) { 299 if (stsch_err(schid, &schib) || !schib.pmcw.dnv) {
303 /* Unusable - ignore. */ 300 /* Unusable - ignore. */
304 return 0; 301 return 0;
305 } 302 }
@@ -417,7 +414,7 @@ static void reprobe_all(struct work_struct *unused)
417 need_reprobe); 414 need_reprobe);
418} 415}
419 416
420DECLARE_WORK(css_reprobe_work, reprobe_all); 417static DECLARE_WORK(css_reprobe_work, reprobe_all);
421 418
422/* Schedule reprobing of all unregistered subchannels. */ 419/* Schedule reprobing of all unregistered subchannels. */
423void css_schedule_reprobe(void) 420void css_schedule_reprobe(void)
@@ -578,7 +575,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
578 575
579static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); 576static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
580 577
581static inline int __init setup_css(int nr) 578static int __init setup_css(int nr)
582{ 579{
583 u32 tod_high; 580 u32 tod_high;
584 int ret; 581 int ret;
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 3464c5b875c4..ca2bab932a8a 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -143,6 +143,8 @@ extern void css_sch_device_unregister(struct subchannel *);
143extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); 143extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
144extern int css_init_done; 144extern int css_init_done;
145extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); 145extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
146extern int css_process_crw(int, int);
147extern void css_reiterate_subchannels(void);
146 148
147#define __MAX_SUBCHANNEL 65535 149#define __MAX_SUBCHANNEL 65535
148#define __MAX_SSID 3 150#define __MAX_SSID 3
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 803579053c2f..e322111fb369 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -138,7 +138,6 @@ struct bus_type ccw_bus_type;
138 138
139static int io_subchannel_probe (struct subchannel *); 139static int io_subchannel_probe (struct subchannel *);
140static int io_subchannel_remove (struct subchannel *); 140static int io_subchannel_remove (struct subchannel *);
141void io_subchannel_irq (struct device *);
142static int io_subchannel_notify(struct device *, int); 141static int io_subchannel_notify(struct device *, int);
143static void io_subchannel_verify(struct device *); 142static void io_subchannel_verify(struct device *);
144static void io_subchannel_ioterm(struct device *); 143static void io_subchannel_ioterm(struct device *);
@@ -235,11 +234,8 @@ chpids_show (struct device * dev, struct device_attribute *attr, char * buf)
235 ssize_t ret = 0; 234 ssize_t ret = 0;
236 int chp; 235 int chp;
237 236
238 if (ssd) 237 for (chp = 0; chp < 8; chp++)
239 for (chp = 0; chp < 8; chp++) 238 ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
240 ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
241 else
242 ret += sprintf (buf, "n/a");
243 ret += sprintf (buf+ret, "\n"); 239 ret += sprintf (buf+ret, "\n");
244 return min((ssize_t)PAGE_SIZE, ret); 240 return min((ssize_t)PAGE_SIZE, ret);
245} 241}
@@ -552,13 +548,13 @@ static struct attribute_group ccwdev_attr_group = {
552 .attrs = ccwdev_attrs, 548 .attrs = ccwdev_attrs,
553}; 549};
554 550
555static inline int 551static int
556device_add_files (struct device *dev) 552device_add_files (struct device *dev)
557{ 553{
558 return sysfs_create_group(&dev->kobj, &ccwdev_attr_group); 554 return sysfs_create_group(&dev->kobj, &ccwdev_attr_group);
559} 555}
560 556
561static inline void 557static void
562device_remove_files(struct device *dev) 558device_remove_files(struct device *dev)
563{ 559{
564 sysfs_remove_group(&dev->kobj, &ccwdev_attr_group); 560 sysfs_remove_group(&dev->kobj, &ccwdev_attr_group);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 29db6341d632..b66338b76579 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -74,6 +74,7 @@ extern struct workqueue_struct *ccw_device_notify_work;
74extern wait_queue_head_t ccw_device_init_wq; 74extern wait_queue_head_t ccw_device_init_wq;
75extern atomic_t ccw_device_init_count; 75extern atomic_t ccw_device_init_count;
76 76
77void io_subchannel_irq (struct device *pdev);
77void io_subchannel_recog_done(struct ccw_device *cdev); 78void io_subchannel_recog_done(struct ccw_device *cdev);
78 79
79int ccw_device_cancel_halt_clear(struct ccw_device *); 80int ccw_device_cancel_halt_clear(struct ccw_device *);
@@ -118,6 +119,7 @@ int ccw_device_stlck(struct ccw_device *);
118/* qdio needs this. */ 119/* qdio needs this. */
119void ccw_device_set_timeout(struct ccw_device *, int); 120void ccw_device_set_timeout(struct ccw_device *, int);
120extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); 121extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
122extern struct bus_type ccw_bus_type;
121 123
122/* Channel measurement facility related */ 124/* Channel measurement facility related */
123void retry_set_schib(struct ccw_device *cdev); 125void retry_set_schib(struct ccw_device *cdev);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index eed14572fc3b..51238e7555bb 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -206,7 +206,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
206 * been varied online on the SE so we have to find out by magic (i. e. driving 206 * been varied online on the SE so we have to find out by magic (i. e. driving
207 * the channel subsystem to device selection and updating our path masks). 207 * the channel subsystem to device selection and updating our path masks).
208 */ 208 */
209static inline void 209static void
210__recover_lost_chpids(struct subchannel *sch, int old_lpm) 210__recover_lost_chpids(struct subchannel *sch, int old_lpm)
211{ 211{
212 int mask, i; 212 int mask, i;
@@ -387,7 +387,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
387 put_device (&cdev->dev); 387 put_device (&cdev->dev);
388} 388}
389 389
390static inline int cmp_pgid(struct pgid *p1, struct pgid *p2) 390static int cmp_pgid(struct pgid *p1, struct pgid *p2)
391{ 391{
392 char *c1; 392 char *c1;
393 char *c2; 393 char *c2;
@@ -842,6 +842,8 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
842call_handler_unsol: 842call_handler_unsol:
843 if (cdev->handler) 843 if (cdev->handler)
844 cdev->handler (cdev, 0, irb); 844 cdev->handler (cdev, 0, irb);
845 if (cdev->private->flags.doverify)
846 ccw_device_online_verify(cdev, 0);
845 return; 847 return;
846 } 848 }
847 /* Accumulate status and find out if a basic sense is needed. */ 849 /* Accumulate status and find out if a basic sense is needed. */
@@ -892,7 +894,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
892/* 894/*
893 * Got an interrupt for a basic sense. 895 * Got an interrupt for a basic sense.
894 */ 896 */
895void 897static void
896ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) 898ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
897{ 899{
898 struct irb *irb; 900 struct irb *irb;
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index d269607336ec..d7b25b8f71d2 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -302,7 +302,7 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
302 wake_up(&cdev->private->wait_q); 302 wake_up(&cdev->private->wait_q);
303} 303}
304 304
305static inline int 305static int
306__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, __u8 lpm) 306__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, __u8 lpm)
307{ 307{
308 int ret; 308 int ret;
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index bdcf930f7beb..6b1caea622ea 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -25,7 +25,7 @@
25 * Check for any kind of channel or interface control check but don't 25 * Check for any kind of channel or interface control check but don't
26 * issue the message for the console device 26 * issue the message for the console device
27 */ 27 */
28static inline void 28static void
29ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) 29ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
30{ 30{
31 if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK | 31 if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK |
@@ -72,7 +72,7 @@ ccw_device_path_notoper(struct ccw_device *cdev)
72/* 72/*
73 * Copy valid bits from the extended control word to device irb. 73 * Copy valid bits from the extended control word to device irb.
74 */ 74 */
75static inline void 75static void
76ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb) 76ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
77{ 77{
78 /* 78 /*
@@ -94,7 +94,7 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
94/* 94/*
95 * Check if extended status word is valid. 95 * Check if extended status word is valid.
96 */ 96 */
97static inline int 97static int
98ccw_device_accumulate_esw_valid(struct irb *irb) 98ccw_device_accumulate_esw_valid(struct irb *irb)
99{ 99{
100 if (!irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) 100 if (!irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND)
@@ -109,7 +109,7 @@ ccw_device_accumulate_esw_valid(struct irb *irb)
109/* 109/*
110 * Copy valid bits from the extended status word to device irb. 110 * Copy valid bits from the extended status word to device irb.
111 */ 111 */
112static inline void 112static void
113ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb) 113ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
114{ 114{
115 struct irb *cdev_irb; 115 struct irb *cdev_irb;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 6fd1940842eb..d726cd5777de 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -66,7 +66,6 @@ MODULE_LICENSE("GPL");
66/******************** HERE WE GO ***********************************/ 66/******************** HERE WE GO ***********************************/
67 67
68static const char version[] = "QDIO base support version 2"; 68static const char version[] = "QDIO base support version 2";
69extern struct bus_type ccw_bus_type;
70 69
71static int qdio_performance_stats = 0; 70static int qdio_performance_stats = 0;
72static int proc_perf_file_registration; 71static int proc_perf_file_registration;
@@ -138,7 +137,7 @@ qdio_release_q(struct qdio_q *q)
138} 137}
139 138
140/*check ccq */ 139/*check ccq */
141static inline int 140static int
142qdio_check_ccq(struct qdio_q *q, unsigned int ccq) 141qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
143{ 142{
144 char dbf_text[15]; 143 char dbf_text[15];
@@ -153,7 +152,7 @@ qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
153 return -EIO; 152 return -EIO;
154} 153}
155/* EQBS: extract buffer states */ 154/* EQBS: extract buffer states */
156static inline int 155static int
157qdio_do_eqbs(struct qdio_q *q, unsigned char *state, 156qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
158 unsigned int *start, unsigned int *cnt) 157 unsigned int *start, unsigned int *cnt)
159{ 158{
@@ -188,7 +187,7 @@ again:
188} 187}
189 188
190/* SQBS: set buffer states */ 189/* SQBS: set buffer states */
191static inline int 190static int
192qdio_do_sqbs(struct qdio_q *q, unsigned char state, 191qdio_do_sqbs(struct qdio_q *q, unsigned char state,
193 unsigned int *start, unsigned int *cnt) 192 unsigned int *start, unsigned int *cnt)
194{ 193{
@@ -315,7 +314,7 @@ __do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
315 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns 314 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
316 * an access exception 315 * an access exception
317 */ 316 */
318static inline int 317static int
319qdio_siga_output(struct qdio_q *q) 318qdio_siga_output(struct qdio_q *q)
320{ 319{
321 int cc; 320 int cc;
@@ -349,7 +348,7 @@ qdio_siga_output(struct qdio_q *q)
349 return cc; 348 return cc;
350} 349}
351 350
352static inline int 351static int
353qdio_siga_input(struct qdio_q *q) 352qdio_siga_input(struct qdio_q *q)
354{ 353{
355 int cc; 354 int cc;
@@ -421,7 +420,7 @@ tiqdio_sched_tl(void)
421 tasklet_hi_schedule(&tiqdio_tasklet); 420 tasklet_hi_schedule(&tiqdio_tasklet);
422} 421}
423 422
424static inline void 423static void
425qdio_mark_tiq(struct qdio_q *q) 424qdio_mark_tiq(struct qdio_q *q)
426{ 425{
427 unsigned long flags; 426 unsigned long flags;
@@ -471,7 +470,7 @@ qdio_mark_q(struct qdio_q *q)
471 tasklet_schedule(&q->tasklet); 470 tasklet_schedule(&q->tasklet);
472} 471}
473 472
474static inline int 473static int
475qdio_stop_polling(struct qdio_q *q) 474qdio_stop_polling(struct qdio_q *q)
476{ 475{
477#ifdef QDIO_USE_PROCESSING_STATE 476#ifdef QDIO_USE_PROCESSING_STATE
@@ -525,7 +524,7 @@ qdio_stop_polling(struct qdio_q *q)
525 * sophisticated locking outside of unmark_q, so that we don't need to 524 * sophisticated locking outside of unmark_q, so that we don't need to
526 * disable the interrupts :-) 525 * disable the interrupts :-)
527*/ 526*/
528static inline void 527static void
529qdio_unmark_q(struct qdio_q *q) 528qdio_unmark_q(struct qdio_q *q)
530{ 529{
531 unsigned long flags; 530 unsigned long flags;
@@ -691,7 +690,7 @@ qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q)
691 return q->first_to_check; 690 return q->first_to_check;
692} 691}
693 692
694static inline int 693static int
695qdio_get_outbound_buffer_frontier(struct qdio_q *q) 694qdio_get_outbound_buffer_frontier(struct qdio_q *q)
696{ 695{
697 struct qdio_irq *irq; 696 struct qdio_irq *irq;
@@ -774,7 +773,7 @@ out:
774} 773}
775 774
776/* all buffers are processed */ 775/* all buffers are processed */
777static inline int 776static int
778qdio_is_outbound_q_done(struct qdio_q *q) 777qdio_is_outbound_q_done(struct qdio_q *q)
779{ 778{
780 int no_used; 779 int no_used;
@@ -796,7 +795,7 @@ qdio_is_outbound_q_done(struct qdio_q *q)
796 return (no_used==0); 795 return (no_used==0);
797} 796}
798 797
799static inline int 798static int
800qdio_has_outbound_q_moved(struct qdio_q *q) 799qdio_has_outbound_q_moved(struct qdio_q *q)
801{ 800{
802 int i; 801 int i;
@@ -816,7 +815,7 @@ qdio_has_outbound_q_moved(struct qdio_q *q)
816 } 815 }
817} 816}
818 817
819static inline void 818static void
820qdio_kick_outbound_q(struct qdio_q *q) 819qdio_kick_outbound_q(struct qdio_q *q)
821{ 820{
822 int result; 821 int result;
@@ -905,7 +904,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
905 } 904 }
906} 905}
907 906
908static inline void 907static void
909qdio_kick_outbound_handler(struct qdio_q *q) 908qdio_kick_outbound_handler(struct qdio_q *q)
910{ 909{
911 int start, end, real_end, count; 910 int start, end, real_end, count;
@@ -942,7 +941,7 @@ qdio_kick_outbound_handler(struct qdio_q *q)
942 q->error_status_flags=0; 941 q->error_status_flags=0;
943} 942}
944 943
945static inline void 944static void
946__qdio_outbound_processing(struct qdio_q *q) 945__qdio_outbound_processing(struct qdio_q *q)
947{ 946{
948 int siga_attempts; 947 int siga_attempts;
@@ -1002,7 +1001,7 @@ qdio_outbound_processing(struct qdio_q *q)
1002/************************* INBOUND ROUTINES *******************************/ 1001/************************* INBOUND ROUTINES *******************************/
1003 1002
1004 1003
1005static inline int 1004static int
1006qdio_get_inbound_buffer_frontier(struct qdio_q *q) 1005qdio_get_inbound_buffer_frontier(struct qdio_q *q)
1007{ 1006{
1008 struct qdio_irq *irq; 1007 struct qdio_irq *irq;
@@ -1133,7 +1132,7 @@ out:
1133 return q->first_to_check; 1132 return q->first_to_check;
1134} 1133}
1135 1134
1136static inline int 1135static int
1137qdio_has_inbound_q_moved(struct qdio_q *q) 1136qdio_has_inbound_q_moved(struct qdio_q *q)
1138{ 1137{
1139 int i; 1138 int i;
@@ -1167,7 +1166,7 @@ qdio_has_inbound_q_moved(struct qdio_q *q)
1167} 1166}
1168 1167
1169/* means, no more buffers to be filled */ 1168/* means, no more buffers to be filled */
1170static inline int 1169static int
1171tiqdio_is_inbound_q_done(struct qdio_q *q) 1170tiqdio_is_inbound_q_done(struct qdio_q *q)
1172{ 1171{
1173 int no_used; 1172 int no_used;
@@ -1228,7 +1227,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
1228 return 0; 1227 return 0;
1229} 1228}
1230 1229
1231static inline int 1230static int
1232qdio_is_inbound_q_done(struct qdio_q *q) 1231qdio_is_inbound_q_done(struct qdio_q *q)
1233{ 1232{
1234 int no_used; 1233 int no_used;
@@ -1296,7 +1295,7 @@ qdio_is_inbound_q_done(struct qdio_q *q)
1296 } 1295 }
1297} 1296}
1298 1297
1299static inline void 1298static void
1300qdio_kick_inbound_handler(struct qdio_q *q) 1299qdio_kick_inbound_handler(struct qdio_q *q)
1301{ 1300{
1302 int count, start, end, real_end, i; 1301 int count, start, end, real_end, i;
@@ -1343,7 +1342,7 @@ qdio_kick_inbound_handler(struct qdio_q *q)
1343 } 1342 }
1344} 1343}
1345 1344
1346static inline void 1345static void
1347__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) 1346__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set)
1348{ 1347{
1349 struct qdio_irq *irq_ptr; 1348 struct qdio_irq *irq_ptr;
@@ -1442,7 +1441,7 @@ tiqdio_inbound_processing(struct qdio_q *q)
1442 __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount)); 1441 __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount));
1443} 1442}
1444 1443
1445static inline void 1444static void
1446__qdio_inbound_processing(struct qdio_q *q) 1445__qdio_inbound_processing(struct qdio_q *q)
1447{ 1446{
1448 int q_laps=0; 1447 int q_laps=0;
@@ -1493,7 +1492,7 @@ qdio_inbound_processing(struct qdio_q *q)
1493/************************* MAIN ROUTINES *******************************/ 1492/************************* MAIN ROUTINES *******************************/
1494 1493
1495#ifdef QDIO_USE_PROCESSING_STATE 1494#ifdef QDIO_USE_PROCESSING_STATE
1496static inline int 1495static int
1497tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) 1496tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
1498{ 1497{
1499 if (!q) { 1498 if (!q) {
@@ -1545,7 +1544,7 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
1545} 1544}
1546#endif /* QDIO_USE_PROCESSING_STATE */ 1545#endif /* QDIO_USE_PROCESSING_STATE */
1547 1546
1548static inline void 1547static void
1549tiqdio_inbound_checks(void) 1548tiqdio_inbound_checks(void)
1550{ 1549{
1551 struct qdio_q *q; 1550 struct qdio_q *q;
@@ -1949,7 +1948,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state)
1949 mb(); 1948 mb();
1950} 1949}
1951 1950
1952static inline void 1951static void
1953qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) 1952qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1954{ 1953{
1955 char dbf_text[15]; 1954 char dbf_text[15];
@@ -1966,7 +1965,7 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1966 1965
1967} 1966}
1968 1967
1969static inline void 1968static void
1970qdio_handle_pci(struct qdio_irq *irq_ptr) 1969qdio_handle_pci(struct qdio_irq *irq_ptr)
1971{ 1970{
1972 int i; 1971 int i;
@@ -2002,7 +2001,7 @@ qdio_handle_pci(struct qdio_irq *irq_ptr)
2002 2001
2003static void qdio_establish_handle_irq(struct ccw_device*, int, int); 2002static void qdio_establish_handle_irq(struct ccw_device*, int, int);
2004 2003
2005static inline void 2004static void
2006qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, 2005qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm,
2007 int cstat, int dstat) 2006 int cstat, int dstat)
2008{ 2007{
@@ -2229,7 +2228,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
2229 return cc; 2228 return cc;
2230} 2229}
2231 2230
2232static inline void 2231static void
2233qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac, 2232qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac,
2234 unsigned long token) 2233 unsigned long token)
2235{ 2234{
@@ -2740,7 +2739,7 @@ qdio_free(struct ccw_device *cdev)
2740 return 0; 2739 return 0;
2741} 2740}
2742 2741
2743static inline void 2742static void
2744qdio_allocate_do_dbf(struct qdio_initialize *init_data) 2743qdio_allocate_do_dbf(struct qdio_initialize *init_data)
2745{ 2744{
2746 char dbf_text[20]; /* if a printf printed out more than 8 chars */ 2745 char dbf_text[20]; /* if a printf printed out more than 8 chars */
@@ -2773,7 +2772,7 @@ qdio_allocate_do_dbf(struct qdio_initialize *init_data)
2773 QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); 2772 QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
2774} 2773}
2775 2774
2776static inline void 2775static void
2777qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) 2776qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
2778{ 2777{
2779 irq_ptr->input_qs[i]->is_iqdio_q = iqfmt; 2778 irq_ptr->input_qs[i]->is_iqdio_q = iqfmt;
@@ -2792,7 +2791,7 @@ qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
2792 irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY; 2791 irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY;
2793} 2792}
2794 2793
2795static inline void 2794static void
2796qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, 2795qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
2797 int j, int iqfmt) 2796 int j, int iqfmt)
2798{ 2797{
@@ -2813,7 +2812,7 @@ qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i,
2813} 2812}
2814 2813
2815 2814
2816static inline void 2815static void
2817qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) 2816qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
2818{ 2817{
2819 int i; 2818 int i;
@@ -2839,7 +2838,7 @@ qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
2839 } 2838 }
2840} 2839}
2841 2840
2842static inline void 2841static void
2843qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) 2842qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
2844{ 2843{
2845 int i; 2844 int i;
@@ -2865,7 +2864,7 @@ qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
2865 } 2864 }
2866} 2865}
2867 2866
2868static inline int 2867static int
2869qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, 2868qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
2870 int dstat) 2869 int dstat)
2871{ 2870{
@@ -3014,7 +3013,7 @@ qdio_allocate(struct qdio_initialize *init_data)
3014 return 0; 3013 return 0;
3015} 3014}
3016 3015
3017int qdio_fill_irq(struct qdio_initialize *init_data) 3016static int qdio_fill_irq(struct qdio_initialize *init_data)
3018{ 3017{
3019 int i; 3018 int i;
3020 char dbf_text[15]; 3019 char dbf_text[15];
@@ -3367,7 +3366,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
3367} 3366}
3368 3367
3369/* buffers filled forwards again to make Rick happy */ 3368/* buffers filled forwards again to make Rick happy */
3370static inline void 3369static void
3371qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, 3370qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
3372 unsigned int count, struct qdio_buffer *buffers) 3371 unsigned int count, struct qdio_buffer *buffers)
3373{ 3372{
@@ -3386,7 +3385,7 @@ qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
3386 } 3385 }
3387} 3386}
3388 3387
3389static inline void 3388static void
3390qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, 3389qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
3391 unsigned int count, struct qdio_buffer *buffers) 3390 unsigned int count, struct qdio_buffer *buffers)
3392{ 3391{
@@ -3407,7 +3406,7 @@ qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
3407 } 3406 }
3408} 3407}
3409 3408
3410static inline void 3409static void
3411do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, 3410do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3412 unsigned int qidx, unsigned int count, 3411 unsigned int qidx, unsigned int count,
3413 struct qdio_buffer *buffers) 3412 struct qdio_buffer *buffers)
@@ -3443,7 +3442,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3443 qdio_mark_q(q); 3442 qdio_mark_q(q);
3444} 3443}
3445 3444
3446static inline void 3445static void
3447do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, 3446do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3448 unsigned int qidx, unsigned int count, 3447 unsigned int qidx, unsigned int count,
3449 struct qdio_buffer *buffers) 3448 struct qdio_buffer *buffers)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 81b5899f4010..c7d1355237b6 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -465,7 +465,7 @@ static int ap_device_probe(struct device *dev)
465 * Flush all requests from the request/pending queue of an AP device. 465 * Flush all requests from the request/pending queue of an AP device.
466 * @ap_dev: pointer to the AP device. 466 * @ap_dev: pointer to the AP device.
467 */ 467 */
468static inline void __ap_flush_queue(struct ap_device *ap_dev) 468static void __ap_flush_queue(struct ap_device *ap_dev)
469{ 469{
470 struct ap_message *ap_msg, *next; 470 struct ap_message *ap_msg, *next;
471 471
@@ -587,7 +587,7 @@ static struct bus_attribute *const ap_bus_attrs[] = {
587/** 587/**
588 * Pick one of the 16 ap domains. 588 * Pick one of the 16 ap domains.
589 */ 589 */
590static inline int ap_select_domain(void) 590static int ap_select_domain(void)
591{ 591{
592 int queue_depth, device_type, count, max_count, best_domain; 592 int queue_depth, device_type, count, max_count, best_domain;
593 int rc, i, j; 593 int rc, i, j;
@@ -825,7 +825,7 @@ static inline void ap_schedule_poll_timer(void)
825 * required, bit 2^1 is set if the poll timer needs to get armed 825 * required, bit 2^1 is set if the poll timer needs to get armed
826 * Returns 0 if the device is still present, -ENODEV if not. 826 * Returns 0 if the device is still present, -ENODEV if not.
827 */ 827 */
828static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) 828static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
829{ 829{
830 struct ap_queue_status status; 830 struct ap_queue_status status;
831 struct ap_message *ap_msg; 831 struct ap_message *ap_msg;
@@ -872,7 +872,7 @@ static inline int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
872 * required, bit 2^1 is set if the poll timer needs to get armed 872 * required, bit 2^1 is set if the poll timer needs to get armed
873 * Returns 0 if the device is still present, -ENODEV if not. 873 * Returns 0 if the device is still present, -ENODEV if not.
874 */ 874 */
875static inline int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) 875static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
876{ 876{
877 struct ap_queue_status status; 877 struct ap_queue_status status;
878 struct ap_message *ap_msg; 878 struct ap_message *ap_msg;
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 1edc10a7a6f2..b9e59bc9435a 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -791,7 +791,7 @@ static long trans_xcRB32(struct file *filp, unsigned int cmd,
791 return rc; 791 return rc;
792} 792}
793 793
794long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd, 794static long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
795 unsigned long arg) 795 unsigned long arg)
796{ 796{
797 if (cmd == ICARSAMODEXPO) 797 if (cmd == ICARSAMODEXPO)
@@ -833,8 +833,8 @@ static struct miscdevice zcrypt_misc_device = {
833 */ 833 */
834static struct proc_dir_entry *zcrypt_entry; 834static struct proc_dir_entry *zcrypt_entry;
835 835
836static inline int sprintcl(unsigned char *outaddr, unsigned char *addr, 836static int sprintcl(unsigned char *outaddr, unsigned char *addr,
837 unsigned int len) 837 unsigned int len)
838{ 838{
839 int hl, i; 839 int hl, i;
840 840
@@ -845,8 +845,8 @@ static inline int sprintcl(unsigned char *outaddr, unsigned char *addr,
845 return hl; 845 return hl;
846} 846}
847 847
848static inline int sprintrw(unsigned char *outaddr, unsigned char *addr, 848static int sprintrw(unsigned char *outaddr, unsigned char *addr,
849 unsigned int len) 849 unsigned int len)
850{ 850{
851 int hl, inl, c, cx; 851 int hl, inl, c, cx;
852 852
@@ -865,8 +865,8 @@ static inline int sprintrw(unsigned char *outaddr, unsigned char *addr,
865 return hl; 865 return hl;
866} 866}
867 867
868static inline int sprinthx(unsigned char *title, unsigned char *outaddr, 868static int sprinthx(unsigned char *title, unsigned char *outaddr,
869 unsigned char *addr, unsigned int len) 869 unsigned char *addr, unsigned int len)
870{ 870{
871 int hl, inl, r, rx; 871 int hl, inl, r, rx;
872 872
@@ -885,8 +885,8 @@ static inline int sprinthx(unsigned char *title, unsigned char *outaddr,
885 return hl; 885 return hl;
886} 886}
887 887
888static inline int sprinthx4(unsigned char *title, unsigned char *outaddr, 888static int sprinthx4(unsigned char *title, unsigned char *outaddr,
889 unsigned int *array, unsigned int len) 889 unsigned int *array, unsigned int len)
890{ 890{
891 int hl, r; 891 int hl, r;
892 892
@@ -943,7 +943,7 @@ static int zcrypt_status_read(char *resp_buff, char **start, off_t offset,
943 zcrypt_qdepth_mask(workarea); 943 zcrypt_qdepth_mask(workarea);
944 len += sprinthx("Waiting work element counts", 944 len += sprinthx("Waiting work element counts",
945 resp_buff+len, workarea, AP_DEVICES); 945 resp_buff+len, workarea, AP_DEVICES);
946 zcrypt_perdev_reqcnt((unsigned int *) workarea); 946 zcrypt_perdev_reqcnt((int *) workarea);
947 len += sprinthx4("Per-device successfully completed request counts", 947 len += sprinthx4("Per-device successfully completed request counts",
948 resp_buff+len,(unsigned int *) workarea, AP_DEVICES); 948 resp_buff+len,(unsigned int *) workarea, AP_DEVICES);
949 *eof = 1; 949 *eof = 1;
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 32e37014345c..818ffe05ac00 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -191,10 +191,10 @@ static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
191 * 191 *
192 * Returns 0 on success or -EFAULT. 192 * Returns 0 on success or -EFAULT.
193 */ 193 */
194static inline int convert_type84(struct zcrypt_device *zdev, 194static int convert_type84(struct zcrypt_device *zdev,
195 struct ap_message *reply, 195 struct ap_message *reply,
196 char __user *outputdata, 196 char __user *outputdata,
197 unsigned int outputdatalength) 197 unsigned int outputdatalength)
198{ 198{
199 struct type84_hdr *t84h = reply->message; 199 struct type84_hdr *t84h = reply->message;
200 char *data; 200 char *data;
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index b7153c1e15cd..252443b6bd1b 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -709,7 +709,8 @@ out_free:
709 * PCIXCC/CEX2C device to the request distributor 709 * PCIXCC/CEX2C device to the request distributor
710 * @xcRB: pointer to the send_cprb request buffer 710 * @xcRB: pointer to the send_cprb request buffer
711 */ 711 */
712long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, struct ica_xcRB *xcRB) 712static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
713 struct ica_xcRB *xcRB)
713{ 714{
714 struct ap_message ap_msg; 715 struct ap_message ap_msg;
715 struct response_type resp_type = { 716 struct response_type resp_type = {
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 95f4e105cb96..7809a79feec7 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -121,7 +121,7 @@ MODULE_LICENSE("GPL");
121#define DEBUG 121#define DEBUG
122#endif 122#endif
123 123
124 char debug_buffer[255]; 124static char debug_buffer[255];
125/** 125/**
126 * Debug Facility Stuff 126 * Debug Facility Stuff
127 */ 127 */
@@ -223,16 +223,14 @@ static void claw_timer ( struct chbk * p_ch );
223/* Functions */ 223/* Functions */
224static int add_claw_reads(struct net_device *dev, 224static int add_claw_reads(struct net_device *dev,
225 struct ccwbk* p_first, struct ccwbk* p_last); 225 struct ccwbk* p_first, struct ccwbk* p_last);
226static void inline ccw_check_return_code (struct ccw_device *cdev, 226static void ccw_check_return_code (struct ccw_device *cdev, int return_code);
227 int return_code); 227static void ccw_check_unit_check (struct chbk * p_ch, unsigned char sense );
228static void inline ccw_check_unit_check (struct chbk * p_ch,
229 unsigned char sense );
230static int find_link(struct net_device *dev, char *host_name, char *ws_name ); 228static int find_link(struct net_device *dev, char *host_name, char *ws_name );
231static int claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid); 229static int claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid);
232static int init_ccw_bk(struct net_device *dev); 230static int init_ccw_bk(struct net_device *dev);
233static void probe_error( struct ccwgroup_device *cgdev); 231static void probe_error( struct ccwgroup_device *cgdev);
234static struct net_device_stats *claw_stats(struct net_device *dev); 232static struct net_device_stats *claw_stats(struct net_device *dev);
235static int inline pages_to_order_of_mag(int num_of_pages); 233static int pages_to_order_of_mag(int num_of_pages);
236static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr); 234static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
237#ifdef DEBUG 235#ifdef DEBUG
238static void dumpit (char *buf, int len); 236static void dumpit (char *buf, int len);
@@ -1310,7 +1308,7 @@ claw_timer ( struct chbk * p_ch )
1310* of magnitude get_free_pages() has an upper order of 9 * 1308* of magnitude get_free_pages() has an upper order of 9 *
1311*--------------------------------------------------------------------*/ 1309*--------------------------------------------------------------------*/
1312 1310
1313static int inline 1311static int
1314pages_to_order_of_mag(int num_of_pages) 1312pages_to_order_of_mag(int num_of_pages)
1315{ 1313{
1316 int order_of_mag=1; /* assume 2 pages */ 1314 int order_of_mag=1; /* assume 2 pages */
@@ -1482,7 +1480,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
1482 * * 1480 * *
1483 *-------------------------------------------------------------------*/ 1481 *-------------------------------------------------------------------*/
1484 1482
1485static void inline 1483static void
1486ccw_check_return_code(struct ccw_device *cdev, int return_code) 1484ccw_check_return_code(struct ccw_device *cdev, int return_code)
1487{ 1485{
1488#ifdef FUNCTRACE 1486#ifdef FUNCTRACE
@@ -1529,7 +1527,7 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
1529* ccw_check_unit_check * 1527* ccw_check_unit_check *
1530*--------------------------------------------------------------------*/ 1528*--------------------------------------------------------------------*/
1531 1529
1532static void inline 1530static void
1533ccw_check_unit_check(struct chbk * p_ch, unsigned char sense ) 1531ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
1534{ 1532{
1535 struct net_device *dev = p_ch->ndev; 1533 struct net_device *dev = p_ch->ndev;
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 03cc263fe0da..5a84fbbc6611 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -369,7 +369,7 @@ ctc_dump_skb(struct sk_buff *skb, int offset)
369 * @param ch The channel where this skb has been received. 369 * @param ch The channel where this skb has been received.
370 * @param pskb The received skb. 370 * @param pskb The received skb.
371 */ 371 */
372static __inline__ void 372static void
373ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb) 373ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
374{ 374{
375 struct net_device *dev = ch->netdev; 375 struct net_device *dev = ch->netdev;
@@ -512,7 +512,7 @@ ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
512 * @param ch The channel, the error belongs to. 512 * @param ch The channel, the error belongs to.
513 * @param return_code The error code to inspect. 513 * @param return_code The error code to inspect.
514 */ 514 */
515static void inline 515static void
516ccw_check_return_code(struct channel *ch, int return_code, char *msg) 516ccw_check_return_code(struct channel *ch, int return_code, char *msg)
517{ 517{
518 DBF_TEXT(trace, 5, __FUNCTION__); 518 DBF_TEXT(trace, 5, __FUNCTION__);
@@ -547,7 +547,7 @@ ccw_check_return_code(struct channel *ch, int return_code, char *msg)
547 * @param ch The channel, the sense code belongs to. 547 * @param ch The channel, the sense code belongs to.
548 * @param sense The sense code to inspect. 548 * @param sense The sense code to inspect.
549 */ 549 */
550static void inline 550static void
551ccw_unit_check(struct channel *ch, unsigned char sense) 551ccw_unit_check(struct channel *ch, unsigned char sense)
552{ 552{
553 DBF_TEXT(trace, 5, __FUNCTION__); 553 DBF_TEXT(trace, 5, __FUNCTION__);
@@ -603,7 +603,7 @@ ctc_purge_skb_queue(struct sk_buff_head *q)
603 } 603 }
604} 604}
605 605
606static __inline__ int 606static int
607ctc_checkalloc_buffer(struct channel *ch, int warn) 607ctc_checkalloc_buffer(struct channel *ch, int warn)
608{ 608{
609 DBF_TEXT(trace, 5, __FUNCTION__); 609 DBF_TEXT(trace, 5, __FUNCTION__);
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index e965f03a7291..76728ae4b843 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -57,7 +57,7 @@ static struct ccw_device_id cu3088_ids[] = {
57 57
58static struct ccw_driver cu3088_driver; 58static struct ccw_driver cu3088_driver;
59 59
60struct device *cu3088_root_dev; 60static struct device *cu3088_root_dev;
61 61
62static ssize_t 62static ssize_t
63group_write(struct device_driver *drv, const char *buf, size_t count) 63group_write(struct device_driver *drv, const char *buf, size_t count)
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index e5665b6743a1..b97dd15bdb9a 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -828,7 +828,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd)
828/** 828/**
829 * Emit buffer of a lan comand. 829 * Emit buffer of a lan comand.
830 */ 830 */
831void 831static void
832lcs_lancmd_timeout(unsigned long data) 832lcs_lancmd_timeout(unsigned long data)
833{ 833{
834 struct lcs_reply *reply, *list_reply, *r; 834 struct lcs_reply *reply, *list_reply, *r;
@@ -1360,7 +1360,7 @@ lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
1360 return 0; 1360 return 0;
1361} 1361}
1362 1362
1363void 1363static void
1364lcs_schedule_recovery(struct lcs_card *card) 1364lcs_schedule_recovery(struct lcs_card *card)
1365{ 1365{
1366 LCS_DBF_TEXT(2, trace, "startrec"); 1366 LCS_DBF_TEXT(2, trace, "startrec");
@@ -1990,7 +1990,7 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char
1990 1990
1991} 1991}
1992 1992
1993DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store); 1993static DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store);
1994 1994
1995static ssize_t 1995static ssize_t
1996lcs_dev_recover_store(struct device *dev, struct device_attribute *attr, 1996lcs_dev_recover_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index d7d1cc0a5c8e..3346088f47e0 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -2053,7 +2053,7 @@ out_free_ndev:
2053 return ret; 2053 return ret;
2054} 2054}
2055 2055
2056DRIVER_ATTR(connection, 0200, NULL, conn_write); 2056static DRIVER_ATTR(connection, 0200, NULL, conn_write);
2057 2057
2058static ssize_t 2058static ssize_t
2059remove_write (struct device_driver *drv, const char *buf, size_t count) 2059remove_write (struct device_driver *drv, const char *buf, size_t count)
@@ -2112,7 +2112,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
2112 return -EINVAL; 2112 return -EINVAL;
2113} 2113}
2114 2114
2115DRIVER_ATTR(remove, 0200, NULL, remove_write); 2115static DRIVER_ATTR(remove, 0200, NULL, remove_write);
2116 2116
2117static void 2117static void
2118netiucv_banner(void) 2118netiucv_banner(void)
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 6bb558a9a032..7c735e1fe063 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -49,7 +49,7 @@ qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
49 return buffers_needed; 49 return buffers_needed;
50} 50}
51 51
52static inline void 52static void
53qeth_eddp_free_context(struct qeth_eddp_context *ctx) 53qeth_eddp_free_context(struct qeth_eddp_context *ctx)
54{ 54{
55 int i; 55 int i;
@@ -91,7 +91,7 @@ qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
91 } 91 }
92} 92}
93 93
94static inline int 94static int
95qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf, 95qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
96 struct qeth_eddp_context *ctx) 96 struct qeth_eddp_context *ctx)
97{ 97{
@@ -196,7 +196,7 @@ out:
196 return flush_cnt; 196 return flush_cnt;
197} 197}
198 198
199static inline void 199static void
200qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, 200qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
201 struct qeth_eddp_data *eddp, int data_len) 201 struct qeth_eddp_data *eddp, int data_len)
202{ 202{
@@ -256,7 +256,7 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
256 ctx->offset += eddp->thl; 256 ctx->offset += eddp->thl;
257} 257}
258 258
259static inline void 259static void
260qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len, 260qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
261 __wsum *hcsum) 261 __wsum *hcsum)
262{ 262{
@@ -302,7 +302,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
302 } 302 }
303} 303}
304 304
305static inline void 305static void
306qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx, 306qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
307 struct qeth_eddp_data *eddp, int data_len, 307 struct qeth_eddp_data *eddp, int data_len,
308 __wsum hcsum) 308 __wsum hcsum)
@@ -349,7 +349,7 @@ qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
349 ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum); 349 ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
350} 350}
351 351
352static inline __wsum 352static __wsum
353qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len) 353qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
354{ 354{
355 __wsum phcsum; /* pseudo header checksum */ 355 __wsum phcsum; /* pseudo header checksum */
@@ -363,7 +363,7 @@ qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
363 return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum); 363 return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
364} 364}
365 365
366static inline __wsum 366static __wsum
367qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len) 367qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
368{ 368{
369 __be32 proto; 369 __be32 proto;
@@ -381,7 +381,7 @@ qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
381 return phcsum; 381 return phcsum;
382} 382}
383 383
384static inline struct qeth_eddp_data * 384static struct qeth_eddp_data *
385qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl) 385qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
386{ 386{
387 struct qeth_eddp_data *eddp; 387 struct qeth_eddp_data *eddp;
@@ -399,7 +399,7 @@ qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
399 return eddp; 399 return eddp;
400} 400}
401 401
402static inline void 402static void
403__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 403__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
404 struct qeth_eddp_data *eddp) 404 struct qeth_eddp_data *eddp)
405{ 405{
@@ -464,7 +464,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
464 } 464 }
465} 465}
466 466
467static inline int 467static int
468qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 468qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
469 struct sk_buff *skb, struct qeth_hdr *qhdr) 469 struct sk_buff *skb, struct qeth_hdr *qhdr)
470{ 470{
@@ -505,7 +505,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
505 return 0; 505 return 0;
506} 506}
507 507
508static inline void 508static void
509qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, 509qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
510 int hdr_len) 510 int hdr_len)
511{ 511{
@@ -529,7 +529,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
529 (skb_shinfo(skb)->gso_segs + 1); 529 (skb_shinfo(skb)->gso_segs + 1);
530} 530}
531 531
532static inline struct qeth_eddp_context * 532static struct qeth_eddp_context *
533qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb, 533qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
534 int hdr_len) 534 int hdr_len)
535{ 535{
@@ -581,7 +581,7 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
581 return ctx; 581 return ctx;
582} 582}
583 583
584static inline struct qeth_eddp_context * 584static struct qeth_eddp_context *
585qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb, 585qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
586 struct qeth_hdr *qhdr) 586 struct qeth_hdr *qhdr)
587{ 587{
@@ -625,5 +625,3 @@ qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
625 } 625 }
626 return NULL; 626 return NULL;
627} 627}
628
629
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index d2efa5ff125d..2257e45594b3 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -651,7 +651,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
651 return 0; 651 return 0;
652} 652}
653 653
654static inline int 654static int
655__qeth_address_exists_in_list(struct list_head *list, struct qeth_ipaddr *addr, 655__qeth_address_exists_in_list(struct list_head *list, struct qeth_ipaddr *addr,
656 int same_type) 656 int same_type)
657{ 657{
@@ -795,7 +795,7 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
795 return rc; 795 return rc;
796} 796}
797 797
798static inline void 798static void
799__qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags) 799__qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
800{ 800{
801 struct qeth_ipaddr *addr, *tmp; 801 struct qeth_ipaddr *addr, *tmp;
@@ -882,7 +882,7 @@ static void qeth_layer2_add_multicast(struct qeth_card *);
882static void qeth_add_multicast_ipv6(struct qeth_card *); 882static void qeth_add_multicast_ipv6(struct qeth_card *);
883#endif 883#endif
884 884
885static inline int 885static int
886qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread) 886qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread)
887{ 887{
888 unsigned long flags; 888 unsigned long flags;
@@ -920,7 +920,7 @@ qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
920 wake_up(&card->wait_q); 920 wake_up(&card->wait_q);
921} 921}
922 922
923static inline int 923static int
924__qeth_do_run_thread(struct qeth_card *card, unsigned long thread) 924__qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
925{ 925{
926 unsigned long flags; 926 unsigned long flags;
@@ -1764,9 +1764,9 @@ out:
1764 qeth_release_buffer(channel,iob); 1764 qeth_release_buffer(channel,iob);
1765} 1765}
1766 1766
1767static inline void 1767static void
1768qeth_prepare_control_data(struct qeth_card *card, int len, 1768qeth_prepare_control_data(struct qeth_card *card, int len,
1769struct qeth_cmd_buffer *iob) 1769 struct qeth_cmd_buffer *iob)
1770{ 1770{
1771 qeth_setup_ccw(&card->write,iob->data,len); 1771 qeth_setup_ccw(&card->write,iob->data,len);
1772 iob->callback = qeth_release_buffer; 1772 iob->callback = qeth_release_buffer;
@@ -2160,7 +2160,7 @@ qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2160 return 0; 2160 return 0;
2161} 2161}
2162 2162
2163static inline struct sk_buff * 2163static struct sk_buff *
2164qeth_get_skb(unsigned int length, struct qeth_hdr *hdr) 2164qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
2165{ 2165{
2166 struct sk_buff* skb; 2166 struct sk_buff* skb;
@@ -2179,7 +2179,7 @@ qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
2179 return skb; 2179 return skb;
2180} 2180}
2181 2181
2182static inline struct sk_buff * 2182static struct sk_buff *
2183qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer, 2183qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2184 struct qdio_buffer_element **__element, int *__offset, 2184 struct qdio_buffer_element **__element, int *__offset,
2185 struct qeth_hdr **hdr) 2185 struct qeth_hdr **hdr)
@@ -2264,7 +2264,7 @@ no_mem:
2264 return NULL; 2264 return NULL;
2265} 2265}
2266 2266
2267static inline __be16 2267static __be16
2268qeth_type_trans(struct sk_buff *skb, struct net_device *dev) 2268qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
2269{ 2269{
2270 struct qeth_card *card; 2270 struct qeth_card *card;
@@ -2297,7 +2297,7 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
2297 return htons(ETH_P_802_2); 2297 return htons(ETH_P_802_2);
2298} 2298}
2299 2299
2300static inline void 2300static void
2301qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb, 2301qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
2302 struct qeth_hdr *hdr) 2302 struct qeth_hdr *hdr)
2303{ 2303{
@@ -2351,7 +2351,7 @@ qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
2351 fake_llc->ethertype = ETH_P_IP; 2351 fake_llc->ethertype = ETH_P_IP;
2352} 2352}
2353 2353
2354static inline void 2354static void
2355qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb, 2355qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
2356 struct qeth_hdr *hdr) 2356 struct qeth_hdr *hdr)
2357{ 2357{
@@ -2420,7 +2420,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
2420 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; 2420 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
2421} 2421}
2422 2422
2423static inline __u16 2423static __u16
2424qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, 2424qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
2425 struct qeth_hdr *hdr) 2425 struct qeth_hdr *hdr)
2426{ 2426{
@@ -2476,7 +2476,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
2476 return vlan_id; 2476 return vlan_id;
2477} 2477}
2478 2478
2479static inline void 2479static void
2480qeth_process_inbound_buffer(struct qeth_card *card, 2480qeth_process_inbound_buffer(struct qeth_card *card,
2481 struct qeth_qdio_buffer *buf, int index) 2481 struct qeth_qdio_buffer *buf, int index)
2482{ 2482{
@@ -2528,7 +2528,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
2528 } 2528 }
2529} 2529}
2530 2530
2531static inline struct qeth_buffer_pool_entry * 2531static struct qeth_buffer_pool_entry *
2532qeth_get_buffer_pool_entry(struct qeth_card *card) 2532qeth_get_buffer_pool_entry(struct qeth_card *card)
2533{ 2533{
2534 struct qeth_buffer_pool_entry *entry; 2534 struct qeth_buffer_pool_entry *entry;
@@ -2543,7 +2543,7 @@ qeth_get_buffer_pool_entry(struct qeth_card *card)
2543 return NULL; 2543 return NULL;
2544} 2544}
2545 2545
2546static inline void 2546static void
2547qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf) 2547qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
2548{ 2548{
2549 struct qeth_buffer_pool_entry *pool_entry; 2549 struct qeth_buffer_pool_entry *pool_entry;
@@ -2570,7 +2570,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
2570 buf->state = QETH_QDIO_BUF_EMPTY; 2570 buf->state = QETH_QDIO_BUF_EMPTY;
2571} 2571}
2572 2572
2573static inline void 2573static void
2574qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, 2574qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
2575 struct qeth_qdio_out_buffer *buf) 2575 struct qeth_qdio_out_buffer *buf)
2576{ 2576{
@@ -2595,7 +2595,7 @@ qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
2595 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); 2595 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
2596} 2596}
2597 2597
2598static inline void 2598static void
2599qeth_queue_input_buffer(struct qeth_card *card, int index) 2599qeth_queue_input_buffer(struct qeth_card *card, int index)
2600{ 2600{
2601 struct qeth_qdio_q *queue = card->qdio.in_q; 2601 struct qeth_qdio_q *queue = card->qdio.in_q;
@@ -2699,7 +2699,7 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
2699 card->perf_stats.inbound_start_time; 2699 card->perf_stats.inbound_start_time;
2700} 2700}
2701 2701
2702static inline int 2702static int
2703qeth_handle_send_error(struct qeth_card *card, 2703qeth_handle_send_error(struct qeth_card *card,
2704 struct qeth_qdio_out_buffer *buffer, 2704 struct qeth_qdio_out_buffer *buffer,
2705 unsigned int qdio_err, unsigned int siga_err) 2705 unsigned int qdio_err, unsigned int siga_err)
@@ -2821,7 +2821,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
2821 * Switched to packing state if the number of used buffers on a queue 2821 * Switched to packing state if the number of used buffers on a queue
2822 * reaches a certain limit. 2822 * reaches a certain limit.
2823 */ 2823 */
2824static inline void 2824static void
2825qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue) 2825qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
2826{ 2826{
2827 if (!queue->do_pack) { 2827 if (!queue->do_pack) {
@@ -2842,7 +2842,7 @@ qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
2842 * In that case 1 is returned to inform the caller. If no buffer 2842 * In that case 1 is returned to inform the caller. If no buffer
2843 * has to be flushed, zero is returned. 2843 * has to be flushed, zero is returned.
2844 */ 2844 */
2845static inline int 2845static int
2846qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue) 2846qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
2847{ 2847{
2848 struct qeth_qdio_out_buffer *buffer; 2848 struct qeth_qdio_out_buffer *buffer;
@@ -2877,7 +2877,7 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
2877 * Checks if there is a packing buffer and prepares it to be flushed. 2877 * Checks if there is a packing buffer and prepares it to be flushed.
2878 * In that case returns 1, otherwise zero. 2878 * In that case returns 1, otherwise zero.
2879 */ 2879 */
2880static inline int 2880static int
2881qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue) 2881qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
2882{ 2882{
2883 struct qeth_qdio_out_buffer *buffer; 2883 struct qeth_qdio_out_buffer *buffer;
@@ -2894,7 +2894,7 @@ qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
2894 return 0; 2894 return 0;
2895} 2895}
2896 2896
2897static inline void 2897static void
2898qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) 2898qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
2899{ 2899{
2900 int index; 2900 int index;
@@ -3594,7 +3594,7 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
3594 } 3594 }
3595} 3595}
3596 3596
3597static inline int 3597static int
3598qeth_send_packet(struct qeth_card *, struct sk_buff *); 3598qeth_send_packet(struct qeth_card *, struct sk_buff *);
3599 3599
3600static int 3600static int
@@ -3759,7 +3759,7 @@ qeth_stop(struct net_device *dev)
3759 return 0; 3759 return 0;
3760} 3760}
3761 3761
3762static inline int 3762static int
3763qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb) 3763qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
3764{ 3764{
3765 int cast_type = RTN_UNSPEC; 3765 int cast_type = RTN_UNSPEC;
@@ -3806,7 +3806,7 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
3806 return cast_type; 3806 return cast_type;
3807} 3807}
3808 3808
3809static inline int 3809static int
3810qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, 3810qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
3811 int ipv, int cast_type) 3811 int ipv, int cast_type)
3812{ 3812{
@@ -3853,7 +3853,7 @@ qeth_get_ip_version(struct sk_buff *skb)
3853 } 3853 }
3854} 3854}
3855 3855
3856static inline struct qeth_hdr * 3856static struct qeth_hdr *
3857__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv) 3857__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
3858{ 3858{
3859#ifdef CONFIG_QETH_VLAN 3859#ifdef CONFIG_QETH_VLAN
@@ -3882,14 +3882,14 @@ __qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
3882 qeth_push_skb(card, skb, sizeof(struct qeth_hdr))); 3882 qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
3883} 3883}
3884 3884
3885static inline void 3885static void
3886__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb) 3886__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
3887{ 3887{
3888 if (orig_skb != new_skb) 3888 if (orig_skb != new_skb)
3889 dev_kfree_skb_any(new_skb); 3889 dev_kfree_skb_any(new_skb);
3890} 3890}
3891 3891
3892static inline struct sk_buff * 3892static struct sk_buff *
3893qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, 3893qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
3894 struct qeth_hdr **hdr, int ipv) 3894 struct qeth_hdr **hdr, int ipv)
3895{ 3895{
@@ -3940,7 +3940,7 @@ qeth_get_qeth_hdr_flags6(int cast_type)
3940 return ct | QETH_CAST_UNICAST; 3940 return ct | QETH_CAST_UNICAST;
3941} 3941}
3942 3942
3943static inline void 3943static void
3944qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr, 3944qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
3945 struct sk_buff *skb) 3945 struct sk_buff *skb)
3946{ 3946{
@@ -3977,7 +3977,7 @@ qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
3977 } 3977 }
3978} 3978}
3979 3979
3980static inline void 3980static void
3981qeth_layer2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, 3981qeth_layer2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
3982 struct sk_buff *skb, int cast_type) 3982 struct sk_buff *skb, int cast_type)
3983{ 3983{
@@ -4068,7 +4068,7 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
4068 } 4068 }
4069} 4069}
4070 4070
4071static inline void 4071static void
4072__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, 4072__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
4073 int is_tso, int *next_element_to_fill) 4073 int is_tso, int *next_element_to_fill)
4074{ 4074{
@@ -4112,7 +4112,7 @@ __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
4112 *next_element_to_fill = element; 4112 *next_element_to_fill = element;
4113} 4113}
4114 4114
4115static inline int 4115static int
4116qeth_fill_buffer(struct qeth_qdio_out_q *queue, 4116qeth_fill_buffer(struct qeth_qdio_out_q *queue,
4117 struct qeth_qdio_out_buffer *buf, 4117 struct qeth_qdio_out_buffer *buf,
4118 struct sk_buff *skb) 4118 struct sk_buff *skb)
@@ -4171,7 +4171,7 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue,
4171 return flush_cnt; 4171 return flush_cnt;
4172} 4172}
4173 4173
4174static inline int 4174static int
4175qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue, 4175qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4176 struct sk_buff *skb, struct qeth_hdr *hdr, 4176 struct sk_buff *skb, struct qeth_hdr *hdr,
4177 int elements_needed, 4177 int elements_needed,
@@ -4222,7 +4222,7 @@ out:
4222 return -EBUSY; 4222 return -EBUSY;
4223} 4223}
4224 4224
4225static inline int 4225static int
4226qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, 4226qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4227 struct sk_buff *skb, struct qeth_hdr *hdr, 4227 struct sk_buff *skb, struct qeth_hdr *hdr,
4228 int elements_needed, struct qeth_eddp_context *ctx) 4228 int elements_needed, struct qeth_eddp_context *ctx)
@@ -4328,7 +4328,7 @@ out:
4328 return rc; 4328 return rc;
4329} 4329}
4330 4330
4331static inline int 4331static int
4332qeth_get_elements_no(struct qeth_card *card, void *hdr, 4332qeth_get_elements_no(struct qeth_card *card, void *hdr,
4333 struct sk_buff *skb, int elems) 4333 struct sk_buff *skb, int elems)
4334{ 4334{
@@ -4349,7 +4349,7 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
4349} 4349}
4350 4350
4351 4351
4352static inline int 4352static int
4353qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) 4353qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4354{ 4354{
4355 int ipv = 0; 4355 int ipv = 0;
@@ -4536,7 +4536,7 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
4536} 4536}
4537 4537
4538 4538
4539static inline const char * 4539static const char *
4540qeth_arp_get_error_cause(int *rc) 4540qeth_arp_get_error_cause(int *rc)
4541{ 4541{
4542 switch (*rc) { 4542 switch (*rc) {
@@ -4597,7 +4597,7 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
4597 return rc; 4597 return rc;
4598} 4598}
4599 4599
4600static inline void 4600static void
4601qeth_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo, 4601qeth_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
4602 struct qeth_arp_query_data *qdata, 4602 struct qeth_arp_query_data *qdata,
4603 int entry_size, int uentry_size) 4603 int entry_size, int uentry_size)
@@ -5214,7 +5214,7 @@ qeth_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
5214 spin_unlock_irqrestore(&card->vlanlock, flags); 5214 spin_unlock_irqrestore(&card->vlanlock, flags);
5215} 5215}
5216 5216
5217static inline void 5217static void
5218qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf, 5218qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf,
5219 unsigned short vid) 5219 unsigned short vid)
5220{ 5220{
@@ -5625,7 +5625,7 @@ qeth_delete_mc_addresses(struct qeth_card *card)
5625 spin_unlock_irqrestore(&card->ip_lock, flags); 5625 spin_unlock_irqrestore(&card->ip_lock, flags);
5626} 5626}
5627 5627
5628static inline void 5628static void
5629qeth_add_mc(struct qeth_card *card, struct in_device *in4_dev) 5629qeth_add_mc(struct qeth_card *card, struct in_device *in4_dev)
5630{ 5630{
5631 struct qeth_ipaddr *ipm; 5631 struct qeth_ipaddr *ipm;
@@ -5711,7 +5711,7 @@ qeth_layer2_add_multicast(struct qeth_card *card)
5711} 5711}
5712 5712
5713#ifdef CONFIG_QETH_IPV6 5713#ifdef CONFIG_QETH_IPV6
5714static inline void 5714static void
5715qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) 5715qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
5716{ 5716{
5717 struct qeth_ipaddr *ipm; 5717 struct qeth_ipaddr *ipm;
@@ -6022,7 +6022,7 @@ qeth_send_setdelmc(struct qeth_card *card, struct qeth_ipaddr *addr, int ipacmd)
6022 6022
6023 return rc; 6023 return rc;
6024} 6024}
6025static inline void 6025static void
6026qeth_fill_netmask(u8 *netmask, unsigned int len) 6026qeth_fill_netmask(u8 *netmask, unsigned int len)
6027{ 6027{
6028 int i,j; 6028 int i,j;
@@ -6626,7 +6626,7 @@ qeth_send_setadp_mode(struct qeth_card *card, __u32 command, __u32 mode)
6626 return rc; 6626 return rc;
6627} 6627}
6628 6628
6629static inline int 6629static int
6630qeth_setadapter_hstr(struct qeth_card *card) 6630qeth_setadapter_hstr(struct qeth_card *card)
6631{ 6631{
6632 int rc; 6632 int rc;
@@ -6889,7 +6889,7 @@ qeth_send_simple_setassparms(struct qeth_card *card,
6889 return rc; 6889 return rc;
6890} 6890}
6891 6891
6892static inline int 6892static int
6893qeth_start_ipa_arp_processing(struct qeth_card *card) 6893qeth_start_ipa_arp_processing(struct qeth_card *card)
6894{ 6894{
6895 int rc; 6895 int rc;
@@ -7529,7 +7529,7 @@ qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
7529 wake_up(&card->wait_q); 7529 wake_up(&card->wait_q);
7530} 7530}
7531 7531
7532static inline int 7532static int
7533qeth_threads_running(struct qeth_card *card, unsigned long threads) 7533qeth_threads_running(struct qeth_card *card, unsigned long threads)
7534{ 7534{
7535 unsigned long flags; 7535 unsigned long flags;
@@ -8118,7 +8118,7 @@ qeth_del_ipato_entry(struct qeth_card *card, enum qeth_prot_versions proto,
8118 spin_unlock_irqrestore(&card->ip_lock, flags); 8118 spin_unlock_irqrestore(&card->ip_lock, flags);
8119} 8119}
8120 8120
8121static inline void 8121static void
8122qeth_convert_addr_to_bits(u8 *addr, u8 *bits, int len) 8122qeth_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
8123{ 8123{
8124 int i, j; 8124 int i, j;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 5836737ac58f..d518419cd0c6 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -328,7 +328,7 @@ qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const c
328static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, 328static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
329 qeth_dev_bufcnt_store); 329 qeth_dev_bufcnt_store);
330 330
331static inline ssize_t 331static ssize_t
332qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route, 332qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route,
333 char *buf) 333 char *buf)
334{ 334{
@@ -368,7 +368,7 @@ qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *bu
368 return qeth_dev_route_show(card, &card->options.route4, buf); 368 return qeth_dev_route_show(card, &card->options.route4, buf);
369} 369}
370 370
371static inline ssize_t 371static ssize_t
372qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route, 372qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
373 enum qeth_prot_versions prot, const char *buf, size_t count) 373 enum qeth_prot_versions prot, const char *buf, size_t count)
374{ 374{
@@ -998,7 +998,7 @@ struct device_attribute dev_attr_##_id = { \
998 .store = _store, \ 998 .store = _store, \
999}; 999};
1000 1000
1001int 1001static int
1002qeth_check_layer2(struct qeth_card *card) 1002qeth_check_layer2(struct qeth_card *card)
1003{ 1003{
1004 if (card->options.layer2) 1004 if (card->options.layer2)
@@ -1100,7 +1100,7 @@ static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
1100 qeth_dev_ipato_invert4_show, 1100 qeth_dev_ipato_invert4_show,
1101 qeth_dev_ipato_invert4_store); 1101 qeth_dev_ipato_invert4_store);
1102 1102
1103static inline ssize_t 1103static ssize_t
1104qeth_dev_ipato_add_show(char *buf, struct qeth_card *card, 1104qeth_dev_ipato_add_show(char *buf, struct qeth_card *card,
1105 enum qeth_prot_versions proto) 1105 enum qeth_prot_versions proto)
1106{ 1106{
@@ -1146,7 +1146,7 @@ qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char
1146 return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4); 1146 return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
1147} 1147}
1148 1148
1149static inline int 1149static int
1150qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto, 1150qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
1151 u8 *addr, int *mask_bits) 1151 u8 *addr, int *mask_bits)
1152{ 1152{
@@ -1178,7 +1178,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
1178 return 0; 1178 return 0;
1179} 1179}
1180 1180
1181static inline ssize_t 1181static ssize_t
1182qeth_dev_ipato_add_store(const char *buf, size_t count, 1182qeth_dev_ipato_add_store(const char *buf, size_t count,
1183 struct qeth_card *card, enum qeth_prot_versions proto) 1183 struct qeth_card *card, enum qeth_prot_versions proto)
1184{ 1184{
@@ -1223,7 +1223,7 @@ static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
1223 qeth_dev_ipato_add4_show, 1223 qeth_dev_ipato_add4_show,
1224 qeth_dev_ipato_add4_store); 1224 qeth_dev_ipato_add4_store);
1225 1225
1226static inline ssize_t 1226static ssize_t
1227qeth_dev_ipato_del_store(const char *buf, size_t count, 1227qeth_dev_ipato_del_store(const char *buf, size_t count,
1228 struct qeth_card *card, enum qeth_prot_versions proto) 1228 struct qeth_card *card, enum qeth_prot_versions proto)
1229{ 1229{
@@ -1361,7 +1361,7 @@ static struct attribute_group qeth_device_ipato_group = {
1361 .attrs = (struct attribute **)qeth_ipato_device_attrs, 1361 .attrs = (struct attribute **)qeth_ipato_device_attrs,
1362}; 1362};
1363 1363
1364static inline ssize_t 1364static ssize_t
1365qeth_dev_vipa_add_show(char *buf, struct qeth_card *card, 1365qeth_dev_vipa_add_show(char *buf, struct qeth_card *card,
1366 enum qeth_prot_versions proto) 1366 enum qeth_prot_versions proto)
1367{ 1367{
@@ -1407,7 +1407,7 @@ qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char
1407 return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV4); 1407 return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
1408} 1408}
1409 1409
1410static inline int 1410static int
1411qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto, 1411qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
1412 u8 *addr) 1412 u8 *addr)
1413{ 1413{
@@ -1418,7 +1418,7 @@ qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
1418 return 0; 1418 return 0;
1419} 1419}
1420 1420
1421static inline ssize_t 1421static ssize_t
1422qeth_dev_vipa_add_store(const char *buf, size_t count, 1422qeth_dev_vipa_add_store(const char *buf, size_t count,
1423 struct qeth_card *card, enum qeth_prot_versions proto) 1423 struct qeth_card *card, enum qeth_prot_versions proto)
1424{ 1424{
@@ -1451,7 +1451,7 @@ static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
1451 qeth_dev_vipa_add4_show, 1451 qeth_dev_vipa_add4_show,
1452 qeth_dev_vipa_add4_store); 1452 qeth_dev_vipa_add4_store);
1453 1453
1454static inline ssize_t 1454static ssize_t
1455qeth_dev_vipa_del_store(const char *buf, size_t count, 1455qeth_dev_vipa_del_store(const char *buf, size_t count,
1456 struct qeth_card *card, enum qeth_prot_versions proto) 1456 struct qeth_card *card, enum qeth_prot_versions proto)
1457{ 1457{
@@ -1542,7 +1542,7 @@ static struct attribute_group qeth_device_vipa_group = {
1542 .attrs = (struct attribute **)qeth_vipa_device_attrs, 1542 .attrs = (struct attribute **)qeth_vipa_device_attrs,
1543}; 1543};
1544 1544
1545static inline ssize_t 1545static ssize_t
1546qeth_dev_rxip_add_show(char *buf, struct qeth_card *card, 1546qeth_dev_rxip_add_show(char *buf, struct qeth_card *card,
1547 enum qeth_prot_versions proto) 1547 enum qeth_prot_versions proto)
1548{ 1548{
@@ -1588,7 +1588,7 @@ qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char
1588 return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV4); 1588 return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
1589} 1589}
1590 1590
1591static inline int 1591static int
1592qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto, 1592qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
1593 u8 *addr) 1593 u8 *addr)
1594{ 1594{
@@ -1599,7 +1599,7 @@ qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
1599 return 0; 1599 return 0;
1600} 1600}
1601 1601
1602static inline ssize_t 1602static ssize_t
1603qeth_dev_rxip_add_store(const char *buf, size_t count, 1603qeth_dev_rxip_add_store(const char *buf, size_t count,
1604 struct qeth_card *card, enum qeth_prot_versions proto) 1604 struct qeth_card *card, enum qeth_prot_versions proto)
1605{ 1605{
@@ -1632,7 +1632,7 @@ static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1632 qeth_dev_rxip_add4_show, 1632 qeth_dev_rxip_add4_show,
1633 qeth_dev_rxip_add4_store); 1633 qeth_dev_rxip_add4_store);
1634 1634
1635static inline ssize_t 1635static ssize_t
1636qeth_dev_rxip_del_store(const char *buf, size_t count, 1636qeth_dev_rxip_del_store(const char *buf, size_t count,
1637 struct qeth_card *card, enum qeth_prot_versions proto) 1637 struct qeth_card *card, enum qeth_prot_versions proto)
1638{ 1638{
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index e088b5e28711..806bb1a921eb 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -13,22 +13,18 @@
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/workqueue.h> 14#include <linux/workqueue.h>
15#include <linux/time.h> 15#include <linux/time.h>
16#include <linux/device.h>
16#include <linux/kthread.h> 17#include <linux/kthread.h>
17 18#include <asm/etr.h>
18#include <asm/lowcore.h> 19#include <asm/lowcore.h>
19 20#include <asm/cio.h>
21#include "cio/cio.h"
22#include "cio/chsc.h"
23#include "cio/css.h"
20#include "s390mach.h" 24#include "s390mach.h"
21 25
22static struct semaphore m_sem; 26static struct semaphore m_sem;
23 27
24extern int css_process_crw(int, int);
25extern int chsc_process_crw(void);
26extern int chp_process_crw(int, int);
27extern void css_reiterate_subchannels(void);
28
29extern struct workqueue_struct *slow_path_wq;
30extern struct work_struct slow_path_work;
31
32static NORET_TYPE void 28static NORET_TYPE void
33s390_handle_damage(char *msg) 29s390_handle_damage(char *msg)
34{ 30{
@@ -470,6 +466,19 @@ s390_do_machine_check(struct pt_regs *regs)
470 s390_handle_damage("unable to revalidate registers."); 466 s390_handle_damage("unable to revalidate registers.");
471 } 467 }
472 468
469 if (mci->cd) {
470 /* Timing facility damage */
471 s390_handle_damage("TOD clock damaged");
472 }
473
474 if (mci->ed && mci->ec) {
475 /* External damage */
476 if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
477 etr_sync_check();
478 if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
479 etr_switch_to_local();
480 }
481
473 if (mci->se) 482 if (mci->se)
474 /* Storage error uncorrected */ 483 /* Storage error uncorrected */
475 s390_handle_damage("received storage error uncorrected " 484 s390_handle_damage("received storage error uncorrected "
@@ -508,7 +517,7 @@ static int
508machine_check_init(void) 517machine_check_init(void)
509{ 518{
510 init_MUTEX_LOCKED(&m_sem); 519 init_MUTEX_LOCKED(&m_sem);
511 ctl_clear_bit(14, 25); /* disable external damage MCH */ 520 ctl_set_bit(14, 25); /* enable external damage MCH */
512 ctl_set_bit(14, 27); /* enable system recovery MCH */ 521 ctl_set_bit(14, 27); /* enable system recovery MCH */
513#ifdef CONFIG_MACHCHK_WARNING 522#ifdef CONFIG_MACHCHK_WARNING
514 ctl_set_bit(14, 24); /* enable warning MCH */ 523 ctl_set_bit(14, 24); /* enable warning MCH */
@@ -529,7 +538,11 @@ arch_initcall(machine_check_init);
529static int __init 538static int __init
530machine_check_crw_init (void) 539machine_check_crw_init (void)
531{ 540{
532 kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); 541 struct task_struct *task;
542
543 task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
544 if (IS_ERR(task))
545 return PTR_ERR(task);
533 ctl_set_bit(14, 28); /* enable channel report MCH */ 546 ctl_set_bit(14, 28); /* enable channel report MCH */
534 return 0; 547 return 0;
535} 548}
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 7abb42a09ae2..d3ca4281a494 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -102,4 +102,7 @@ static inline int stcrw(struct crw *pcrw )
102 return ccode; 102 return ccode;
103} 103}
104 104
105#define ED_ETR_SYNC 12 /* External damage ETR sync check */
106#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
107
105#endif /* __s390mach */ 108#endif /* __s390mach */
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 85093b71f9fa..39a885266790 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -47,13 +47,12 @@ static int __init zfcp_module_init(void);
47static void zfcp_ns_gid_pn_handler(unsigned long); 47static void zfcp_ns_gid_pn_handler(unsigned long);
48 48
49/* miscellaneous */ 49/* miscellaneous */
50static inline int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t); 50static int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t);
51static inline void zfcp_sg_list_free(struct zfcp_sg_list *); 51static void zfcp_sg_list_free(struct zfcp_sg_list *);
52static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, 52static int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *,
53 void __user *, size_t); 53 void __user *, size_t);
54static inline int zfcp_sg_list_copy_to_user(void __user *, 54static int zfcp_sg_list_copy_to_user(void __user *,
55 struct zfcp_sg_list *, size_t); 55 struct zfcp_sg_list *, size_t);
56
57static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long); 56static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
58 57
59#define ZFCP_CFDC_IOC_MAGIC 0xDD 58#define ZFCP_CFDC_IOC_MAGIC 0xDD
@@ -605,7 +604,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
605 * elements of the scatter-gather list. The maximum size of a single element 604 * elements of the scatter-gather list. The maximum size of a single element
606 * in the scatter-gather list is PAGE_SIZE. 605 * in the scatter-gather list is PAGE_SIZE.
607 */ 606 */
608static inline int 607static int
609zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) 608zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
610{ 609{
611 struct scatterlist *sg; 610 struct scatterlist *sg;
@@ -652,7 +651,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
652 * Memory for each element in the scatter-gather list is freed. 651 * Memory for each element in the scatter-gather list is freed.
653 * Finally sg_list->sg is freed itself and sg_list->count is reset. 652 * Finally sg_list->sg is freed itself and sg_list->count is reset.
654 */ 653 */
655static inline void 654static void
656zfcp_sg_list_free(struct zfcp_sg_list *sg_list) 655zfcp_sg_list_free(struct zfcp_sg_list *sg_list)
657{ 656{
658 struct scatterlist *sg; 657 struct scatterlist *sg;
@@ -697,7 +696,7 @@ zfcp_sg_size(struct scatterlist *sg, unsigned int sg_count)
697 * @size: number of bytes to be copied 696 * @size: number of bytes to be copied
698 * Return: 0 on success, -EFAULT if copy_from_user fails. 697 * Return: 0 on success, -EFAULT if copy_from_user fails.
699 */ 698 */
700static inline int 699static int
701zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list, 700zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,
702 void __user *user_buffer, 701 void __user *user_buffer,
703 size_t size) 702 size_t size)
@@ -735,7 +734,7 @@ zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,
735 * @size: number of bytes to be copied 734 * @size: number of bytes to be copied
736 * Return: 0 on success, -EFAULT if copy_to_user fails 735 * Return: 0 on success, -EFAULT if copy_to_user fails
737 */ 736 */
738static inline int 737static int
739zfcp_sg_list_copy_to_user(void __user *user_buffer, 738zfcp_sg_list_copy_to_user(void __user *user_buffer,
740 struct zfcp_sg_list *sg_list, 739 struct zfcp_sg_list *sg_list,
741 size_t size) 740 size_t size)
@@ -1799,7 +1798,7 @@ static const struct zfcp_rc_entry zfcp_p_rjt_rc[] = {
1799 * @code: reason code 1798 * @code: reason code
1800 * @rc_table: table of reason codes and descriptions 1799 * @rc_table: table of reason codes and descriptions
1801 */ 1800 */
1802static inline const char * 1801static const char *
1803zfcp_rc_description(u8 code, const struct zfcp_rc_entry *rc_table) 1802zfcp_rc_description(u8 code, const struct zfcp_rc_entry *rc_table)
1804{ 1803{
1805 const char *descr = "unknown reason code"; 1804 const char *descr = "unknown reason code";
@@ -1847,7 +1846,7 @@ zfcp_check_ct_response(struct ct_hdr *rjt)
1847 * @rjt_par: reject parameter acc. to FC-PH/FC-FS 1846 * @rjt_par: reject parameter acc. to FC-PH/FC-FS
1848 * @rc_table: table of reason codes and descriptions 1847 * @rc_table: table of reason codes and descriptions
1849 */ 1848 */
1850static inline void 1849static void
1851zfcp_print_els_rjt(struct zfcp_ls_rjt_par *rjt_par, 1850zfcp_print_els_rjt(struct zfcp_ls_rjt_par *rjt_par,
1852 const struct zfcp_rc_entry *rc_table) 1851 const struct zfcp_rc_entry *rc_table)
1853{ 1852{
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 0aa3b1ac76af..d8191d115c14 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -31,7 +31,7 @@ MODULE_PARM_DESC(dbfsize,
31 31
32#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER 32#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
33 33
34static inline int 34static int
35zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) 35zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)
36{ 36{
37 unsigned long long sec; 37 unsigned long long sec;
@@ -106,7 +106,7 @@ zfcp_dbf_view_dump(char *out_buf, const char *label,
106 return len; 106 return len;
107} 107}
108 108
109static inline int 109static int
110zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area, 110zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
111 debug_entry_t * entry, char *out_buf) 111 debug_entry_t * entry, char *out_buf)
112{ 112{
@@ -130,7 +130,7 @@ zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
130 return len; 130 return len;
131} 131}
132 132
133inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) 133void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
134{ 134{
135 struct zfcp_adapter *adapter = fsf_req->adapter; 135 struct zfcp_adapter *adapter = fsf_req->adapter;
136 struct fsf_qtcb *qtcb = fsf_req->qtcb; 136 struct fsf_qtcb *qtcb = fsf_req->qtcb;
@@ -241,7 +241,7 @@ inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
241 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 241 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
242} 242}
243 243
244inline void 244void
245zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, 245zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
246 struct fsf_status_read_buffer *status_buffer) 246 struct fsf_status_read_buffer *status_buffer)
247{ 247{
@@ -295,7 +295,7 @@ zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
295 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 295 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
296} 296}
297 297
298inline void 298void
299zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, 299zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
300 unsigned int qdio_error, unsigned int siga_error, 300 unsigned int qdio_error, unsigned int siga_error,
301 int sbal_index, int sbal_count) 301 int sbal_index, int sbal_count)
@@ -316,7 +316,7 @@ zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
316 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 316 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
317} 317}
318 318
319static inline int 319static int
320zfcp_hba_dbf_view_response(char *out_buf, 320zfcp_hba_dbf_view_response(char *out_buf,
321 struct zfcp_hba_dbf_record_response *rec) 321 struct zfcp_hba_dbf_record_response *rec)
322{ 322{
@@ -403,7 +403,7 @@ zfcp_hba_dbf_view_response(char *out_buf,
403 return len; 403 return len;
404} 404}
405 405
406static inline int 406static int
407zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec) 407zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
408{ 408{
409 int len = 0; 409 int len = 0;
@@ -424,7 +424,7 @@ zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
424 return len; 424 return len;
425} 425}
426 426
427static inline int 427static int
428zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec) 428zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
429{ 429{
430 int len = 0; 430 int len = 0;
@@ -469,7 +469,7 @@ zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
469 return len; 469 return len;
470} 470}
471 471
472struct debug_view zfcp_hba_dbf_view = { 472static struct debug_view zfcp_hba_dbf_view = {
473 "structured", 473 "structured",
474 NULL, 474 NULL,
475 &zfcp_dbf_view_header, 475 &zfcp_dbf_view_header,
@@ -478,7 +478,7 @@ struct debug_view zfcp_hba_dbf_view = {
478 NULL 478 NULL
479}; 479};
480 480
481inline void 481void
482_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req, 482_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
483 u32 s_id, u32 d_id, void *buffer, int buflen) 483 u32 s_id, u32 d_id, void *buffer, int buflen)
484{ 484{
@@ -519,7 +519,7 @@ _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
519 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); 519 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
520} 520}
521 521
522inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) 522void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
523{ 523{
524 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; 524 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
525 struct zfcp_port *port = ct->port; 525 struct zfcp_port *port = ct->port;
@@ -531,7 +531,7 @@ inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
531 ct->req->length); 531 ct->req->length);
532} 532}
533 533
534inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) 534void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
535{ 535{
536 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; 536 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
537 struct zfcp_port *port = ct->port; 537 struct zfcp_port *port = ct->port;
@@ -543,7 +543,7 @@ inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
543 ct->resp->length); 543 ct->resp->length);
544} 544}
545 545
546static inline void 546static void
547_zfcp_san_dbf_event_common_els(const char *tag, int level, 547_zfcp_san_dbf_event_common_els(const char *tag, int level,
548 struct zfcp_fsf_req *fsf_req, u32 s_id, 548 struct zfcp_fsf_req *fsf_req, u32 s_id,
549 u32 d_id, u8 ls_code, void *buffer, int buflen) 549 u32 d_id, u8 ls_code, void *buffer, int buflen)
@@ -585,7 +585,7 @@ _zfcp_san_dbf_event_common_els(const char *tag, int level,
585 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); 585 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
586} 586}
587 587
588inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) 588void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
589{ 589{
590 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; 590 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
591 591
@@ -597,7 +597,7 @@ inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
597 els->req->length); 597 els->req->length);
598} 598}
599 599
600inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) 600void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
601{ 601{
602 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; 602 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
603 603
@@ -608,7 +608,7 @@ inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
608 els->resp->length); 608 els->resp->length);
609} 609}
610 610
611inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) 611void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
612{ 612{
613 struct zfcp_adapter *adapter = fsf_req->adapter; 613 struct zfcp_adapter *adapter = fsf_req->adapter;
614 struct fsf_status_read_buffer *status_buffer = 614 struct fsf_status_read_buffer *status_buffer =
@@ -693,7 +693,7 @@ zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
693 return len; 693 return len;
694} 694}
695 695
696struct debug_view zfcp_san_dbf_view = { 696static struct debug_view zfcp_san_dbf_view = {
697 "structured", 697 "structured",
698 NULL, 698 NULL,
699 &zfcp_dbf_view_header, 699 &zfcp_dbf_view_header,
@@ -702,7 +702,7 @@ struct debug_view zfcp_san_dbf_view = {
702 NULL 702 NULL
703}; 703};
704 704
705static inline void 705static void
706_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, 706_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
707 struct zfcp_adapter *adapter, 707 struct zfcp_adapter *adapter,
708 struct scsi_cmnd *scsi_cmnd, 708 struct scsi_cmnd *scsi_cmnd,
@@ -786,7 +786,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
786 spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); 786 spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
787} 787}
788 788
789inline void 789void
790zfcp_scsi_dbf_event_result(const char *tag, int level, 790zfcp_scsi_dbf_event_result(const char *tag, int level,
791 struct zfcp_adapter *adapter, 791 struct zfcp_adapter *adapter,
792 struct scsi_cmnd *scsi_cmnd, 792 struct scsi_cmnd *scsi_cmnd,
@@ -796,7 +796,7 @@ zfcp_scsi_dbf_event_result(const char *tag, int level,
796 adapter, scsi_cmnd, fsf_req, 0); 796 adapter, scsi_cmnd, fsf_req, 0);
797} 797}
798 798
799inline void 799void
800zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, 800zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
801 struct scsi_cmnd *scsi_cmnd, 801 struct scsi_cmnd *scsi_cmnd,
802 struct zfcp_fsf_req *new_fsf_req, 802 struct zfcp_fsf_req *new_fsf_req,
@@ -806,7 +806,7 @@ zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
806 adapter, scsi_cmnd, new_fsf_req, old_req_id); 806 adapter, scsi_cmnd, new_fsf_req, old_req_id);
807} 807}
808 808
809inline void 809void
810zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, 810zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
811 struct scsi_cmnd *scsi_cmnd) 811 struct scsi_cmnd *scsi_cmnd)
812{ 812{
@@ -884,7 +884,7 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
884 return len; 884 return len;
885} 885}
886 886
887struct debug_view zfcp_scsi_dbf_view = { 887static struct debug_view zfcp_scsi_dbf_view = {
888 "structured", 888 "structured",
889 NULL, 889 NULL,
890 &zfcp_dbf_view_header, 890 &zfcp_dbf_view_header,
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index c88babce9bca..88642dec080c 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -200,7 +200,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
200 * returns: 0 - initiated action successfully 200 * returns: 0 - initiated action successfully
201 * <0 - failed to initiate action 201 * <0 - failed to initiate action
202 */ 202 */
203int 203static int
204zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) 204zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
205{ 205{
206 int retval; 206 int retval;
@@ -295,7 +295,7 @@ zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
295 * zfcp_erp_adisc - send ADISC ELS command 295 * zfcp_erp_adisc - send ADISC ELS command
296 * @port: port structure 296 * @port: port structure
297 */ 297 */
298int 298static int
299zfcp_erp_adisc(struct zfcp_port *port) 299zfcp_erp_adisc(struct zfcp_port *port)
300{ 300{
301 struct zfcp_adapter *adapter = port->adapter; 301 struct zfcp_adapter *adapter = port->adapter;
@@ -380,7 +380,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
380 * 380 *
381 * If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered. 381 * If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered.
382 */ 382 */
383void 383static void
384zfcp_erp_adisc_handler(unsigned long data) 384zfcp_erp_adisc_handler(unsigned long data)
385{ 385{
386 struct zfcp_send_els *send_els; 386 struct zfcp_send_els *send_els;
@@ -3141,7 +3141,6 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
3141 break; 3141 break;
3142 case ZFCP_ERP_ACTION_REOPEN_ADAPTER: 3142 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
3143 if (result != ZFCP_ERP_SUCCEEDED) { 3143 if (result != ZFCP_ERP_SUCCEEDED) {
3144 struct zfcp_port *port;
3145 list_for_each_entry(port, &adapter->port_list_head, list) 3144 list_for_each_entry(port, &adapter->port_list_head, list)
3146 if (port->rport && 3145 if (port->rport &&
3147 !atomic_test_mask(ZFCP_STATUS_PORT_WKA, 3146 !atomic_test_mask(ZFCP_STATUS_PORT_WKA,
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index b8794d77285d..cda0cc095ad1 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -119,8 +119,8 @@ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
119extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); 119extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
120extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); 120extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t);
121extern char *zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *); 121extern char *zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *);
122extern void set_host_byte(u32 *, char); 122extern void set_host_byte(int *, char);
123extern void set_driver_byte(u32 *, char); 123extern void set_driver_byte(int *, char);
124extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); 124extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
125extern fcp_dl_t zfcp_get_fcp_dl(struct fcp_cmnd_iu *); 125extern fcp_dl_t zfcp_get_fcp_dl(struct fcp_cmnd_iu *);
126 126
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 067f1519eb04..4b3ae3f22e78 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -4563,7 +4563,7 @@ zfcp_fsf_req_sbal_check(unsigned long *flags,
4563/* 4563/*
4564 * set qtcb pointer in fsf_req and initialize QTCB 4564 * set qtcb pointer in fsf_req and initialize QTCB
4565 */ 4565 */
4566static inline void 4566static void
4567zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) 4567zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
4568{ 4568{
4569 if (likely(fsf_req->qtcb != NULL)) { 4569 if (likely(fsf_req->qtcb != NULL)) {
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index dbd9f48e863e..1e12a78e8edd 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -21,22 +21,22 @@
21 21
22#include "zfcp_ext.h" 22#include "zfcp_ext.h"
23 23
24static inline void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int); 24static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int);
25static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_get 25static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_get
26 (struct zfcp_qdio_queue *, int, int); 26 (struct zfcp_qdio_queue *, int, int);
27static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_resp 27static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_resp
28 (struct zfcp_fsf_req *, int, int); 28 (struct zfcp_fsf_req *, int, int);
29static inline volatile struct qdio_buffer_element *zfcp_qdio_sbal_chain 29static volatile struct qdio_buffer_element *zfcp_qdio_sbal_chain
30 (struct zfcp_fsf_req *, unsigned long); 30 (struct zfcp_fsf_req *, unsigned long);
31static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_next 31static volatile struct qdio_buffer_element *zfcp_qdio_sbale_next
32 (struct zfcp_fsf_req *, unsigned long); 32 (struct zfcp_fsf_req *, unsigned long);
33static inline int zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *, int, int); 33static int zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *, int, int);
34static inline int zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *); 34static inline int zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *);
35static inline void zfcp_qdio_sbale_fill 35static void zfcp_qdio_sbale_fill
36 (struct zfcp_fsf_req *, unsigned long, void *, int); 36 (struct zfcp_fsf_req *, unsigned long, void *, int);
37static inline int zfcp_qdio_sbals_from_segment 37static int zfcp_qdio_sbals_from_segment
38 (struct zfcp_fsf_req *, unsigned long, void *, unsigned long); 38 (struct zfcp_fsf_req *, unsigned long, void *, unsigned long);
39static inline int zfcp_qdio_sbals_from_buffer 39static int zfcp_qdio_sbals_from_buffer
40 (struct zfcp_fsf_req *, unsigned long, void *, unsigned long, int); 40 (struct zfcp_fsf_req *, unsigned long, void *, unsigned long, int);
41 41
42static qdio_handler_t zfcp_qdio_request_handler; 42static qdio_handler_t zfcp_qdio_request_handler;
@@ -201,7 +201,7 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
201 * returns: error flag 201 * returns: error flag
202 * 202 *
203 */ 203 */
204static inline int 204static int
205zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, 205zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
206 unsigned int qdio_error, unsigned int siga_error, 206 unsigned int qdio_error, unsigned int siga_error,
207 int first_element, int elements_processed) 207 int first_element, int elements_processed)
@@ -462,7 +462,7 @@ zfcp_qdio_sbale_get(struct zfcp_qdio_queue *queue, int sbal, int sbale)
462 * zfcp_qdio_sbale_req - return pointer to SBALE of request_queue for 462 * zfcp_qdio_sbale_req - return pointer to SBALE of request_queue for
463 * a struct zfcp_fsf_req 463 * a struct zfcp_fsf_req
464 */ 464 */
465inline volatile struct qdio_buffer_element * 465volatile struct qdio_buffer_element *
466zfcp_qdio_sbale_req(struct zfcp_fsf_req *fsf_req, int sbal, int sbale) 466zfcp_qdio_sbale_req(struct zfcp_fsf_req *fsf_req, int sbal, int sbale)
467{ 467{
468 return zfcp_qdio_sbale_get(&fsf_req->adapter->request_queue, 468 return zfcp_qdio_sbale_get(&fsf_req->adapter->request_queue,
@@ -484,7 +484,7 @@ zfcp_qdio_sbale_resp(struct zfcp_fsf_req *fsf_req, int sbal, int sbale)
484 * zfcp_qdio_sbale_curr - return current SBALE on request_queue for 484 * zfcp_qdio_sbale_curr - return current SBALE on request_queue for
485 * a struct zfcp_fsf_req 485 * a struct zfcp_fsf_req
486 */ 486 */
487inline volatile struct qdio_buffer_element * 487volatile struct qdio_buffer_element *
488zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req) 488zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req)
489{ 489{
490 return zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 490 return zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr,
@@ -499,7 +499,7 @@ zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req)
499 * 499 *
500 * Note: We can assume at least one free SBAL in the request_queue when called. 500 * Note: We can assume at least one free SBAL in the request_queue when called.
501 */ 501 */
502static inline void 502static void
503zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) 503zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
504{ 504{
505 int count = atomic_read(&fsf_req->adapter->request_queue.free_count); 505 int count = atomic_read(&fsf_req->adapter->request_queue.free_count);
@@ -517,7 +517,7 @@ zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
517 * 517 *
518 * This function changes sbal_curr, sbale_curr, sbal_number of fsf_req. 518 * This function changes sbal_curr, sbale_curr, sbal_number of fsf_req.
519 */ 519 */
520static inline volatile struct qdio_buffer_element * 520static volatile struct qdio_buffer_element *
521zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) 521zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
522{ 522{
523 volatile struct qdio_buffer_element *sbale; 523 volatile struct qdio_buffer_element *sbale;
@@ -554,7 +554,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
554/** 554/**
555 * zfcp_qdio_sbale_next - switch to next SBALE, chain SBALs if needed 555 * zfcp_qdio_sbale_next - switch to next SBALE, chain SBALs if needed
556 */ 556 */
557static inline volatile struct qdio_buffer_element * 557static volatile struct qdio_buffer_element *
558zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) 558zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
559{ 559{
560 if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) 560 if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
@@ -569,7 +569,7 @@ zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
569 * zfcp_qdio_sbals_zero - initialize SBALs between first and last in queue 569 * zfcp_qdio_sbals_zero - initialize SBALs between first and last in queue
570 * with zero from 570 * with zero from
571 */ 571 */
572static inline int 572static int
573zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *queue, int first, int last) 573zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *queue, int first, int last)
574{ 574{
575 struct qdio_buffer **buf = queue->buffer; 575 struct qdio_buffer **buf = queue->buffer;
@@ -603,7 +603,7 @@ zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *fsf_req)
603 * zfcp_qdio_sbale_fill - set address and lenght in current SBALE 603 * zfcp_qdio_sbale_fill - set address and lenght in current SBALE
604 * on request_queue 604 * on request_queue
605 */ 605 */
606static inline void 606static void
607zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, 607zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
608 void *addr, int length) 608 void *addr, int length)
609{ 609{
@@ -624,7 +624,7 @@ zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
624 * Alignment and length of the segment determine how many SBALEs are needed 624 * Alignment and length of the segment determine how many SBALEs are needed
625 * for the memory segment. 625 * for the memory segment.
626 */ 626 */
627static inline int 627static int
628zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, 628zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
629 void *start_addr, unsigned long total_length) 629 void *start_addr, unsigned long total_length)
630{ 630{
@@ -659,7 +659,7 @@ zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
659 * @sg_count: number of elements in scatter-gather list 659 * @sg_count: number of elements in scatter-gather list
660 * @max_sbals: upper bound for number of SBALs to be used 660 * @max_sbals: upper bound for number of SBALs to be used
661 */ 661 */
662inline int 662int
663zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, 663zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
664 struct scatterlist *sg, int sg_count, int max_sbals) 664 struct scatterlist *sg, int sg_count, int max_sbals)
665{ 665{
@@ -707,7 +707,7 @@ out:
707 * @length: length of buffer 707 * @length: length of buffer
708 * @max_sbals: upper bound for number of SBALs to be used 708 * @max_sbals: upper bound for number of SBALs to be used
709 */ 709 */
710static inline int 710static int
711zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, 711zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
712 void *buffer, unsigned long length, int max_sbals) 712 void *buffer, unsigned long length, int max_sbals)
713{ 713{
@@ -728,7 +728,7 @@ zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
728 * @scsi_cmnd: either scatter-gather list or buffer contained herein is used 728 * @scsi_cmnd: either scatter-gather list or buffer contained herein is used
729 * to fill SBALs 729 * to fill SBALs
730 */ 730 */
731inline int 731int
732zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req, 732zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req,
733 unsigned long sbtype, struct scsi_cmnd *scsi_cmnd) 733 unsigned long sbtype, struct scsi_cmnd *scsi_cmnd)
734{ 734{
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 452d96f92a14..99db02062c3b 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -90,7 +90,7 @@ zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
90 return fcp_sns_info_ptr; 90 return fcp_sns_info_ptr;
91} 91}
92 92
93fcp_dl_t * 93static fcp_dl_t *
94zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd) 94zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd)
95{ 95{
96 int additional_length = fcp_cmd->add_fcp_cdb_length << 2; 96 int additional_length = fcp_cmd->add_fcp_cdb_length << 2;
@@ -124,19 +124,19 @@ zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl)
124 * regarding the specified byte 124 * regarding the specified byte
125 */ 125 */
126static inline void 126static inline void
127set_byte(u32 * result, char status, char pos) 127set_byte(int *result, char status, char pos)
128{ 128{
129 *result |= status << (pos * 8); 129 *result |= status << (pos * 8);
130} 130}
131 131
132void 132void
133set_host_byte(u32 * result, char status) 133set_host_byte(int *result, char status)
134{ 134{
135 set_byte(result, status, 2); 135 set_byte(result, status, 2);
136} 136}
137 137
138void 138void
139set_driver_byte(u32 * result, char status) 139set_driver_byte(int *result, char status)
140{ 140{
141 set_byte(result, status, 3); 141 set_byte(result, status, 3);
142} 142}
@@ -280,7 +280,7 @@ out:
280 return retval; 280 return retval;
281} 281}
282 282
283void 283static void
284zfcp_scsi_command_sync_handler(struct scsi_cmnd *scpnt) 284zfcp_scsi_command_sync_handler(struct scsi_cmnd *scpnt)
285{ 285{
286 struct completion *wait = (struct completion *) scpnt->SCp.ptr; 286 struct completion *wait = (struct completion *) scpnt->SCp.ptr;
@@ -324,7 +324,7 @@ zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
324 * returns: 0 - success, SCSI command enqueued 324 * returns: 0 - success, SCSI command enqueued
325 * !0 - failure 325 * !0 - failure
326 */ 326 */
327int 327static int
328zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, 328zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
329 void (*done) (struct scsi_cmnd *)) 329 void (*done) (struct scsi_cmnd *))
330{ 330{
@@ -380,7 +380,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
380 * will handle late commands. (Usually, the normal completion of late 380 * will handle late commands. (Usually, the normal completion of late
381 * commands is ignored with respect to the running abort operation.) 381 * commands is ignored with respect to the running abort operation.)
382 */ 382 */
383int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) 383static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
384{ 384{
385 struct Scsi_Host *scsi_host; 385 struct Scsi_Host *scsi_host;
386 struct zfcp_adapter *adapter; 386 struct zfcp_adapter *adapter;
@@ -445,7 +445,7 @@ int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
445 return retval; 445 return retval;
446} 446}
447 447
448int 448static int
449zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) 449zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
450{ 450{
451 int retval; 451 int retval;
@@ -541,7 +541,7 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
541/** 541/**
542 * zfcp_scsi_eh_host_reset_handler - handler for host and bus reset 542 * zfcp_scsi_eh_host_reset_handler - handler for host and bus reset
543 */ 543 */
544int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) 544static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
545{ 545{
546 struct zfcp_unit *unit; 546 struct zfcp_unit *unit;
547 struct zfcp_adapter *adapter; 547 struct zfcp_adapter *adapter;
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c
index 1e788e815ce7..090743d2f914 100644
--- a/drivers/s390/sysinfo.c
+++ b/drivers/s390/sysinfo.c
@@ -9,8 +9,14 @@
9#include <linux/mm.h> 9#include <linux/mm.h>
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h>
12#include <asm/ebcdic.h> 13#include <asm/ebcdic.h>
13 14
15/* Sigh, math-emu. Don't ask. */
16#include <asm/sfp-util.h>
17#include <math-emu/soft-fp.h>
18#include <math-emu/single.h>
19
14struct sysinfo_1_1_1 { 20struct sysinfo_1_1_1 {
15 char reserved_0[32]; 21 char reserved_0[32];
16 char manufacturer[16]; 22 char manufacturer[16];
@@ -198,7 +204,7 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
198 * if the higher order 8 bits are not zero. Printing 204 * if the higher order 8 bits are not zero. Printing
199 * a floating point number in the kernel is a no-no, 205 * a floating point number in the kernel is a no-no,
200 * always print the number as 32 bit unsigned integer. 206 * always print the number as 32 bit unsigned integer.
201 * The user-space needs to know about the stange 207 * The user-space needs to know about the strange
202 * encoding of the alternate cpu capability. 208 * encoding of the alternate cpu capability.
203 */ 209 */
204 len += sprintf(page + len, "Capability: %u %u\n", 210 len += sprintf(page + len, "Capability: %u %u\n",
@@ -351,3 +357,58 @@ static __init int create_proc_sysinfo(void)
351 357
352__initcall(create_proc_sysinfo); 358__initcall(create_proc_sysinfo);
353 359
360/*
361 * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
362 */
363void s390_adjust_jiffies(void)
364{
365 struct sysinfo_1_2_2 *info;
366 const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
367 FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
368 FP_DECL_EX;
369 unsigned int capability;
370
371 info = (void *) get_zeroed_page(GFP_KERNEL);
372 if (!info)
373 return;
374
375 if (stsi(info, 1, 2, 2) != -ENOSYS) {
376 /*
377 * Major sigh. The cpu capability encoding is "special".
378 * If the first 9 bits of info->capability are 0 then it
379 * is a 32 bit unsigned integer in the range 0 .. 2^23.
380 * If the first 9 bits are != 0 then it is a 32 bit float.
381 * In addition a lower value indicates a proportionally
382 * higher cpu capacity. Bogomips are the other way round.
383 * To get to a halfway suitable number we divide 1e7
384 * by the cpu capability number. Yes, that means a floating
385 * point division .. math-emu here we come :-)
386 */
387 FP_UNPACK_SP(SA, &fmil);
388 if ((info->capability >> 23) == 0)
389 FP_FROM_INT_S(SB, info->capability, 32, int);
390 else
391 FP_UNPACK_SP(SB, &info->capability);
392 FP_DIV_S(SR, SA, SB);
393 FP_TO_INT_S(capability, SR, 32, 0);
394 } else
395 /*
396 * Really old machine without stsi block for basic
397 * cpu information. Report 42.0 bogomips.
398 */
399 capability = 42;
400 loops_per_jiffy = capability * (500000/HZ);
401 free_page((unsigned long) info);
402}
403
404/*
405 * calibrate the delay loop
406 */
407void __init calibrate_delay(void)
408{
409 s390_adjust_jiffies();
410 /* Print the good old Bogomips line .. */
411 printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
412 "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
413 (loops_per_jiffy/(5000/HZ)) % 100);
414}
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index c7d887540d8d..aa6a620c162f 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -69,6 +69,14 @@ config LOGITECH_FF
69 Note: if you say N here, this device will still be supported, but without 69 Note: if you say N here, this device will still be supported, but without
70 force feedback. 70 force feedback.
71 71
72config PANTHERLORD_FF
73 bool "PantherLord USB/PS2 2in1 Adapter support"
74 depends on HID_FF
75 select INPUT_FF_MEMLESS if USB_HID
76 help
77 Say Y here if you have a PantherLord USB/PS2 2in1 Adapter and want
78 to enable force feedback support for it.
79
72config THRUSTMASTER_FF 80config THRUSTMASTER_FF
73 bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)" 81 bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
74 depends on HID_FF && EXPERIMENTAL 82 depends on HID_FF && EXPERIMENTAL
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 1a24b5bfa05f..a06024e5cd56 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -17,6 +17,9 @@ endif
17ifeq ($(CONFIG_LOGITECH_FF),y) 17ifeq ($(CONFIG_LOGITECH_FF),y)
18 usbhid-objs += hid-lgff.o 18 usbhid-objs += hid-lgff.o
19endif 19endif
20ifeq ($(CONFIG_PANTHERLORD_FF),y)
21 usbhid-objs += hid-plff.o
22endif
20ifeq ($(CONFIG_THRUSTMASTER_FF),y) 23ifeq ($(CONFIG_THRUSTMASTER_FF),y)
21 usbhid-objs += hid-tmff.o 24 usbhid-objs += hid-tmff.o
22endif 25endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index c6c9e72e5fd9..e07a30490726 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -35,6 +35,7 @@
35 35
36#include <linux/hid.h> 36#include <linux/hid.h>
37#include <linux/hiddev.h> 37#include <linux/hiddev.h>
38#include <linux/hid-debug.h>
38#include "usbhid.h" 39#include "usbhid.h"
39 40
40/* 41/*
@@ -220,23 +221,6 @@ static void hid_irq_in(struct urb *urb)
220 } 221 }
221} 222}
222 223
223/*
224 * Find a report field with a specified HID usage.
225 */
226#if 0
227struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
228{
229 struct hid_report *report;
230 int i;
231
232 list_for_each_entry(report, &hid->report_enum[type].report_list, list)
233 for (i = 0; i < report->maxfield; i++)
234 if (report->field[i]->logical == wanted_usage)
235 return report->field[i];
236 return NULL;
237}
238#endif /* 0 */
239
240static int hid_submit_out(struct hid_device *hid) 224static int hid_submit_out(struct hid_device *hid)
241{ 225{
242 struct hid_report *report; 226 struct hid_report *report;
@@ -501,7 +485,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
501{ 485{
502 int result, retries = 4; 486 int result, retries = 4;
503 487
504 memset(buf,0,size); // Make sure we parse really received data 488 memset(buf, 0, size);
505 489
506 do { 490 do {
507 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 491 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -528,18 +512,6 @@ void usbhid_close(struct hid_device *hid)
528 usb_kill_urb(usbhid->urbin); 512 usb_kill_urb(usbhid->urbin);
529} 513}
530 514
531static int hidinput_open(struct input_dev *dev)
532{
533 struct hid_device *hid = dev->private;
534 return usbhid_open(hid);
535}
536
537static void hidinput_close(struct input_dev *dev)
538{
539 struct hid_device *hid = dev->private;
540 usbhid_close(hid);
541}
542
543#define USB_VENDOR_ID_PANJIT 0x134c 515#define USB_VENDOR_ID_PANJIT 0x134c
544 516
545#define USB_VENDOR_ID_TURBOX 0x062a 517#define USB_VENDOR_ID_TURBOX 0x062a
@@ -770,6 +742,7 @@ void usbhid_init_reports(struct hid_device *hid)
770#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c 742#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
771#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a 743#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
772#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b 744#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
745#define USB_DEVICE_ID_APPLE_IR 0x8240
773 746
774#define USB_VENDOR_ID_CHERRY 0x046a 747#define USB_VENDOR_ID_CHERRY 0x046a
775#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 748#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@@ -792,6 +765,9 @@ void usbhid_init_reports(struct hid_device *hid)
792#define USB_VENDOR_ID_IMATION 0x0718 765#define USB_VENDOR_ID_IMATION 0x0718
793#define USB_DEVICE_ID_DISC_STAKKA 0xd000 766#define USB_DEVICE_ID_DISC_STAKKA 0xd000
794 767
768#define USB_VENDOR_ID_PANTHERLORD 0x0810
769#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
770
795/* 771/*
796 * Alphabetically sorted blacklist by quirk type. 772 * Alphabetically sorted blacklist by quirk type.
797 */ 773 */
@@ -946,19 +922,21 @@ static const struct hid_blacklist {
946 922
947 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, 923 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
948 924
949 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, 925 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
950 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, 926 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
951 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, 927 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
952 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, 928 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
953 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, 929 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
954 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, 930 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
955 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, 931 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
956 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, 932 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
957 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, 933 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
958 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, 934 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
959 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, 935 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
960 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, 936 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
961 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, 937 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
938
939 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR, HID_QUIRK_IGNORE },
962 940
963 { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, 941 { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
964 { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, 942 { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
@@ -969,6 +947,8 @@ static const struct hid_blacklist {
969 947
970 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, 948 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
971 949
950 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
951
972 { 0, 0 } 952 { 0, 0 }
973}; 953};
974 954
@@ -1064,6 +1044,11 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1064 if (quirks & HID_QUIRK_IGNORE) 1044 if (quirks & HID_QUIRK_IGNORE)
1065 return NULL; 1045 return NULL;
1066 1046
1047 if ((quirks & HID_QUIRK_IGNORE_MOUSE) &&
1048 (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE))
1049 return NULL;
1050
1051
1067 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && 1052 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
1068 (!interface->desc.bNumEndpoints || 1053 (!interface->desc.bNumEndpoints ||
1069 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { 1054 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
@@ -1235,8 +1220,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1235 usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; 1220 usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
1236 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); 1221 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1237 hid->hidinput_input_event = usb_hidinput_input_event; 1222 hid->hidinput_input_event = usb_hidinput_input_event;
1238 hid->hidinput_open = hidinput_open; 1223 hid->hid_open = usbhid_open;
1239 hid->hidinput_close = hidinput_close; 1224 hid->hid_close = usbhid_close;
1240#ifdef CONFIG_USB_HIDDEV 1225#ifdef CONFIG_USB_HIDDEV
1241 hid->hiddev_hid_event = hiddev_hid_event; 1226 hid->hiddev_hid_event = hiddev_hid_event;
1242 hid->hiddev_report_event = hiddev_report_event; 1227 hid->hiddev_report_event = hiddev_report_event;
@@ -1315,11 +1300,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
1315 return -ENODEV; 1300 return -ENODEV;
1316 } 1301 }
1317 1302
1318 /* This only gets called when we are a single-input (most of the 1303 if ((hid->claimed & HID_CLAIMED_INPUT))
1319 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
1320 * only useful in this case, and not for multi-input quirks. */
1321 if ((hid->claimed & HID_CLAIMED_INPUT) &&
1322 !(hid->quirks & HID_QUIRK_MULTI_INPUT))
1323 hid_ff_init(hid); 1304 hid_ff_init(hid);
1324 1305
1325 printk(KERN_INFO); 1306 printk(KERN_INFO);
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index 59ed65e7a621..5d145058a5cb 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -58,6 +58,9 @@ static struct hid_ff_initializer inits[] = {
58 { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ 58 { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
59 { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ 59 { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
60#endif 60#endif
61#ifdef CONFIG_PANTHERLORD_FF
62 { 0x810, 0x0001, hid_plff_init },
63#endif
61#ifdef CONFIG_THRUSTMASTER_FF 64#ifdef CONFIG_THRUSTMASTER_FF
62 { 0x44f, 0xb304, hid_tmff_init }, 65 { 0x44f, 0xb304, hid_tmff_init },
63#endif 66#endif
diff --git a/drivers/usb/input/hid-plff.c b/drivers/usb/input/hid-plff.c
new file mode 100644
index 000000000000..76d2e6e14db4
--- /dev/null
+++ b/drivers/usb/input/hid-plff.c
@@ -0,0 +1,129 @@
1/*
2 * Force feedback support for PantherLord USB/PS2 2in1 Adapter devices
3 *
4 * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
5 */
6
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24/* #define DEBUG */
25
26#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
27
28#include <linux/input.h>
29#include <linux/usb.h>
30#include <linux/hid.h>
31#include "usbhid.h"
32
33struct plff_device {
34 struct hid_report *report;
35};
36
37static int hid_plff_play(struct input_dev *dev, void *data,
38 struct ff_effect *effect)
39{
40 struct hid_device *hid = dev->private;
41 struct plff_device *plff = data;
42 int left, right;
43
44 left = effect->u.rumble.strong_magnitude;
45 right = effect->u.rumble.weak_magnitude;
46 debug("called with 0x%04x 0x%04x", left, right);
47
48 left = left * 0x7f / 0xffff;
49 right = right * 0x7f / 0xffff;
50
51 plff->report->field[0]->value[2] = left;
52 plff->report->field[0]->value[3] = right;
53 debug("running with 0x%02x 0x%02x", left, right);
54 usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
55
56 return 0;
57}
58
59int hid_plff_init(struct hid_device *hid)
60{
61 struct plff_device *plff;
62 struct hid_report *report;
63 struct hid_input *hidinput;
64 struct list_head *report_list =
65 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
66 struct list_head *report_ptr = report_list;
67 struct input_dev *dev;
68 int error;
69
70 /* The device contains 2 output reports (one for each
71 HID_QUIRK_MULTI_INPUT device), both containing 1 field, which
72 contains 4 ff00.0002 usages and 4 16bit absolute values.
73
74 The 2 input reports also contain a field which contains
75 8 ff00.0001 usages and 8 boolean values. Their meaning is
76 currently unknown. */
77
78 if (list_empty(report_list)) {
79 printk(KERN_ERR "hid-plff: no output reports found\n");
80 return -ENODEV;
81 }
82
83 list_for_each_entry(hidinput, &hid->inputs, list) {
84
85 report_ptr = report_ptr->next;
86
87 if (report_ptr == report_list) {
88 printk(KERN_ERR "hid-plff: required output report is missing\n");
89 return -ENODEV;
90 }
91
92 report = list_entry(report_ptr, struct hid_report, list);
93 if (report->maxfield < 1) {
94 printk(KERN_ERR "hid-plff: no fields in the report\n");
95 return -ENODEV;
96 }
97
98 if (report->field[0]->report_count < 4) {
99 printk(KERN_ERR "hid-plff: not enough values in the field\n");
100 return -ENODEV;
101 }
102
103 plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
104 if (!plff)
105 return -ENOMEM;
106
107 dev = hidinput->input;
108
109 set_bit(FF_RUMBLE, dev->ffbit);
110
111 error = input_ff_create_memless(dev, plff, hid_plff_play);
112 if (error) {
113 kfree(plff);
114 return error;
115 }
116
117 plff->report = report;
118 plff->report->field[0]->value[0] = 0x00;
119 plff->report->field[0]->value[1] = 0x00;
120 plff->report->field[0]->value[2] = 0x00;
121 plff->report->field[0]->value[3] = 0x00;
122 usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
123 }
124
125 printk(KERN_INFO "hid-plff: Force feedback for PantherLord USB/PS2 "
126 "2in1 Adapters by Anssi Hannula <anssi.hannula@gmail.com>\n");
127
128 return 0;
129}
diff --git a/drivers/video/output.c b/drivers/video/output.c
new file mode 100644
index 000000000000..1473f2c892d2
--- /dev/null
+++ b/drivers/video/output.c
@@ -0,0 +1,129 @@
1/*
2 * output.c - Display Output Switch driver
3 *
4 * Copyright (C) 2006 Luming Yu <luming.yu@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/module.h>
25#include <linux/video_output.h>
26#include <linux/err.h>
27#include <linux/ctype.h>
28
29
30MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction");
31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>");
33
34static ssize_t video_output_show_state(struct class_device *dev,char *buf)
35{
36 ssize_t ret_size = 0;
37 struct output_device *od = to_output_device(dev);
38 if (od->props)
39 ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od));
40 return ret_size;
41}
42
43static ssize_t video_output_store_state(struct class_device *dev,
44 const char *buf,size_t count)
45{
46 char *endp;
47 struct output_device *od = to_output_device(dev);
48 int request_state = simple_strtoul(buf,&endp,0);
49 size_t size = endp - buf;
50
51 if (*endp && isspace(*endp))
52 size++;
53 if (size != count)
54 return -EINVAL;
55
56 if (od->props) {
57 od->request_state = request_state;
58 od->props->set_state(od);
59 }
60 return count;
61}
62
63static void video_output_class_release(struct class_device *dev)
64{
65 struct output_device *od = to_output_device(dev);
66 kfree(od);
67}
68
69static struct class_device_attribute video_output_attributes[] = {
70 __ATTR(state, 0644, video_output_show_state, video_output_store_state),
71 __ATTR_NULL,
72};
73
74static struct class video_output_class = {
75 .name = "video_output",
76 .release = video_output_class_release,
77 .class_dev_attrs = video_output_attributes,
78};
79
80struct output_device *video_output_register(const char *name,
81 struct device *dev,
82 void *devdata,
83 struct output_properties *op)
84{
85 struct output_device *new_dev;
86 int ret_code = 0;
87
88 new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL);
89 if (!new_dev) {
90 ret_code = -ENOMEM;
91 goto error_return;
92 }
93 new_dev->props = op;
94 new_dev->class_dev.class = &video_output_class;
95 new_dev->class_dev.dev = dev;
96 strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN);
97 class_set_devdata(&new_dev->class_dev,devdata);
98 ret_code = class_device_register(&new_dev->class_dev);
99 if (ret_code) {
100 kfree(new_dev);
101 goto error_return;
102 }
103 return new_dev;
104
105error_return:
106 return ERR_PTR(ret_code);
107}
108EXPORT_SYMBOL(video_output_register);
109
110void video_output_unregister(struct output_device *dev)
111{
112 if (!dev)
113 return;
114 class_device_unregister(&dev->class_dev);
115}
116EXPORT_SYMBOL(video_output_unregister);
117
118static void __exit video_output_class_exit(void)
119{
120 class_unregister(&video_output_class);
121}
122
123static int __init video_output_class_init(void)
124{
125 return class_register(&video_output_class);
126}
127
128postcore_initcall(video_output_class_init);
129module_exit(video_output_class_exit);