summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-07-13 15:25:59 +0100
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-07-13 15:25:59 +0100
commit30beab1491f0b96b2f23d3fb68af01fd921a16d8 (patch)
treec580bdc0846269fbb10feeda901ecec1a48ee2ef /drivers
parent21af6c4f2aa5f63138871b4ddd77d7ebf2588c9d (diff)
parentc32511e2718618f0b53479eb36e07439aa363a74 (diff)
Merge with /shiny/git/linux-2.6/.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/Kconfig38
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/asus_acpi.c4
-rw-r--r--drivers/acpi/bus.c8
-rw-r--r--drivers/acpi/button.c245
-rw-r--r--drivers/acpi/dispatcher/dsfield.c58
-rw-r--r--drivers/acpi/dispatcher/dsinit.c28
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c11
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c195
-rw-r--r--drivers/acpi/dispatcher/dsobject.c79
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c105
-rw-r--r--drivers/acpi/dispatcher/dsutils.c41
-rw-r--r--drivers/acpi/dispatcher/dswexec.c57
-rw-r--r--drivers/acpi/dispatcher/dswload.c118
-rw-r--r--drivers/acpi/dispatcher/dswscope.c31
-rw-r--r--drivers/acpi/dispatcher/dswstate.c458
-rw-r--r--drivers/acpi/ec.c420
-rw-r--r--drivers/acpi/events/evevent.c33
-rw-r--r--drivers/acpi/events/evgpe.c39
-rw-r--r--drivers/acpi/events/evgpeblk.c63
-rw-r--r--drivers/acpi/events/evmisc.c97
-rw-r--r--drivers/acpi/events/evregion.c35
-rw-r--r--drivers/acpi/events/evrgnini.c14
-rw-r--r--drivers/acpi/events/evsci.c12
-rw-r--r--drivers/acpi/events/evxface.c19
-rw-r--r--drivers/acpi/events/evxfevnt.c25
-rw-r--r--drivers/acpi/executer/exconfig.c31
-rw-r--r--drivers/acpi/executer/exconvrt.c44
-rw-r--r--drivers/acpi/executer/excreate.c50
-rw-r--r--drivers/acpi/executer/exdump.c105
-rw-r--r--drivers/acpi/executer/exfield.c25
-rw-r--r--drivers/acpi/executer/exfldio.c133
-rw-r--r--drivers/acpi/executer/exmisc.c7
-rw-r--r--drivers/acpi/executer/exmutex.c45
-rw-r--r--drivers/acpi/executer/exnames.c70
-rw-r--r--drivers/acpi/executer/exoparg1.c94
-rw-r--r--drivers/acpi/executer/exoparg2.c69
-rw-r--r--drivers/acpi/executer/exoparg3.c25
-rw-r--r--drivers/acpi/executer/exoparg6.c26
-rw-r--r--drivers/acpi/executer/exprep.c104
-rw-r--r--drivers/acpi/executer/exregion.c34
-rw-r--r--drivers/acpi/executer/exresnte.c24
-rw-r--r--drivers/acpi/executer/exresolv.c63
-rw-r--r--drivers/acpi/executer/exresop.c80
-rw-r--r--drivers/acpi/executer/exstore.c260
-rw-r--r--drivers/acpi/executer/exstoren.c20
-rw-r--r--drivers/acpi/executer/exstorob.c9
-rw-r--r--drivers/acpi/executer/exsystem.c48
-rw-r--r--drivers/acpi/executer/exutils.c37
-rw-r--r--drivers/acpi/glue.c360
-rw-r--r--drivers/acpi/hardware/hwacpi.c19
-rw-r--r--drivers/acpi/hardware/hwgpe.c31
-rw-r--r--drivers/acpi/hardware/hwregs.c114
-rw-r--r--drivers/acpi/hardware/hwsleep.c101
-rw-r--r--drivers/acpi/hardware/hwtimer.c4
-rw-r--r--drivers/acpi/hotkey.c1019
-rw-r--r--drivers/acpi/ibm_acpi.c8
-rw-r--r--drivers/acpi/namespace/nsaccess.c5
-rw-r--r--drivers/acpi/namespace/nsalloc.c121
-rw-r--r--drivers/acpi/namespace/nsdump.c109
-rw-r--r--drivers/acpi/namespace/nsdumpdv.c18
-rw-r--r--drivers/acpi/namespace/nseval.c70
-rw-r--r--drivers/acpi/namespace/nsinit.c28
-rw-r--r--drivers/acpi/namespace/nsload.c28
-rw-r--r--drivers/acpi/namespace/nsnames.c12
-rw-r--r--drivers/acpi/namespace/nsobject.c14
-rw-r--r--drivers/acpi/namespace/nssearch.c29
-rw-r--r--drivers/acpi/namespace/nsutils.c167
-rw-r--r--drivers/acpi/namespace/nswalk.c2
-rw-r--r--drivers/acpi/namespace/nsxfeval.c16
-rw-r--r--drivers/acpi/namespace/nsxfname.c8
-rw-r--r--drivers/acpi/namespace/nsxfobj.c4
-rw-r--r--drivers/acpi/osl.c12
-rw-r--r--drivers/acpi/parser/psargs.c55
-rw-r--r--drivers/acpi/parser/psopcode.c298
-rw-r--r--drivers/acpi/parser/psparse.c144
-rw-r--r--drivers/acpi/parser/psscope.c45
-rw-r--r--drivers/acpi/parser/pstree.c159
-rw-r--r--drivers/acpi/parser/psutils.c15
-rw-r--r--drivers/acpi/parser/pswalk.c11
-rw-r--r--drivers/acpi/parser/psxface.c21
-rw-r--r--drivers/acpi/pci_irq.c2
-rw-r--r--drivers/acpi/pci_link.c43
-rw-r--r--drivers/acpi/processor_core.c37
-rw-r--r--drivers/acpi/processor_idle.c138
-rw-r--r--drivers/acpi/processor_perflib.c33
-rw-r--r--drivers/acpi/resources/rsaddr.c480
-rw-r--r--drivers/acpi/resources/rscalc.c144
-rw-r--r--drivers/acpi/resources/rscreate.c45
-rw-r--r--drivers/acpi/resources/rsdump.c402
-rw-r--r--drivers/acpi/resources/rsio.c197
-rw-r--r--drivers/acpi/resources/rsirq.c167
-rw-r--r--drivers/acpi/resources/rslist.c68
-rw-r--r--drivers/acpi/resources/rsmemory.c236
-rw-r--r--drivers/acpi/resources/rsmisc.c160
-rw-r--r--drivers/acpi/resources/rsutils.c53
-rw-r--r--drivers/acpi/resources/rsxface.c43
-rw-r--r--drivers/acpi/scan.c12
-rw-r--r--drivers/acpi/sleep/main.c74
-rw-r--r--drivers/acpi/sleep/poweroff.c81
-rw-r--r--drivers/acpi/sleep/proc.c9
-rw-r--r--drivers/acpi/tables/tbconvrt.c105
-rw-r--r--drivers/acpi/tables/tbget.c63
-rw-r--r--drivers/acpi/tables/tbgetall.c45
-rw-r--r--drivers/acpi/tables/tbinstal.c31
-rw-r--r--drivers/acpi/tables/tbrsdt.c19
-rw-r--r--drivers/acpi/tables/tbutils.c97
-rw-r--r--drivers/acpi/tables/tbxface.c39
-rw-r--r--drivers/acpi/tables/tbxfroot.c123
-rw-r--r--drivers/acpi/toshiba_acpi.c8
-rw-r--r--drivers/acpi/utilities/utalloc.c84
-rw-r--r--drivers/acpi/utilities/utcopy.c126
-rw-r--r--drivers/acpi/utilities/utdebug.c106
-rw-r--r--drivers/acpi/utilities/utdelete.c63
-rw-r--r--drivers/acpi/utilities/uteval.c36
-rw-r--r--drivers/acpi/utilities/utglobal.c133
-rw-r--r--drivers/acpi/utilities/utinit.c36
-rw-r--r--drivers/acpi/utilities/utmath.c2
-rw-r--r--drivers/acpi/utilities/utmisc.c187
-rw-r--r--drivers/acpi/utilities/utobject.c68
-rw-r--r--drivers/acpi/utilities/utxface.c61
-rw-r--r--drivers/acpi/video.c15
-rw-r--r--drivers/base/sys.c1
-rw-r--r--drivers/bluetooth/bluecard_cs.c7
-rw-r--r--drivers/bluetooth/bt3c_cs.c7
-rw-r--r--drivers/bluetooth/btuart_cs.c7
-rw-r--r--drivers/bluetooth/dtl1_cs.c7
-rw-r--r--drivers/bluetooth/hci_vhci.c2
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/drm/Kconfig7
-rw-r--r--drivers/char/drm/Makefile5
-rw-r--r--drivers/char/drm/ati_pcigart.c2
-rw-r--r--drivers/char/drm/drm.h2
-rw-r--r--drivers/char/drm/drmP.h30
-rw-r--r--drivers/char/drm/drm_auth.c4
-rw-r--r--drivers/char/drm/drm_bufs.c12
-rw-r--r--drivers/char/drm/drm_context.c4
-rw-r--r--drivers/char/drm/drm_drv.c9
-rw-r--r--drivers/char/drm/drm_fops.c14
-rw-r--r--drivers/char/drm/drm_irq.c2
-rw-r--r--drivers/char/drm/drm_lock.c12
-rw-r--r--drivers/char/drm/drm_memory.c13
-rw-r--r--drivers/char/drm/drm_pciids.h7
-rw-r--r--drivers/char/drm/drm_proc.c2
-rw-r--r--drivers/char/drm/drm_stub.c92
-rw-r--r--drivers/char/drm/drm_vm.c10
-rw-r--r--drivers/char/drm/i810_dma.c24
-rw-r--r--drivers/char/drm/i810_drv.h1
-rw-r--r--drivers/char/drm/i830_dma.c20
-rw-r--r--drivers/char/drm/i830_drv.c2
-rw-r--r--drivers/char/drm/i830_drv.h2
-rw-r--r--drivers/char/drm/i830_irq.c5
-rw-r--r--drivers/char/drm/i915_dma.c60
-rw-r--r--drivers/char/drm/i915_drv.c5
-rw-r--r--drivers/char/drm/i915_drv.h14
-rw-r--r--drivers/char/drm/i915_ioc32.c221
-rw-r--r--drivers/char/drm/i915_irq.c4
-rw-r--r--drivers/char/drm/mga_drv.c3
-rw-r--r--drivers/char/drm/mga_drv.h2
-rw-r--r--drivers/char/drm/mga_ioc32.c167
-rw-r--r--drivers/char/drm/r128_drv.c3
-rw-r--r--drivers/char/drm/r128_drv.h3
-rw-r--r--drivers/char/drm/r128_ioc32.c219
-rw-r--r--drivers/char/drm/r128_state.c2
-rw-r--r--drivers/char/drm/via_3d_reg.h1651
-rw-r--r--drivers/char/drm/via_dma.c741
-rw-r--r--drivers/char/drm/via_drm.h243
-rw-r--r--drivers/char/drm/via_drv.c126
-rw-r--r--drivers/char/drm/via_drv.h118
-rw-r--r--drivers/char/drm/via_ds.c280
-rw-r--r--drivers/char/drm/via_ds.h104
-rw-r--r--drivers/char/drm/via_irq.c339
-rw-r--r--drivers/char/drm/via_map.c110
-rw-r--r--drivers/char/drm/via_mm.c358
-rw-r--r--drivers/char/drm/via_mm.h40
-rw-r--r--drivers/char/drm/via_verifier.c1061
-rw-r--r--drivers/char/drm/via_verifier.h61
-rw-r--r--drivers/char/drm/via_video.c97
-rw-r--r--drivers/char/hvc_console.c429
-rw-r--r--drivers/char/hvc_vio.c152
-rw-r--r--drivers/char/hvsi.c8
-rw-r--r--drivers/char/hw_random.c2
-rw-r--r--drivers/char/n_tty.c33
-rw-r--r--drivers/char/pcmcia/synclink_cs.c7
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/sysrq.c2
-rw-r--r--drivers/char/tb0219.c19
-rw-r--r--drivers/char/watchdog/i8xx_tco.c2
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/crypto/padlock-aes.c153
-rw-r--r--drivers/crypto/padlock.h22
-rw-r--r--drivers/hwmon/Kconfig420
-rw-r--r--drivers/hwmon/Makefile44
-rw-r--r--drivers/hwmon/adm1021.c (renamed from drivers/i2c/chips/adm1021.c)0
-rw-r--r--drivers/hwmon/adm1025.c (renamed from drivers/i2c/chips/adm1025.c)0
-rw-r--r--drivers/hwmon/adm1026.c (renamed from drivers/i2c/chips/adm1026.c)0
-rw-r--r--drivers/hwmon/adm1031.c (renamed from drivers/i2c/chips/adm1031.c)0
-rw-r--r--drivers/hwmon/adm9240.c (renamed from drivers/i2c/chips/adm9240.c)0
-rw-r--r--drivers/hwmon/asb100.c (renamed from drivers/i2c/chips/asb100.c)0
-rw-r--r--drivers/hwmon/atxp1.c (renamed from drivers/i2c/chips/atxp1.c)0
-rw-r--r--drivers/hwmon/ds1621.c (renamed from drivers/i2c/chips/ds1621.c)0
-rw-r--r--drivers/hwmon/fscher.c (renamed from drivers/i2c/chips/fscher.c)0
-rw-r--r--drivers/hwmon/fscpos.c (renamed from drivers/i2c/chips/fscpos.c)0
-rw-r--r--drivers/hwmon/gl518sm.c (renamed from drivers/i2c/chips/gl518sm.c)0
-rw-r--r--drivers/hwmon/gl520sm.c (renamed from drivers/i2c/chips/gl520sm.c)0
-rw-r--r--drivers/hwmon/it87.c (renamed from drivers/i2c/chips/it87.c)0
-rw-r--r--drivers/hwmon/lm63.c (renamed from drivers/i2c/chips/lm63.c)0
-rw-r--r--drivers/hwmon/lm75.c (renamed from drivers/i2c/chips/lm75.c)0
-rw-r--r--drivers/hwmon/lm75.h (renamed from drivers/i2c/chips/lm75.h)0
-rw-r--r--drivers/hwmon/lm77.c (renamed from drivers/i2c/chips/lm77.c)0
-rw-r--r--drivers/hwmon/lm78.c (renamed from drivers/i2c/chips/lm78.c)0
-rw-r--r--drivers/hwmon/lm80.c (renamed from drivers/i2c/chips/lm80.c)0
-rw-r--r--drivers/hwmon/lm83.c (renamed from drivers/i2c/chips/lm83.c)0
-rw-r--r--drivers/hwmon/lm85.c (renamed from drivers/i2c/chips/lm85.c)0
-rw-r--r--drivers/hwmon/lm87.c (renamed from drivers/i2c/chips/lm87.c)0
-rw-r--r--drivers/hwmon/lm90.c (renamed from drivers/i2c/chips/lm90.c)0
-rw-r--r--drivers/hwmon/lm92.c (renamed from drivers/i2c/chips/lm92.c)0
-rw-r--r--drivers/hwmon/max1619.c (renamed from drivers/i2c/chips/max1619.c)0
-rw-r--r--drivers/hwmon/pc87360.c (renamed from drivers/i2c/chips/pc87360.c)0
-rw-r--r--drivers/hwmon/sis5595.c (renamed from drivers/i2c/chips/sis5595.c)0
-rw-r--r--drivers/hwmon/smsc47b397.c (renamed from drivers/i2c/chips/smsc47b397.c)0
-rw-r--r--drivers/hwmon/smsc47m1.c (renamed from drivers/i2c/chips/smsc47m1.c)0
-rw-r--r--drivers/hwmon/via686a.c (renamed from drivers/i2c/chips/via686a.c)12
-rw-r--r--drivers/hwmon/w83627ehf.c (renamed from drivers/i2c/chips/w83627ehf.c)0
-rw-r--r--drivers/hwmon/w83627hf.c (renamed from drivers/i2c/chips/w83627hf.c)0
-rw-r--r--drivers/hwmon/w83781d.c (renamed from drivers/i2c/chips/w83781d.c)0
-rw-r--r--drivers/hwmon/w83l785ts.c (renamed from drivers/i2c/chips/w83l785ts.c)0
-rw-r--r--drivers/i2c/algos/i2c-algo-ite.c8
-rw-r--r--drivers/i2c/busses/i2c-i801.c4
-rw-r--r--drivers/i2c/busses/i2c-keywest.c7
-rw-r--r--drivers/i2c/busses/i2c-piix4.c2
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c2
-rw-r--r--drivers/i2c/chips/Kconfig413
-rw-r--r--drivers/i2c/chips/Makefile38
-rw-r--r--drivers/i2c/chips/eeprom.c3
-rw-r--r--drivers/i2c/chips/m41t00.c2
-rw-r--r--drivers/i2c/chips/max6875.c6
-rw-r--r--drivers/i2c/chips/tps65010.c59
-rw-r--r--drivers/i2c/i2c-core.c17
-rw-r--r--drivers/ide/Makefile1
-rw-r--r--drivers/ide/ide-cd.c4
-rw-r--r--drivers/ide/ide-lib.c13
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/ide/pci/alim15x3.c10
-rw-r--r--drivers/ide/pci/amd74xx.c7
-rw-r--r--drivers/ide/pci/cs5530.c4
-rw-r--r--drivers/ide/pci/cy82c693.c8
-rw-r--r--drivers/ide/pci/it8172.c4
-rw-r--r--drivers/ide/pci/ns87415.c2
-rw-r--r--drivers/ide/pci/opti621.c2
-rw-r--r--drivers/ide/pci/sc1200.c2
-rw-r--r--drivers/ide/pci/sl82c105.c6
-rw-r--r--drivers/ide/pci/slc90e66.c2
-rw-r--r--drivers/ide/pci/triflex.c2
-rw-r--r--drivers/ide/pci/via82cxxx.c4
-rw-r--r--drivers/ide/ppc/pmac.c12
-rw-r--r--drivers/ide/setup-pci.c2
-rw-r--r--drivers/ieee1394/Kconfig12
-rw-r--r--drivers/ieee1394/csr.c3
-rw-r--r--drivers/ieee1394/csr1212.c37
-rw-r--r--drivers/ieee1394/dma.c2
-rw-r--r--drivers/ieee1394/eth1394.c6
-rw-r--r--drivers/ieee1394/ieee1394_core.c35
-rw-r--r--drivers/ieee1394/ieee1394_core.h4
-rw-r--r--drivers/ieee1394/iso.c27
-rw-r--r--drivers/ieee1394/iso.h13
-rw-r--r--drivers/ieee1394/nodemgr.c2
-rw-r--r--drivers/ieee1394/ohci1394.c40
-rw-r--r--drivers/ieee1394/pcilynx.c4
-rw-r--r--drivers/ieee1394/raw1394.c7
-rw-r--r--drivers/ieee1394/sbp2.c135
-rw-r--r--drivers/infiniband/Kconfig10
-rw-r--r--drivers/infiniband/core/Makefile5
-rw-r--r--drivers/infiniband/core/uverbs.h132
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c1006
-rw-r--r--drivers/infiniband/core/uverbs_main.c698
-rw-r--r--drivers/infiniband/core/uverbs_mem.c221
-rw-r--r--drivers/infiniband/core/verbs.c32
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c76
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c141
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_pd.c24
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c330
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c215
-rw-r--r--drivers/infiniband/hw/mthca/mthca_user.h81
-rw-r--r--drivers/infiniband/include/ib_user_verbs.h389
-rw-r--r--drivers/infiniband/include/ib_verbs.h124
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c7
-rw-r--r--drivers/isdn/hisax/avma1_cs.c7
-rw-r--r--drivers/isdn/hisax/elsa_cs.c7
-rw-r--r--drivers/isdn/hisax/isdnl1.c3
-rw-r--r--drivers/isdn/hisax/isdnl2.c17
-rw-r--r--drivers/isdn/hisax/isdnl3.c2
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c7
-rw-r--r--drivers/isdn/hisax/teles_cs.c7
-rw-r--r--drivers/isdn/i4l/isdn_tty.c4
-rw-r--r--drivers/isdn/icn/icn.c4
-rw-r--r--drivers/macintosh/Makefile2
-rw-r--r--drivers/macintosh/macio_asic.c78
-rw-r--r--drivers/macintosh/macio_sysfs.c50
-rw-r--r--drivers/macintosh/mediabay.c7
-rw-r--r--drivers/macintosh/therm_pm72.c9
-rw-r--r--drivers/macintosh/therm_windtunnel.c6
-rw-r--r--drivers/md/dm-mpath.c68
-rw-r--r--drivers/md/dm-raid1.c1
-rw-r--r--drivers/md/dm-snap.c6
-rw-r--r--drivers/md/dm-table.c1
-rw-r--r--drivers/md/dm.c27
-rw-r--r--drivers/media/common/ir-common.c255
-rw-r--r--drivers/media/common/saa7146_core.c13
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig14
-rw-r--r--drivers/media/dvb/b2c2/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c122
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h548
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c2
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c34
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h458
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h458
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c2644
-rw-r--r--drivers/media/dvb/bt8xx/dst.c233
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c349
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c4
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c19
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c44
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h22
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig34
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c10
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c295
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h30
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c62
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c73
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c76
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c96
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h42
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c14
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c182
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h26
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c49
-rw-r--r--drivers/media/dvb/frontends/Kconfig13
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/cx22702.c29
-rw-r--r--drivers/media/dvb/frontends/cx22702.h5
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c85
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h6
-rw-r--r--drivers/media/dvb/frontends/l64781.c9
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.c609
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.h49
-rw-r--r--drivers/media/dvb/frontends/lgdt3302_priv.h72
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c800
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h41
-rw-r--r--drivers/media/dvb/frontends/stv0297.c8
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c235
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h31
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c1
-rw-r--r--drivers/media/dvb/pluto2/Kconfig16
-rw-r--r--drivers/media/dvb/pluto2/Makefile3
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c809
-rw-r--r--drivers/media/dvb/ttpci/Kconfig9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c251
-rw-r--r--drivers/media/dvb/ttpci/av7110.h7
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c220
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.h4
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c395
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h12
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c12
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c21
-rw-r--r--drivers/media/dvb/ttpci/budget.c99
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig1
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c52
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c11
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c14
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/bt832.c12
-rw-r--r--drivers/media/video/bttv-cards.c110
-rw-r--r--drivers/media/video/bttv-driver.c19
-rw-r--r--drivers/media/video/bttv-i2c.c26
-rw-r--r--drivers/media/video/bttv-risc.c9
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c5
-rw-r--r--drivers/media/video/cx88/cx88-cards.c65
-rw-r--r--drivers/media/video/cx88/cx88-core.c59
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c93
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c32
-rw-r--r--drivers/media/video/cx88/cx88-input.c384
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c33
-rw-r--r--drivers/media/video/cx88/cx88-reg.h11
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c76
-rw-r--r--drivers/media/video/cx88/cx88-video.c358
-rw-r--r--drivers/media/video/cx88/cx88.h20
-rw-r--r--drivers/media/video/ir-kbd-i2c.c51
-rw-r--r--drivers/media/video/msp3400.c25
-rw-r--r--drivers/media/video/mt20xx.c16
-rw-r--r--drivers/media/video/mxb.c7
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c2096
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c74
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c423
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c45
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c48
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c19
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c121
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c12
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c54
-rw-r--r--drivers/media/video/saa7134/saa7134.h21
-rw-r--r--drivers/media/video/tda7432.c13
-rw-r--r--drivers/media/video/tda8290.c13
-rw-r--r--drivers/media/video/tda9875.c13
-rw-r--r--drivers/media/video/tda9887.c9
-rw-r--r--drivers/media/video/tea5767.c158
-rw-r--r--drivers/media/video/tuner-3036.c2
-rw-r--r--drivers/media/video/tuner-core.c707
-rw-r--r--drivers/media/video/tuner-simple.c85
-rw-r--r--drivers/media/video/tvaudio.c5
-rw-r--r--drivers/media/video/tveeprom.c9
-rw-r--r--drivers/message/fusion/mptbase.c14
-rw-r--r--drivers/message/fusion/mptscsih.h2
-rw-r--r--drivers/message/i2o/config-osm.c2
-rw-r--r--drivers/misc/Kconfig5
-rw-r--r--drivers/mmc/mmci.c9
-rw-r--r--drivers/mmc/wbsd.c80
-rw-r--r--drivers/mmc/wbsd.h9
-rw-r--r--drivers/mtd/chips/Kconfig29
-rw-r--r--drivers/mtd/chips/amd_flash.c14
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c580
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c497
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c4
-rw-r--r--drivers/mtd/chips/jedec_probe.c28
-rw-r--r--drivers/mtd/cmdlinepart.c8
-rw-r--r--drivers/mtd/devices/block2mtd.c20
-rw-r--r--drivers/mtd/devices/ms02-nv.c8
-rw-r--r--drivers/mtd/devices/mtdram.c265
-rw-r--r--drivers/mtd/devices/phram.c34
-rw-r--r--drivers/mtd/devices/slram.c23
-rw-r--r--drivers/mtd/ftl.c5
-rw-r--r--drivers/mtd/maps/Kconfig117
-rw-r--r--drivers/mtd/maps/Makefile11
-rw-r--r--drivers/mtd/maps/alchemy-flash.c192
-rw-r--r--drivers/mtd/maps/amd76xrom.c4
-rw-r--r--drivers/mtd/maps/bast-flash.c13
-rw-r--r--drivers/mtd/maps/db1550-flash.c187
-rw-r--r--drivers/mtd/maps/db1x00-flash.c226
-rw-r--r--drivers/mtd/maps/elan-104nc.c228
-rw-r--r--drivers/mtd/maps/ichxrom.c6
-rw-r--r--drivers/mtd/maps/ixp2000.c7
-rw-r--r--drivers/mtd/maps/mainstone-flash.c178
-rw-r--r--drivers/mtd/maps/map_funcs.c11
-rw-r--r--drivers/mtd/maps/omap_nor.c179
-rw-r--r--drivers/mtd/maps/pb1550-flash.c203
-rw-r--r--drivers/mtd/maps/pb1xxx-flash.c178
-rw-r--r--drivers/mtd/maps/pci.c4
-rw-r--r--drivers/mtd/maps/pcmciamtd.c7
-rw-r--r--drivers/mtd/maps/plat-ram.c278
-rw-r--r--drivers/mtd/maps/scb2_flash.c4
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c33
-rw-r--r--drivers/mtd/mtdchar.c176
-rw-r--r--drivers/mtd/mtdcore.c6
-rw-r--r--drivers/mtd/mtdpart.c28
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/diskonchip.c96
-rw-r--r--drivers/mtd/nand/nand_base.c299
-rw-r--r--drivers/mtd/nand/nand_bbt.c114
-rw-r--r--drivers/mtd/nand/nand_ids.c18
-rw-r--r--drivers/mtd/nand/nandsim.c41
-rw-r--r--drivers/mtd/nand/rtc_from4.c140
-rw-r--r--drivers/mtd/nand/s3c2410.c297
-rw-r--r--[-rwxr-xr-x]drivers/mtd/nand/sharpsl.c4
-rw-r--r--drivers/mtd/nand/tx4925ndfmc.c416
-rw-r--r--drivers/mtd/nand/tx4938ndfmc.c406
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/appletalk/Kconfig27
-rw-r--r--drivers/net/b44.c3
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/hamradio/scc.c5
-rw-r--r--drivers/net/mace.c6
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/ne2k-pci.c3
-rw-r--r--drivers/net/pcmcia/3c574_cs.c7
-rw-r--r--drivers/net/pcmcia/3c589_cs.c7
-rw-r--r--drivers/net/pcmcia/axnet_cs.c7
-rw-r--r--drivers/net/pcmcia/com20020_cs.c7
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c7
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c7
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c7
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c7
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c6
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c7
-rw-r--r--drivers/net/plip.c2
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_generic.c12
-rw-r--r--drivers/net/ppp_synctty.c2
-rw-r--r--drivers/net/shaper.c42
-rw-r--r--drivers/net/skge.c4
-rw-r--r--drivers/net/skge.h1
-rw-r--r--drivers/net/sungem.c4
-rw-r--r--drivers/net/sungem_phy.c69
-rw-r--r--drivers/net/sungem_phy.h3
-rw-r--r--drivers/net/tg3.c69
-rw-r--r--drivers/net/tg3.h10
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/typhoon.c6
-rw-r--r--drivers/net/wan/farsync.c3
-rw-r--r--drivers/net/wan/hdlc_cisco.c3
-rw-r--r--drivers/net/wan/hdlc_ppp.c3
-rw-r--r--drivers/net/wan/hdlc_raw.c3
-rw-r--r--drivers/net/wireless/airo.c4
-rw-r--r--drivers/net/wireless/airo_cs.c7
-rw-r--r--drivers/net/wireless/airport.c8
-rw-r--r--drivers/net/wireless/atmel_cs.c17
-rw-r--r--drivers/net/wireless/netwave_cs.c7
-rw-r--r--drivers/net/wireless/orinoco_cs.c7
-rw-r--r--drivers/net/wireless/ray_cs.c7
-rw-r--r--drivers/net/wireless/wavelan_cs.c7
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h1
-rw-r--r--drivers/net/wireless/wl3501_cs.c19
-rw-r--r--drivers/parport/parport_cs.c7
-rw-r--r--drivers/parport/parport_pc.c2
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/hotplug.c2
-rw-r--r--drivers/pci/hotplug/Kconfig5
-rw-r--r--drivers/pci/hotplug/Makefile1
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c611
-rw-r--r--drivers/pci/pci-acpi.c110
-rw-r--r--drivers/pci/pci-driver.c198
-rw-r--r--drivers/pci/pci.c28
-rw-r--r--drivers/pci/pci.h4
-rw-r--r--drivers/pci/pcie/portdrv.h5
-rw-r--r--drivers/pci/pcie/portdrv_core.c14
-rw-r--r--drivers/pci/pcie/portdrv_pci.c79
-rw-r--r--drivers/pci/probe.c24
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/pci/search.c1
-rw-r--r--drivers/pci/setup-bus.c3
-rw-r--r--drivers/pcmcia/Kconfig17
-rw-r--r--drivers/pcmcia/au1000_generic.h1
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/cardbus.c1
-rw-r--r--drivers/pcmcia/cs.c16
-rw-r--r--drivers/pcmcia/cs_internal.h16
-rw-r--r--drivers/pcmcia/ds.c99
-rw-r--r--drivers/pcmcia/hd64465_ss.c1
-rw-r--r--drivers/pcmcia/i82365.c9
-rw-r--r--drivers/pcmcia/m32r_cfc.c1
-rw-r--r--drivers/pcmcia/m32r_pcc.c1
-rw-r--r--drivers/pcmcia/pcmcia_compat.c48
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c27
-rw-r--r--drivers/pcmcia/pcmcia_resource.c143
-rw-r--r--drivers/pcmcia/sa1100_generic.c1
-rw-r--r--drivers/pcmcia/soc_common.h1
-rw-r--r--drivers/pcmcia/socket_sysfs.c1
-rw-r--r--drivers/pcmcia/tcic.c1
-rw-r--r--drivers/pcmcia/ti113x.h4
-rw-r--r--drivers/pcmcia/yenta_socket.c174
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c15
-rw-r--r--drivers/pnp/pnpbios/rsparser.c2
-rw-r--r--drivers/pnp/resource.c2
-rw-r--r--drivers/s390/net/claw.c4
-rw-r--r--drivers/s390/net/ctctty.c6
-rw-r--r--drivers/s390/net/qeth_main.c2
-rw-r--r--drivers/sbus/char/bpp.c20
-rw-r--r--drivers/scsi/aacraid/commctrl.c2
-rw-r--r--drivers/scsi/mac53c94.c7
-rw-r--r--drivers/scsi/mesh.c8
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c7
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c7
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c17
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c4
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c5
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c32
-rw-r--r--drivers/serial/pmac_zilog.c9
-rw-r--r--drivers/serial/s3c2410.c5
-rw-r--r--drivers/serial/serial_core.c14
-rw-r--r--drivers/serial/serial_cs.c7
-rw-r--r--drivers/telephony/ixj_pcmcia.c7
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/atm/speedtch.c63
-rw-r--r--drivers/usb/class/cdc-acm.c31
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/hcd-pci.c1
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hcd.h8
-rw-r--r--drivers/usb/core/hub.c40
-rw-r--r--drivers/usb/core/message.c2
-rw-r--r--drivers/usb/core/sysfs.c2
-rw-r--r--drivers/usb/core/urb.c4
-rw-r--r--drivers/usb/core/usb.c5
-rw-r--r--drivers/usb/gadget/dummy_hcd.c9
-rw-r--r--drivers/usb/gadget/ether.c22
-rw-r--r--drivers/usb/gadget/goku_udc.c6
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c6
-rw-r--r--drivers/usb/gadget/net2280.c8
-rw-r--r--drivers/usb/gadget/omap_udc.c9
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c6
-rw-r--r--drivers/usb/gadget/zero.c8
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-q.c2
-rw-r--r--drivers/usb/host/ehci-sched.c19
-rw-r--r--drivers/usb/host/hc_crisv10.c10
-rw-r--r--drivers/usb/host/isp116x-hcd.c20
-rw-r--r--drivers/usb/host/ohci-hcd.c6
-rw-r--r--drivers/usb/host/ohci-hub.c3
-rw-r--r--drivers/usb/host/ohci-mem.c4
-rw-r--r--drivers/usb/host/ohci-omap.c53
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/host/sl811_cs.c7
-rw-r--r--drivers/usb/host/uhci-q.c2
-rw-r--r--drivers/usb/input/Kconfig13
-rw-r--r--drivers/usb/input/Makefile1
-rw-r--r--drivers/usb/input/hid-core.c24
-rw-r--r--drivers/usb/input/keyspan_remote.c633
-rw-r--r--drivers/usb/media/Makefile2
-rw-r--r--drivers/usb/media/sn9c102.h2
-rw-r--r--drivers/usb/media/sn9c102_core.c2
-rw-r--r--drivers/usb/media/sn9c102_ov7630.c394
-rw-r--r--drivers/usb/media/sn9c102_sensor.h16
-rw-r--r--drivers/usb/media/sn9c102_tas5110c1b.c21
-rw-r--r--drivers/usb/media/sn9c102_tas5130d1b.c27
-rw-r--r--drivers/usb/misc/Kconfig10
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/ldusb.c794
-rw-r--r--drivers/usb/mon/mon_text.c48
-rw-r--r--drivers/usb/net/kaweth.c4
-rw-r--r--drivers/usb/net/usbnet.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.c756
-rw-r--r--drivers/usb/storage/unusual_devs.h2
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/logo/Kconfig5
-rw-r--r--drivers/video/logo/Makefile1
-rw-r--r--drivers/video/logo/logo.c5
-rw-r--r--drivers/video/logo/logo_m32r_clut224.ppm1292
-rw-r--r--drivers/video/platinumfb.c6
-rw-r--r--drivers/video/s1d13xxxfb.c10
-rw-r--r--drivers/video/savage/savagefb_driver.c2
-rw-r--r--drivers/w1/w1.c5
659 files changed, 34124 insertions, 17179 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index aed4a9b97c1..cecab0acc3f 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -28,7 +28,7 @@ source "drivers/message/i2o/Kconfig"
source "drivers/macintosh/Kconfig"
-source "net/Kconfig"
+source "drivers/net/Kconfig"
source "drivers/isdn/Kconfig"
@@ -44,6 +44,8 @@ source "drivers/i2c/Kconfig"
source "drivers/w1/Kconfig"
+source "drivers/hwmon/Kconfig"
+
source "drivers/misc/Kconfig"
source "drivers/media/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 3167be54fed..126a851d565 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT) += input/
obj-$(CONFIG_I2O) += message/
obj-$(CONFIG_I2C) += i2c/
obj-$(CONFIG_W1) += w1/
+obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 86c52520ed3..986410e7b48 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -3,6 +3,7 @@
#
menu "ACPI (Advanced Configuration and Power Interface) Support"
+ depends on PM
depends on !X86_VISWS
depends on !IA64_HP_SIM
depends on IA64 || X86
@@ -48,7 +49,6 @@ config ACPI_BOOT
config ACPI_INTERPRETER
bool
- depends on !IA64_SGI_SN
default y
if ACPI_INTERPRETER
@@ -79,6 +79,14 @@ config ACPI_SLEEP_PROC_FS
depends on ACPI_SLEEP && PROC_FS
default y
+config ACPI_SLEEP_PROC_SLEEP
+ bool "/proc/acpi/sleep (deprecated)"
+ depends on ACPI_SLEEP_PROC_FS
+ default n
+ ---help---
+ Create /proc/acpi/sleep
+ Deprecated by /sys/power/state
+
config ACPI_AC
tristate "AC Adapter"
depends on X86
@@ -99,7 +107,6 @@ config ACPI_BATTERY
config ACPI_BUTTON
tristate "Button"
- depends on !IA64_SGI_SN
default m
help
This driver registers for events based on buttons, such as the
@@ -111,7 +118,6 @@ config ACPI_BUTTON
config ACPI_VIDEO
tristate "Video"
depends on EXPERIMENTAL
- depends on !IA64_SGI_SN
default m
help
This driver implement the ACPI Extensions For Display Adapters
@@ -122,9 +128,17 @@ config ACPI_VIDEO
Note that this is an ref. implementation only. It may or may not work
for your integrated video device.
+config ACPI_HOTKEY
+ tristate "Generic Hotkey"
+ depends on ACPI_INTERPRETER
+ depends on EXPERIMENTAL
+ depends on !IA64_SGI_SN
+ default m
+ help
+ ACPI generic hotkey
+
config ACPI_FAN
tristate "Fan"
- depends on !IA64_SGI_SN
default m
help
This driver adds support for ACPI fan devices, allowing user-mode
@@ -132,7 +146,6 @@ config ACPI_FAN
config ACPI_PROCESSOR
tristate "Processor"
- depends on !IA64_SGI_SN
default m
help
This driver installs ACPI as the idle handler for Linux, and uses
@@ -142,7 +155,6 @@ config ACPI_PROCESSOR
config ACPI_HOTPLUG_CPU
bool "Processor Hotplug (EXPERIMENTAL)"
depends on ACPI_PROCESSOR && HOTPLUG_CPU && EXPERIMENTAL
- depends on !IA64_SGI_SN
select ACPI_CONTAINER
default n
---help---
@@ -262,7 +274,6 @@ config ACPI_BLACKLIST_YEAR
config ACPI_DEBUG
bool "Debug Statements"
- depends on !IA64_SGI_SN
default n
help
The ACPI driver can optionally report errors with a great deal
@@ -271,7 +282,6 @@ config ACPI_DEBUG
config ACPI_BUS
bool
- depends on !IA64_SGI_SN
default y
config ACPI_EC
@@ -285,17 +295,14 @@ config ACPI_EC
config ACPI_POWER
bool
- depends on !IA64_SGI_SN
default y
config ACPI_PCI
bool
- depends on !IA64_SGI_SN
default PCI
config ACPI_SYSTEM
bool
- depends on !IA64_SGI_SN
default y
help
This driver will enable your system to shut down using ACPI, and
@@ -327,8 +334,13 @@ config ACPI_CONTAINER
depends on EXPERIMENTAL
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
---help---
- This is the ACPI generic container driver which supports
- ACPI0004, PNP0A05 and PNP0A06 devices
+ This allows _physical_ insertion and removal of CPUs and memory.
+ This can be useful, for example, on NUMA machines that support
+ ACPI based physical hotplug of nodes, or non-NUMA machines that
+ support physical cpu/memory hot-plug.
+
+ If one selects "m", this driver can be loaded with
+ "modprobe acpi_container".
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 65c92e20566..ad67e8f61e6 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,13 +36,14 @@ processor-objs += processor_perflib.o
endif
obj-$(CONFIG_ACPI_BUS) += sleep/
-obj-$(CONFIG_ACPI_BUS) += bus.o
+obj-$(CONFIG_ACPI_BUS) += bus.o glue.o
obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_EC) += ec.o
obj-$(CONFIG_ACPI_FAN) += fan.o
-obj-$(CONFIG_ACPI_VIDEO) += video.o
+obj-$(CONFIG_ACPI_VIDEO) += video.o
+obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
obj-$(CONFIG_ACPI_PCI) += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_POWER) += power.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index a75cb565cae..a560b1e2da7 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1204,6 +1204,10 @@ static int __init asus_acpi_init(void)
if (acpi_disabled)
return -ENODEV;
+ if (!acpi_specific_hotkey_enabled){
+ printk(KERN_ERR "Using generic hotkey driver\n");
+ return -ENODEV;
+ }
asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
if (!asus_proc_dir) {
printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 4edff173857..d77c2307883 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -212,6 +212,12 @@ acpi_bus_set_power (
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
return_VALUE(-ENODEV);
}
+ /*
+ * Get device's current power state if it's unknown
+ * This means device power state isn't initialized or previous setting failed
+ */
+ if (device->power.state == ACPI_STATE_UNKNOWN)
+ acpi_bus_get_power(device->handle, &device->power.state);
if (state == device->power.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
return_VALUE(0);
@@ -231,7 +237,7 @@ acpi_bus_set_power (
* On transitions to a high-powered state we first apply power (via
* power resources) then evalute _PSx. Conversly for transitions to
* a lower-powered state.
- */
+ */
if (state < device->power.state) {
if (device->power.flags.power_resources) {
result = acpi_power_transition(device, state);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ec4430e3053..0f45d45f05a 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -26,9 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -36,9 +33,6 @@
#define ACPI_BUTTON_COMPONENT 0x00080000
#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver"
#define ACPI_BUTTON_CLASS "button"
-#define ACPI_BUTTON_FILE_INFO "info"
-#define ACPI_BUTTON_FILE_STATE "state"
-#define ACPI_BUTTON_TYPE_UNKNOWN 0x00
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
@@ -70,8 +64,6 @@ MODULE_LICENSE("GPL");
static int acpi_button_add (struct acpi_device *device);
static int acpi_button_remove (struct acpi_device *device, int type);
-static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
-static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
static struct acpi_driver acpi_button_driver = {
.name = ACPI_BUTTON_DRIVER_NAME,
@@ -90,187 +82,6 @@ struct acpi_button {
unsigned long pushed;
};
-static struct file_operations acpi_button_info_fops = {
- .open = acpi_button_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static struct file_operations acpi_button_state_fops = {
- .open = acpi_button_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-/* --------------------------------------------------------------------------
- FS Interface (/proc)
- -------------------------------------------------------------------------- */
-
-static struct proc_dir_entry *acpi_button_dir;
-
-static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_button *button = (struct acpi_button *) seq->private;
-
- ACPI_FUNCTION_TRACE("acpi_button_info_seq_show");
-
- if (!button || !button->device)
- return_VALUE(0);
-
- seq_printf(seq, "type: %s\n",
- acpi_device_name(button->device));
-
- return_VALUE(0);
-}
-
-static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
-}
-
-static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_button *button = (struct acpi_button *) seq->private;
- acpi_status status;
- unsigned long state;
-
- ACPI_FUNCTION_TRACE("acpi_button_state_seq_show");
-
- if (!button || !button->device)
- return_VALUE(0);
-
- status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state);
- if (ACPI_FAILURE(status)) {
- seq_printf(seq, "state: unsupported\n");
- }
- else{
- seq_printf(seq, "state: %s\n", (state ? "open" : "closed"));
- }
-
- return_VALUE(0);
-}
-
-static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
-}
-
-static int
-acpi_button_add_fs (
- struct acpi_device *device)
-{
- struct proc_dir_entry *entry = NULL;
- struct acpi_button *button = NULL;
-
- ACPI_FUNCTION_TRACE("acpi_button_add_fs");
-
- if (!device || !acpi_driver_data(device))
- return_VALUE(-EINVAL);
-
- button = acpi_driver_data(device);
-
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWER:
- case ACPI_BUTTON_TYPE_POWERF:
- entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
- acpi_button_dir);
- break;
- case ACPI_BUTTON_TYPE_SLEEP:
- case ACPI_BUTTON_TYPE_SLEEPF:
- entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
- acpi_button_dir);
- break;
- case ACPI_BUTTON_TYPE_LID:
- entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
- acpi_button_dir);
- break;
- }
-
- if (!entry)
- return_VALUE(-ENODEV);
- entry->owner = THIS_MODULE;
-
- acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
- if (!acpi_device_dir(device))
- return_VALUE(-ENODEV);
- acpi_device_dir(device)->owner = THIS_MODULE;
-
- /* 'info' [R] */
- entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
- S_IRUGO, acpi_device_dir(device));
- if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BUTTON_FILE_INFO));
- else {
- entry->proc_fops = &acpi_button_info_fops;
- entry->data = acpi_driver_data(device);
- entry->owner = THIS_MODULE;
- }
-
- /* show lid state [R] */
- if (button->type == ACPI_BUTTON_TYPE_LID) {
- entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
- S_IRUGO, acpi_device_dir(device));
- if (!entry)
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Unable to create '%s' fs entry\n",
- ACPI_BUTTON_FILE_INFO));
- else {
- entry->proc_fops = &acpi_button_state_fops;
- entry->data = acpi_driver_data(device);
- entry->owner = THIS_MODULE;
- }
- }
-
- return_VALUE(0);
-}
-
-
-static int
-acpi_button_remove_fs (
- struct acpi_device *device)
-{
- struct acpi_button *button = NULL;
-
- ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
-
- button = acpi_driver_data(device);
- if (acpi_device_dir(device)) {
- if (button->type == ACPI_BUTTON_TYPE_LID)
- remove_proc_entry(ACPI_BUTTON_FILE_STATE,
- acpi_device_dir(device));
- remove_proc_entry(ACPI_BUTTON_FILE_INFO,
- acpi_device_dir(device));
-
- remove_proc_entry(acpi_device_bid(device),
- acpi_device_dir(device)->parent);
-
-
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWER:
- case ACPI_BUTTON_TYPE_POWERF:
- remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER,
- acpi_button_dir);
- break;
- case ACPI_BUTTON_TYPE_SLEEP:
- case ACPI_BUTTON_TYPE_SLEEPF:
- remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP,
- acpi_button_dir);
- break;
- case ACPI_BUTTON_TYPE_LID:
- remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID,
- acpi_button_dir);
- break;
- }
- acpi_device_dir(device) = NULL;
- }
-
- return_VALUE(0);
-}
-
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
@@ -310,8 +121,7 @@ acpi_button_notify_fixed (
ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
- if (!button)
- return_ACPI_STATUS(AE_BAD_PARAMETER);
+ BUG_ON(!button);
acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
@@ -327,10 +137,6 @@ acpi_button_add (
acpi_status status = AE_OK;
struct acpi_button *button = NULL;
- static struct acpi_device *power_button;
- static struct acpi_device *sleep_button;
- static struct acpi_device *lid_button;
-
ACPI_FUNCTION_TRACE("acpi_button_add");
if (!device)
@@ -391,42 +197,6 @@ acpi_button_add (
goto end;
}
- /*
- * Ensure only one button of each type is used.
- */
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWER:
- case ACPI_BUTTON_TYPE_POWERF:
- if (!power_button)
- power_button = device;
- else {
- kfree(button);
- return_VALUE(-ENODEV);
- }
- break;
- case ACPI_BUTTON_TYPE_SLEEP:
- case ACPI_BUTTON_TYPE_SLEEPF:
- if (!sleep_button)
- sleep_button = device;
- else {
- kfree(button);
- return_VALUE(-ENODEV);
- }
- break;
- case ACPI_BUTTON_TYPE_LID:
- if (!lid_button)
- lid_button = device;
- else {
- kfree(button);
- return_VALUE(-ENODEV);
- }
- break;
- }
-
- result = acpi_button_add_fs(device);
- if (result)
- goto end;
-
switch (button->type) {
case ACPI_BUTTON_TYPE_POWERF:
status = acpi_install_fixed_event_handler (
@@ -470,7 +240,6 @@ acpi_button_add (
end:
if (result) {
- acpi_button_remove_fs(device);
kfree(button);
}
@@ -511,8 +280,6 @@ acpi_button_remove (struct acpi_device *device, int type)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error removing notify handler\n"));
- acpi_button_remove_fs(device);
-
kfree(button);
return_VALUE(0);
@@ -526,21 +293,14 @@ acpi_button_init (void)
ACPI_FUNCTION_TRACE("acpi_button_init");
- acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
- if (!acpi_button_dir)
- return_VALUE(-ENODEV);
- acpi_button_dir->owner = THIS_MODULE;
-
result = acpi_bus_register_driver(&acpi_button_driver);
if (result < 0) {
- remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
return_VALUE(-ENODEV);
}
return_VALUE(0);
}
-
static void __exit
acpi_button_exit (void)
{
@@ -548,11 +308,8 @@ acpi_button_exit (void)
acpi_bus_unregister_driver(&acpi_button_driver);
- remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
-
return_VOID;
}
-
module_init(acpi_button_init);
module_exit(acpi_button_exit);
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index 2779211be75..84193983d6b 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -53,13 +53,20 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsfield")
+/* Local prototypes */
+
+static acpi_status
+acpi_ds_get_field_names (
+ struct acpi_create_field_info *info,
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *arg);
+
/*******************************************************************************
*
* FUNCTION: acpi_ds_create_buffer_field
*
- * PARAMETERS: Opcode - The opcode to be executed
- * Operands - List of operands for the opcode
+ * PARAMETERS: Op - Current parse op (create_xXField)
* walk_state - Current state
*
* RETURN: Status
@@ -70,7 +77,7 @@
* create_word_field_op,
* create_dword_field_op,
* create_qword_field_op,
- * create_field_op (all of which define fields in buffers)
+ * create_field_op (all of which define a field in a buffer)
*
******************************************************************************/
@@ -119,7 +126,8 @@ acpi_ds_create_buffer_field (
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
}
else {
- flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
+ flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND;
}
/*
@@ -134,16 +142,16 @@ acpi_ds_create_buffer_field (
}
}
- /* We could put the returned object (Node) on the object stack for later, but
- * for now, we will put it in the "op" object that the parser uses, so we
- * can get it again at the end of this scope
+ /* We could put the returned object (Node) on the object stack for later,
+ * but for now, we will put it in the "op" object that the parser uses,
+ * so we can get it again at the end of this scope
*/
op->common.node = node;
/*
- * If there is no object attached to the node, this node was just created and
- * we need to create the field object. Otherwise, this was a lookup of an
- * existing node and we don't want to create the field object again.
+ * If there is no object attached to the node, this node was just created
+ * and we need to create the field object. Otherwise, this was a lookup
+ * of an existing node and we don't want to create the field object again.
*/
obj_desc = acpi_ns_get_attached_object (node);
if (obj_desc) {
@@ -205,7 +213,7 @@ cleanup:
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_get_field_names (
struct acpi_create_field_info *info,
struct acpi_walk_state *walk_state,
@@ -238,7 +246,8 @@ acpi_ds_get_field_names (
+ (acpi_integer) arg->common.value.size;
if (position > ACPI_UINT32_MAX) {
- ACPI_REPORT_ERROR (("Bit offset within field too large (> 0xFFFFFFFF)\n"));
+ ACPI_REPORT_ERROR ((
+ "Bit offset within field too large (> 0xFFFFFFFF)\n"));
return_ACPI_STATUS (AE_SUPPORT);
}
@@ -250,12 +259,15 @@ acpi_ds_get_field_names (
/*
* Get a new access_type and access_attribute -- to be used for all
- * field units that follow, until field end or another access_as keyword.
+ * field units that follow, until field end or another access_as
+ * keyword.
*
- * In field_flags, preserve the flag bits other than the ACCESS_TYPE bits
+ * In field_flags, preserve the flag bits other than the
+ * ACCESS_TYPE bits
*/
- info->field_flags = (u8) ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
- ((u8) ((u32) arg->common.value.integer >> 8)));
+ info->field_flags = (u8)
+ ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+ ((u8) ((u32) arg->common.value.integer >> 8)));
info->attribute = (u8) (arg->common.value.integer);
break;
@@ -267,7 +279,8 @@ acpi_ds_get_field_names (
status = acpi_ns_lookup (walk_state->scope_info,
(char *) &arg->named.name,
- info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ info->field_type, ACPI_IMODE_EXECUTE,
+ ACPI_NS_DONT_OPEN_SCOPE,
walk_state, &info->field_node);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
@@ -295,8 +308,9 @@ acpi_ds_get_field_names (
+ (acpi_integer) arg->common.value.size;
if (position > ACPI_UINT32_MAX) {
- ACPI_REPORT_ERROR (("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
- (char *) &info->field_node->name));
+ ACPI_REPORT_ERROR ((
+ "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
+ (char *) &info->field_node->name));
return_ACPI_STATUS (AE_SUPPORT);
}
@@ -306,7 +320,8 @@ acpi_ds_get_field_names (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Invalid opcode in field list: %X\n",
arg->common.aml_opcode));
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
}
@@ -435,7 +450,8 @@ acpi_ds_init_field_objects (
status = acpi_ns_lookup (walk_state->scope_info,
(char *) &arg->named.name,
type, ACPI_IMODE_LOAD_PASS1,
- ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND,
walk_state, &node);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index b4d264dbbf6..d7790db5017 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -49,12 +49,21 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsinit")
+/* Local prototypes */
+
+static acpi_status
+acpi_ds_init_one_object (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+
/*******************************************************************************
*
* FUNCTION: acpi_ds_init_one_object
*
- * PARAMETERS: obj_handle - Node
+ * PARAMETERS: obj_handle - Node for the object
* Level - Current nesting level
* Context - Points to a init info struct
* return_value - Not used
@@ -70,7 +79,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_init_one_object (
acpi_handle obj_handle,
u32 level,
@@ -105,7 +114,8 @@ acpi_ds_init_one_object (
status = acpi_ds_initialize_region (obj_handle);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Region %p [%4.4s] - Init failure, %s\n",
obj_handle, acpi_ut_get_node_name (obj_handle),
acpi_format_exception (status)));
}
@@ -118,8 +128,10 @@ acpi_ds_init_one_object (
info->method_count++;
- /* Print a dot for each method unless we are going to print the entire pathname */
-
+ /*
+ * Print a dot for each method unless we are going to print
+ * the entire pathname
+ */
if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
}
@@ -140,7 +152,8 @@ acpi_ds_init_one_object (
*/
status = acpi_ds_parse_method (obj_handle);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Method %p [%4.4s] - parse failure, %s\n",
obj_handle, acpi_ut_get_node_name (obj_handle),
acpi_format_exception (status)));
@@ -154,7 +167,8 @@ acpi_ds_init_one_object (
* for every execution since there isn't much overhead
*/
acpi_ns_delete_namespace_subtree (obj_handle);
- acpi_ns_delete_namespace_by_owner (((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
+ acpi_ns_delete_namespace_by_owner (
+ ((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
break;
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 9f0456cb9bb..9fc3f4c033e 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -153,12 +153,11 @@ acpi_ds_parse_method (
/*
* Parse the method, first pass
*
- * The first pass load is where newly declared named objects are
- * added into the namespace. Actual evaluation of
- * the named objects (what would be called a "second
- * pass") happens during the actual execution of the
- * method so that operands to the named objects can
- * take on dynamic run-time values.
+ * The first pass load is where newly declared named objects are added into
+ * the namespace. Actual evaluation of the named objects (what would be
+ * called a "second pass") happens during the actual execution of the
+ * method so that operands to the named objects can take on dynamic
+ * run-time values.
*/
status = acpi_ps_parse_aml (walk_state);
if (ACPI_FAILURE (status)) {
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index f31d095f983..f7998306f75 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -52,6 +52,29 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsmthdat")
+/* Local prototypes */
+
+static void
+acpi_ds_method_data_delete_value (
+ u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state);
+
+static acpi_status
+acpi_ds_method_data_set_value (
+ u16 opcode,
+ u32 index,
+ union acpi_operand_object *object,
+ struct acpi_walk_state *walk_state);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_object_type
+acpi_ds_method_data_get_type (
+ u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state);
+#endif
+
/*******************************************************************************
*
@@ -62,8 +85,8 @@
* RETURN: Status
*
* DESCRIPTION: Initialize the data structures that hold the method's arguments
- * and locals. The data struct is an array of NTEs for each.
- * This allows ref_of and de_ref_of to work properly for these
+ * and locals. The data struct is an array of namespace nodes for
+ * each - this allows ref_of and de_ref_of to work properly for these
* special data types.
*
* NOTES: walk_state fields are initialized to zero by the
@@ -92,7 +115,8 @@ acpi_ds_method_data_init (
walk_state->arguments[i].name.integer |= (i << 24);
walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED;
walk_state->arguments[i].type = ACPI_TYPE_ANY;
- walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
+ walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST |
+ ANOBJ_METHOD_ARG;
}
/* Init the method locals */
@@ -104,7 +128,8 @@ acpi_ds_method_data_init (
walk_state->local_variables[i].name.integer |= (i << 24);
walk_state->local_variables[i].descriptor = ACPI_DESC_TYPE_NAMED;
walk_state->local_variables[i].type = ACPI_TYPE_ANY;
- walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
+ walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST |
+ ANOBJ_METHOD_LOCAL;
}
return_VOID;
@@ -198,15 +223,18 @@ acpi_ds_method_data_init_args (
return_ACPI_STATUS (AE_OK);
}
- /* Copy passed parameters into the new method stack frame */
+ /* Copy passed parameters into the new method stack frame */
- while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
+ while ((index < ACPI_METHOD_NUM_ARGS) &&
+ (index < max_param_count) &&
+ params[index]) {
/*
* A valid parameter.
* Store the argument in the method/walk descriptor.
* Do not copy the arg in order to implement call by reference
*/
- status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state);
+ status = acpi_ds_method_data_set_value (AML_ARG_OP, index,
+ params[index], walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -224,11 +252,13 @@ acpi_ds_method_data_init_args (
* FUNCTION: acpi_ds_method_data_get_node
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
- * Index - which local_var or argument whose type
- * to get
+ * Index - Which Local or Arg whose type to get
* walk_state - Current walk state object
+ * Node - Where the node is returned.
*
- * RETURN: Get the Node associated with a local or arg.
+ * RETURN: Status and node
+ *
+ * DESCRIPTION: Get the Node associated with a local or arg.
*
******************************************************************************/
@@ -249,7 +279,8 @@ acpi_ds_method_data_get_node (
case AML_LOCAL_OP:
if (index > ACPI_METHOD_MAX_LOCAL) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Local index %d is invalid (max %d)\n",
index, ACPI_METHOD_MAX_LOCAL));
return_ACPI_STATUS (AE_AML_INVALID_INDEX);
}
@@ -262,7 +293,8 @@ acpi_ds_method_data_get_node (
case AML_ARG_OP:
if (index > ACPI_METHOD_MAX_ARG) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Arg index %d is invalid (max %d)\n",
index, ACPI_METHOD_MAX_ARG));
return_ACPI_STATUS (AE_AML_INVALID_INDEX);
}
@@ -286,7 +318,7 @@ acpi_ds_method_data_get_node (
* FUNCTION: acpi_ds_method_data_set_value
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
- * Index - which local_var or argument to get
+ * Index - Which Local or Arg to get
* Object - Object to be inserted into the stack entry
* walk_state - Current walk state object
*
@@ -297,7 +329,7 @@ acpi_ds_method_data_get_node (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_method_data_set_value (
u16 opcode,
u32 index,
@@ -340,68 +372,16 @@ acpi_ds_method_data_set_value (
/*******************************************************************************
*
- * FUNCTION: acpi_ds_method_data_get_type
- *
- * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
- * Index - which local_var or argument whose type
- * to get
- * walk_state - Current walk state object
- *
- * RETURN: Data type of current value of the selected Arg or Local
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_object_type
-acpi_ds_method_data_get_type (
- u16 opcode,
- u32 index,
- struct acpi_walk_state *walk_state)
-{
- acpi_status status;
- struct acpi_namespace_node *node;
- union acpi_operand_object *object;
-
-
- ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
-
-
- /* Get the namespace node for the arg/local */
-
- status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
- if (ACPI_FAILURE (status)) {
- return_VALUE ((ACPI_TYPE_NOT_FOUND));
- }
-
- /* Get the object */
-
- object = acpi_ns_get_attached_object (node);
- if (!object) {
- /* Uninitialized local/arg, return TYPE_ANY */
-
- return_VALUE (ACPI_TYPE_ANY);
- }
-
- /* Get the object type */
-
- return_VALUE (ACPI_GET_OBJECT_TYPE (object));
-}
-#endif /* ACPI_FUTURE_USAGE */
-
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ds_method_data_get_value
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
* Index - which local_var or argument to get
* walk_state - Current walk state object
- * *dest_desc - Ptr to Descriptor into which selected Arg
- * or Local value should be copied
+ * dest_desc - Where Arg or Local value is returned
*
* RETURN: Status
*
- * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
- * at the current top of the method stack.
+ * DESCRIPTION: Retrieve value of selected Arg or Local for this method
* Used only in acpi_ex_resolve_to_value().
*
******************************************************************************/
@@ -467,14 +447,16 @@ acpi_ds_method_data_get_value (
else switch (opcode) {
case AML_ARG_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Uninitialized Arg[%d] at node %p\n",
index, node));
return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
case AML_LOCAL_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Uninitialized Local[%d] at node %p\n",
index, node));
return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
@@ -506,12 +488,12 @@ acpi_ds_method_data_get_value (
*
* RETURN: None
*
- * DESCRIPTION: Delete the entry at Opcode:Index on the method stack. Inserts
+ * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
* a null into the stack slot after the object is deleted.
*
******************************************************************************/
-void
+static void
acpi_ds_method_data_delete_value (
u16 opcode,
u32 index,
@@ -562,7 +544,7 @@ acpi_ds_method_data_delete_value (
* FUNCTION: acpi_ds_store_object_to_local
*
* PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
- * Index - which local_var or argument to set
+ * Index - Which Local or Arg to set
* obj_desc - Value to be stored
* walk_state - Current walk state
*
@@ -651,19 +633,20 @@ acpi_ds_store_object_to_local (
*/
if (opcode == AML_ARG_OP) {
/*
- * Make sure that the object is the correct type. This may be overkill, but
- * it is here because references were NS nodes in the past. Now they are
- * operand objects of type Reference.
+ * Make sure that the object is the correct type. This may be
+ * overkill, butit is here because references were NS nodes in
+ * the past. Now they are operand objects of type Reference.
*/
if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
- ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
- acpi_ut_get_descriptor_name (current_obj_desc)));
+ ACPI_REPORT_ERROR ((
+ "Invalid descriptor type while storing to method arg: [%s]\n",
+ acpi_ut_get_descriptor_name (current_obj_desc)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/*
- * If we have a valid reference object that came from ref_of(), do the
- * indirect store
+ * If we have a valid reference object that came from ref_of(),
+ * do the indirect store
*/
if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
@@ -713,3 +696,55 @@ acpi_ds_store_object_to_local (
}
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_method_data_get_type
+ *
+ * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
+ * Index - Which Local or Arg whose type to get
+ * walk_state - Current walk state object
+ *
+ * RETURN: Data type of current value of the selected Arg or Local
+ *
+ * DESCRIPTION: Get the type of the object stored in the Local or Arg
+ *
+ ******************************************************************************/
+
+acpi_object_type
+acpi_ds_method_data_get_type (
+ u16 opcode,
+ u32 index,
+ struct acpi_walk_state *walk_state)
+{
+ acpi_status status;
+ struct acpi_namespace_node *node;
+ union acpi_operand_object *object;
+
+
+ ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
+
+
+ /* Get the namespace node for the arg/local */
+
+ status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+ if (ACPI_FAILURE (status)) {
+ return_VALUE ((ACPI_TYPE_NOT_FOUND));
+ }
+
+ /* Get the object */
+
+ object = acpi_ns_get_attached_object (node);
+ if (!object) {
+ /* Uninitialized local/arg, return TYPE_ANY */
+
+ return_VALUE (ACPI_TYPE_ANY);
+ }
+
+ /* Get the object type */
+
+ return_VALUE (ACPI_GET_OBJECT_TYPE (object));
+}
+#endif
+
+
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index eb8af4785bc..bfbae4e4c66 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -52,9 +52,15 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsobject")
+static acpi_status
+acpi_ds_build_internal_object (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ union acpi_operand_object **obj_desc_ptr);
+
#ifndef ACPI_NO_METHOD_EXECUTION
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_build_internal_object
*
@@ -67,9 +73,9 @@
* DESCRIPTION: Translate a parser Op object to the equivalent namespace object
* Simple objects are any objects other than a package object!
*
- ****************************************************************************/
+ ******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_build_internal_object (
struct acpi_walk_state *walk_state,
union acpi_parse_object *op,
@@ -90,9 +96,11 @@ acpi_ds_build_internal_object (
* Otherwise, go ahead and look it up now
*/
if (!op->common.node) {
- status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string,
+ status = acpi_ns_lookup (walk_state->scope_info,
+ op->common.value.string,
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL,
(struct acpi_namespace_node **) &(op->common.node));
if (ACPI_FAILURE (status)) {
@@ -104,12 +112,14 @@ acpi_ds_build_internal_object (
/* Create and init the internal ACPI object */
- obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
+ obj_desc = acpi_ut_create_internal_object (
+ (acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
if (!obj_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
- status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
+ status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode,
+ &obj_desc);
if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
@@ -120,7 +130,7 @@ acpi_ds_build_internal_object (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_build_internal_buffer_obj
*
@@ -134,7 +144,7 @@ acpi_ds_build_internal_object (
* DESCRIPTION: Translate a parser Op package object to the equivalent
* namespace object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_build_internal_buffer_obj (
@@ -229,7 +239,7 @@ acpi_ds_build_internal_buffer_obj (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_build_internal_package_obj
*
@@ -243,7 +253,7 @@ acpi_ds_build_internal_buffer_obj (
* DESCRIPTION: Translate a parser Op package object to the equivalent
* namespace object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_build_internal_package_obj (
@@ -331,11 +341,12 @@ acpi_ds_build_internal_package_obj (
if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
/* Object (package or buffer) is already built */
- obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
+ obj_desc->package.elements[i] =
+ ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
}
else {
status = acpi_ds_build_internal_object (walk_state, arg,
- &obj_desc->package.elements[i]);
+ &obj_desc->package.elements[i]);
}
i++;
@@ -348,7 +359,7 @@ acpi_ds_build_internal_package_obj (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_create_node
*
@@ -360,7 +371,7 @@ acpi_ds_build_internal_package_obj (
*
* DESCRIPTION: Create the object to be associated with a namespace node
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_create_node (
@@ -392,7 +403,8 @@ acpi_ds_create_node (
/* Build an internal object for the argument(s) */
- status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc);
+ status = acpi_ds_build_internal_object (walk_state, op->common.value.arg,
+ &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -414,7 +426,7 @@ acpi_ds_create_node (
#endif /* ACPI_NO_METHOD_EXECUTION */
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_init_object_from_op
*
@@ -429,7 +441,7 @@ acpi_ds_create_node (
* associated arguments. The namespace object is a more compact
* representation of the Op and its arguments.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_init_object_from_op (
@@ -462,7 +474,8 @@ acpi_ds_init_object_from_op (
/*
* Defer evaluation of Buffer term_arg operand
*/
- obj_desc->buffer.node = (struct acpi_namespace_node *) walk_state->operands[0];
+ obj_desc->buffer.node = (struct acpi_namespace_node *)
+ walk_state->operands[0];
obj_desc->buffer.aml_start = op->named.data;
obj_desc->buffer.aml_length = op->named.length;
break;
@@ -473,7 +486,8 @@ acpi_ds_init_object_from_op (
/*
* Defer evaluation of Package term_arg operand
*/
- obj_desc->package.node = (struct acpi_namespace_node *) walk_state->operands[0];
+ obj_desc->package.node = (struct acpi_namespace_node *)
+ walk_state->operands[0];
obj_desc->package.aml_start = op->named.data;
obj_desc->package.aml_length = op->named.length;
break;
@@ -486,9 +500,10 @@ acpi_ds_init_object_from_op (
/*
* Resolve AML Constants here - AND ONLY HERE!
* All constants are integers.
- * We mark the integer with a flag that indicates that it started life
- * as a constant -- so that stores to constants will perform as expected (noop).
- * (zero_op is used as a placeholder for optional target operands.)
+ * We mark the integer with a flag that indicates that it started
+ * life as a constant -- so that stores to constants will perform
+ * as expected (noop). zero_op is used as a placeholder for optional
+ * target operands.
*/
obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
@@ -521,7 +536,8 @@ acpi_ds_init_object_from_op (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unknown constant opcode %X\n", opcode));
status = AE_AML_OPERAND_TYPE;
break;
}
@@ -535,7 +551,8 @@ acpi_ds_init_object_from_op (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n",
+ op_info->type));
status = AE_AML_OPERAND_TYPE;
break;
}
@@ -570,8 +587,10 @@ acpi_ds_init_object_from_op (
obj_desc->reference.offset = opcode - AML_LOCAL_OP;
#ifndef ACPI_NO_METHOD_EXECUTION
- status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
- walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+ status = acpi_ds_method_data_get_node (AML_LOCAL_OP,
+ obj_desc->reference.offset,
+ walk_state,
+ (struct acpi_namespace_node **) &obj_desc->reference.object);
#endif
break;
@@ -584,8 +603,10 @@ acpi_ds_init_object_from_op (
obj_desc->reference.offset = opcode - AML_ARG_OP;
#ifndef ACPI_NO_METHOD_EXECUTION
- status = acpi_ds_method_data_get_node (AML_ARG_OP, obj_desc->reference.offset,
- walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+ status = acpi_ds_method_data_get_node (AML_ARG_OP,
+ obj_desc->reference.offset,
+ walk_state,
+ (struct acpi_namespace_node **) &obj_desc->reference.object);
#endif
break;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 5c987a0e7b7..ba13bca28be 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -54,12 +54,31 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsopcode")
+/* Local prototypes */
-/*****************************************************************************
+static acpi_status
+acpi_ds_execute_arguments (
+ struct acpi_namespace_node *node,
+ struct acpi_namespace_node *scope_node,
+ u32 aml_length,
+ u8 *aml_start);
+
+static acpi_status
+acpi_ds_init_buffer_field (
+ u16 aml_opcode,
+ union acpi_operand_object *obj_desc,
+ union acpi_operand_object *buffer_desc,
+ union acpi_operand_object *offset_desc,
+ union acpi_operand_object *length_desc,
+ union acpi_operand_object *result_desc);
+
+
+/*******************************************************************************
*
* FUNCTION: acpi_ds_execute_arguments
*
- * PARAMETERS: Node - Parent NS node
+ * PARAMETERS: Node - Object NS node
+ * scope_node - Parent NS node
* aml_length - Length of executable AML
* aml_start - Pointer to the AML
*
@@ -67,9 +86,9 @@
*
* DESCRIPTION: Late (deferred) execution of region or field arguments
*
- ****************************************************************************/
+ ******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_execute_arguments (
struct acpi_namespace_node *node,
struct acpi_namespace_node *scope_node,
@@ -162,7 +181,7 @@ acpi_ds_execute_arguments (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_get_buffer_field_arguments
*
@@ -173,7 +192,7 @@ acpi_ds_execute_arguments (
* DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
* evaluation of these field attributes.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_get_buffer_field_arguments (
@@ -208,7 +227,7 @@ acpi_ds_get_buffer_field_arguments (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_get_buffer_arguments
*
@@ -219,7 +238,7 @@ acpi_ds_get_buffer_field_arguments (
* DESCRIPTION: Get Buffer length and initializer byte list. This implements
* the late evaluation of these attributes.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_get_buffer_arguments (
@@ -255,7 +274,7 @@ acpi_ds_get_buffer_arguments (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_get_package_arguments
*
@@ -266,7 +285,7 @@ acpi_ds_get_buffer_arguments (
* DESCRIPTION: Get Package length and initializer byte list. This implements
* the late evaluation of these attributes.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_get_package_arguments (
@@ -353,17 +372,17 @@ acpi_ds_get_region_arguments (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_initialize_region
*
- * PARAMETERS: Op - A valid region Op object
+ * PARAMETERS: obj_handle - Region namespace node
*
* RETURN: Status
*
* DESCRIPTION: Front end to ev_initialize_region
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_initialize_region (
@@ -382,7 +401,7 @@ acpi_ds_initialize_region (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_init_buffer_field
*
@@ -390,16 +409,16 @@ acpi_ds_initialize_region (
* obj_desc - buffer_field object
* buffer_desc - Host Buffer
* offset_desc - Offset into buffer
- * Length - Length of field (CREATE_FIELD_OP only)
- * Result - Where to store the result
+ * length_desc - Length of field (CREATE_FIELD_OP only)
+ * result_desc - Where to store the result
*
* RETURN: Status
*
* DESCRIPTION: Perform actual initialization of a buffer field
*
- ****************************************************************************/
+ ******************************************************************************/
-acpi_status
+static acpi_status
acpi_ds_init_buffer_field (
u16 aml_opcode,
union acpi_operand_object *obj_desc,
@@ -435,8 +454,10 @@ acpi_ds_init_buffer_field (
* after resolution in acpi_ex_resolve_operands().
*/
if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
- acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "(%s) destination not a NS Node [%s]\n",
+ acpi_ps_get_opcode_name (aml_opcode),
+ acpi_ut_get_descriptor_name (result_desc)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
@@ -452,9 +473,18 @@ acpi_ds_init_buffer_field (
/* Offset is in bits, count is in bits */
+ field_flags = AML_FIELD_ACCESS_BYTE;
bit_offset = offset;
bit_count = (u32) length_desc->integer.value;
- field_flags = AML_FIELD_ACCESS_BYTE;
+
+ /* Must have a valid (>0) bit count */
+
+ if (bit_count == 0) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Attempt to create_field of length 0\n"));
+ status = AE_AML_OPERAND_VALUE;
+ goto cleanup;
+ }
break;
case AML_CREATE_BIT_FIELD_OP:
@@ -527,7 +557,8 @@ acpi_ds_init_buffer_field (
/*
* Initialize areas of the field object that are common to all fields
- * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
+ * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
+ * UPDATE_RULE = 0 (UPDATE_PRESERVE)
*/
status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
bit_offset, bit_count);
@@ -539,8 +570,8 @@ acpi_ds_init_buffer_field (
/* Reference count for buffer_desc inherits obj_desc count */
- buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
- obj_desc->common.reference_count);
+ buffer_desc->common.reference_count = (u16)
+ (buffer_desc->common.reference_count + obj_desc->common.reference_count);
cleanup:
@@ -569,7 +600,7 @@ cleanup:
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_buffer_field_operands
*
@@ -581,7 +612,7 @@ cleanup:
* DESCRIPTION: Get buffer_field Buffer and Index
* Called from acpi_ds_exec_end_op during buffer_field parse tree walk
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_eval_buffer_field_operands (
@@ -656,7 +687,7 @@ acpi_ds_eval_buffer_field_operands (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_region_operands
*
@@ -668,7 +699,7 @@ acpi_ds_eval_buffer_field_operands (
* DESCRIPTION: Get region address and length
* Called from acpi_ds_exec_end_op during op_region parse tree walk
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_eval_region_operands (
@@ -686,7 +717,8 @@ acpi_ds_eval_region_operands (
/*
- * This is where we evaluate the address and length fields of the op_region declaration
+ * This is where we evaluate the address and length fields of the
+ * op_region declaration
*/
node = op->common.node;
@@ -707,7 +739,8 @@ acpi_ds_eval_region_operands (
/* Resolve the length and address operands to numbers */
- status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
+ status = acpi_ex_resolve_operands (op->common.aml_opcode,
+ ACPI_WALK_OPERANDS, walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -736,7 +769,8 @@ acpi_ds_eval_region_operands (
*/
operand_desc = walk_state->operands[walk_state->num_operands - 2];
- obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
+ obj_desc->region.address = (acpi_physical_address)
+ operand_desc->integer.value;
acpi_ut_remove_reference (operand_desc);
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
@@ -752,7 +786,7 @@ acpi_ds_eval_region_operands (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ds_eval_data_object_operands
*
@@ -765,7 +799,7 @@ acpi_ds_eval_region_operands (
* DESCRIPTION: Get the operands and complete the following data object types:
* Buffer, Package.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ds_eval_data_object_operands (
@@ -830,7 +864,7 @@ acpi_ds_eval_data_object_operands (
if (ACPI_SUCCESS (status)) {
/*
- * Return the object in the walk_state, unless the parent is a package --
+ * Return the object in the walk_state, unless the parent is a package -
* in this case, the return object will be stored in the parse tree
* for the package.
*/
@@ -988,7 +1022,8 @@ acpi_ds_exec_end_control_op (
status = AE_CTRL_PENDING;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[WHILE_OP] termination! Op=%p\n",op));
/* Pop this control state and free it */
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 462c5d83e74..9613349ac31 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -100,7 +100,6 @@ acpi_ds_clear_implicit_return (
#ifndef ACPI_NO_METHOD_EXECUTION
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_do_implicit_return
@@ -205,7 +204,7 @@ acpi_ds_is_result_used (
* NOTE: this is optional because the ASL language does not actually
* support this behavior.
*/
- acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+ (void) acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
/*
* Now determine if the parent will use the result
@@ -219,8 +218,9 @@ acpi_ds_is_result_used (
(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
/* No parent, the return value cannot possibly be used */
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "At Method level, result of [%s] not used\n",
+ acpi_ps_get_opcode_name (op->common.aml_opcode)));
return_VALUE (FALSE);
}
@@ -228,7 +228,8 @@ acpi_ds_is_result_used (
parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
if (parent_info->class == AML_CLASS_UNKNOWN) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unknown parent opcode. Op=%p\n", op));
return_VALUE (FALSE);
}
@@ -309,17 +310,19 @@ acpi_ds_is_result_used (
result_used:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] used by Parent [%s] Op=%p\n",
+ acpi_ps_get_opcode_name (op->common.aml_opcode),
+ acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
return_VALUE (TRUE);
result_not_used:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
- acpi_ps_get_opcode_name (op->common.aml_opcode),
- acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] not used by Parent [%s] Op=%p\n",
+ acpi_ps_get_opcode_name (op->common.aml_opcode),
+ acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
return_VALUE (FALSE);
}
@@ -522,7 +525,8 @@ acpi_ds_create_operand (
if ((walk_state->deferred_node) &&
(walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
(arg_index != 0)) {
- obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
+ obj_desc = ACPI_CAST_PTR (
+ union acpi_operand_object, walk_state->deferred_node);
status = AE_OK;
}
else /* All other opcodes */ {
@@ -565,7 +569,8 @@ acpi_ds_create_operand (
* indicate this to the interpreter, set the
* object to the root
*/
- obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
+ obj_desc = ACPI_CAST_PTR (
+ union acpi_operand_object, acpi_gbl_root_node);
status = AE_OK;
}
else {
@@ -612,7 +617,8 @@ acpi_ds_create_operand (
*/
opcode = AML_ZERO_OP; /* Has no arguments! */
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Null namepath: Arg=%p\n", arg));
}
else {
opcode = arg->common.aml_opcode;
@@ -642,7 +648,8 @@ acpi_ds_create_operand (
* Only error is underflow, and this indicates
* a missing or null operand!
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Missing or null operand, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
@@ -657,8 +664,8 @@ acpi_ds_create_operand (
/* Initialize the new object */
- status = acpi_ds_init_object_from_op (walk_state, arg,
- opcode, &obj_desc);
+ status = acpi_ds_init_object_from_op (
+ walk_state, arg, opcode, &obj_desc);
if (ACPI_FAILURE (status)) {
acpi_ut_delete_object_desc (obj_desc);
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 2071a0d2bbb..10f71318e23 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -73,11 +73,13 @@ static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = {
acpi_ex_opcode_3A_1T_1R,
acpi_ex_opcode_6A_0T_1R};
+
/*****************************************************************************
*
* FUNCTION: acpi_ds_get_predicate_value
*
* PARAMETERS: walk_state - Current state of the parse tree walk
+ * result_obj - if non-zero, pop result from result stack
*
* RETURN: Status
*
@@ -124,7 +126,8 @@ acpi_ds_get_predicate_value (
}
if (!obj_desc) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate obj_desc=%p State=%p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "No predicate obj_desc=%p State=%p\n",
obj_desc, walk_state));
return_ACPI_STATUS (AE_AML_NO_OPERAND);
@@ -197,7 +200,7 @@ cleanup:
* FUNCTION: acpi_ds_exec_begin_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * out_op - Return op if a new one is created
+ * out_op - Where to return op if a new one is created
*
* RETURN: Status
*
@@ -233,7 +236,8 @@ acpi_ds_exec_begin_op (
walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "(%s) Popping scope for Op %p\n",
acpi_ut_get_type_name (walk_state->op_info->object_type), op));
status = acpi_ds_scope_stack_pop (walk_state);
@@ -297,11 +301,10 @@ acpi_ds_exec_begin_op (
if (walk_state->walk_type == ACPI_WALK_METHOD) {
/*
- * Found a named object declaration during method
- * execution; we must enter this object into the
- * namespace. The created object is temporary and
- * will be deleted upon completion of the execution
- * of this method.
+ * Found a named object declaration during method execution;
+ * we must enter this object into the namespace. The created
+ * object is temporary and will be deleted upon completion of
+ * the execution of this method.
*/
status = acpi_ds_load2_begin_op (walk_state, NULL);
}
@@ -338,8 +341,6 @@ acpi_ds_exec_begin_op (
* FUNCTION: acpi_ds_exec_end_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * Op - Op that has been just been completed in the
- * walk; Arguments have now been evaluated.
*
* RETURN: Status
*
@@ -389,7 +390,7 @@ acpi_ds_exec_end_op (
/* Decode the Opcode Class */
switch (op_class) {
- case AML_CLASS_ARGUMENT: /* constants, literals, etc. -- do nothing */
+ case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */
break;
@@ -417,12 +418,12 @@ acpi_ds_exec_end_op (
/* Resolve all operands */
status = acpi_ex_resolve_operands (walk_state->opcode,
- &(walk_state->operands [walk_state->num_operands -1]),
- walk_state);
+ &(walk_state->operands [walk_state->num_operands -1]),
+ walk_state);
if (ACPI_SUCCESS (status)) {
ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name (walk_state->opcode),
- walk_state->num_operands, "after ex_resolve_operands");
+ acpi_ps_get_opcode_name (walk_state->opcode),
+ walk_state->num_operands, "after ex_resolve_operands");
}
}
@@ -506,7 +507,8 @@ acpi_ds_exec_end_op (
if ((op->asl.parent) &&
((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
(op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Method Reference in a Package, Op=%p\n", op));
op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
return_ACPI_STATUS (AE_OK);
@@ -583,13 +585,15 @@ acpi_ds_exec_end_op (
case AML_NAME_OP:
/*
- * Put the Node on the object stack (Contains the ACPI Name of
- * this object)
+ * Put the Node on the object stack (Contains the ACPI Name
+ * of this object)
*/
walk_state->operands[0] = (void *) op->common.parent->common.node;
walk_state->num_operands = 1;
- status = acpi_ds_create_node (walk_state, op->common.parent->common.node, op->common.parent);
+ status = acpi_ds_create_node (walk_state,
+ op->common.parent->common.node,
+ op->common.parent);
if (ACPI_FAILURE (status)) {
break;
}
@@ -600,7 +604,7 @@ acpi_ds_exec_end_op (
case AML_INT_EVAL_SUBTREE_OP:
status = acpi_ds_eval_data_object_operands (walk_state, op,
- acpi_ns_get_attached_object (op->common.parent->common.node));
+ acpi_ns_get_attached_object (op->common.parent->common.node));
break;
default:
@@ -609,7 +613,7 @@ acpi_ds_exec_end_op (
break;
}
- /* Done with this result state (Now that operand stack is built) */
+ /* Done with result state (Now that operand stack is built) */
status = acpi_ds_result_stack_pop (walk_state);
if (ACPI_FAILURE (status)) {
@@ -620,8 +624,7 @@ acpi_ds_exec_end_op (
* If a result object was returned from above, push it on the
* current result stack
*/
- if (ACPI_SUCCESS (status) &&
- walk_state->result_obj) {
+ if (walk_state->result_obj) {
status = acpi_ds_result_push (walk_state->result_obj, walk_state);
}
break;
@@ -654,7 +657,8 @@ acpi_ds_exec_end_op (
case AML_TYPE_UNDEFINED:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Undefined opcode type Op=%p\n", op));
return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
@@ -709,13 +713,14 @@ cleanup:
status = acpi_gbl_exception_handler (status,
walk_state->method_node->name.integer, walk_state->opcode,
walk_state->aml_offset, NULL);
- acpi_ex_enter_interpreter ();
+ (void) acpi_ex_enter_interpreter ();
}
if (walk_state->result_obj) {
/* Break to debugger to display result */
- ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state));
+ ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj,
+ walk_state));
/*
* Delete the result op if and only if:
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index 06d75867958..1ac197ccfc8 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -79,20 +79,23 @@ acpi_ds_init_callbacks (
switch (pass_number) {
case 1:
- walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_load1_begin_op;
walk_state->ascending_callback = acpi_ds_load1_end_op;
break;
case 2:
- walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_load2_begin_op;
walk_state->ascending_callback = acpi_ds_load2_end_op;
break;
case 3:
#ifndef ACPI_NO_METHOD_EXECUTION
- walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE;
+ walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
+ ACPI_PARSE_DELETE_TREE;
walk_state->descending_callback = acpi_ds_exec_begin_op;
walk_state->ascending_callback = acpi_ds_exec_end_op;
#endif
@@ -111,8 +114,7 @@ acpi_ds_init_callbacks (
* FUNCTION: acpi_ds_load1_begin_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * Op - Op that has been just been reached in the
- * walk; Arguments have not been evaluated yet.
+ * out_op - Where to return op if a new one is created
*
* RETURN: Status
*
@@ -146,7 +148,8 @@ acpi_ds_load1_begin_op (
#if 0
if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
(walk_state->op_info->class == AML_CLASS_CONTROL)) {
- acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", walk_state->op_info->name);
+ acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n",
+ walk_state->op_info->name);
*out_op = op;
return (AE_CTRL_SKIP);
}
@@ -191,7 +194,8 @@ acpi_ds_load1_begin_op (
*/
acpi_dm_add_to_external_list (path);
status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
- ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
+ walk_state, &(node));
}
#endif
if (ACPI_FAILURE (status)) {
@@ -224,10 +228,12 @@ acpi_ds_load1_begin_op (
* Name (DEB, 0)
* Scope (DEB) { ... }
*
- * Note: silently change the type here. On the second pass, we will report a warning
+ * Note: silently change the type here. On the second pass, we will report
+ * a warning
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
path, acpi_ut_get_type_name (node->type)));
node->type = ACPI_TYPE_ANY;
@@ -238,7 +244,8 @@ acpi_ds_load1_begin_op (
/* All other types are an error */
- ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
+ ACPI_REPORT_ERROR ((
+ "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
acpi_ut_get_type_name (node->type), path));
return (AE_AML_OPERAND_TYPE);
@@ -249,7 +256,8 @@ acpi_ds_load1_begin_op (
default:
/*
- * For all other named opcodes, we will enter the name into the namespace.
+ * For all other named opcodes, we will enter the name into
+ * the namespace.
*
* Setup the search flags.
* Since we are entering a name into the namespace, we do not want to
@@ -279,14 +287,16 @@ acpi_ds_load1_begin_op (
acpi_ut_get_type_name (object_type)));
}
else {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[%s] Both Find or Create allowed\n",
acpi_ut_get_type_name (object_type)));
}
/*
* Enter the named type into the internal namespace. We enter the name
- * as we go downward in the parse tree. Any necessary subobjects that involve
- * arguments to the opcode must be created as we go back up the parse tree later.
+ * as we go downward in the parse tree. Any necessary subobjects that
+ * involve arguments to the opcode must be created as we go back up the
+ * parse tree later.
*/
status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node));
@@ -335,8 +345,6 @@ acpi_ds_load1_begin_op (
* FUNCTION: acpi_ds_load1_end_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * Op - Op that has been just been completed in the
- * walk; Arguments have now been evaluated.
*
* RETURN: Status
*
@@ -383,7 +391,9 @@ acpi_ds_load1_end_op (
if (op->common.aml_opcode == AML_REGION_OP) {
status = acpi_ex_create_region (op->named.data, op->named.length,
- (acpi_adr_space_type) ((op->common.value.arg)->common.value.integer), walk_state);
+ (acpi_adr_space_type)
+ ((op->common.value.arg)->common.value.integer),
+ walk_state);
if (ACPI_FAILURE (status)) {
return (status);
}
@@ -394,7 +404,8 @@ acpi_ds_load1_end_op (
/* For Name opcode, get the object type from the argument */
if (op->common.value.arg) {
- object_type = (acpi_ps_get_opcode_info ((op->common.value.arg)->common.aml_opcode))->object_type;
+ object_type = (acpi_ps_get_opcode_info (
+ (op->common.value.arg)->common.aml_opcode))->object_type;
op->common.node->type = (u8) object_type;
}
}
@@ -448,8 +459,7 @@ acpi_ds_load1_end_op (
* FUNCTION: acpi_ds_load2_begin_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * Op - Op that has been just been reached in the
- * walk; Arguments have not been evaluated yet.
+ * out_op - Wher to return op if a new one is created
*
* RETURN: Status
*
@@ -478,14 +488,20 @@ acpi_ds_load2_begin_op (
if (op) {
/* We only care about Namespace opcodes here */
- if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
+ if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
+ (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
(!(walk_state->op_info->flags & AML_NAMED))) {
+ if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
+ (walk_state->op_info->class == AML_CLASS_CONTROL)) {
+ ACPI_REPORT_WARNING ((
+ "Encountered executable code at module level, [%s]\n",
+ acpi_ps_get_opcode_name (walk_state->opcode)));
+ }
return_ACPI_STATUS (AE_OK);
}
- /*
- * Get the name we are going to enter or lookup in the namespace
- */
+ /* Get the name we are going to enter or lookup in the namespace */
+
if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
/* For Namepath op, get the path string */
@@ -528,21 +544,25 @@ acpi_ds_load2_begin_op (
case AML_INT_NAMEPATH_OP:
/*
- * The name_path is an object reference to an existing object. Don't enter the
- * name into the namespace, but look it up for use later
+ * The name_path is an object reference to an existing object.
+ * Don't enter the name into the namespace, but look it up
+ * for use later.
*/
status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ walk_state, &(node));
break;
case AML_SCOPE_OP:
/*
- * The Path is an object reference to an existing object. Don't enter the
- * name into the namespace, but look it up for use later
+ * The Path is an object reference to an existing object.
+ * Don't enter the name into the namespace, but look it up
+ * for use later.
*/
status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+ ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ walk_state, &(node));
if (ACPI_FAILURE (status)) {
#ifdef _ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) {
@@ -582,7 +602,8 @@ acpi_ds_load2_begin_op (
* Scope (DEB) { ... }
*/
- ACPI_REPORT_WARNING (("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+ ACPI_REPORT_WARNING ((
+ "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
buffer_ptr, acpi_ut_get_type_name (node->type)));
node->type = ACPI_TYPE_ANY;
@@ -593,7 +614,8 @@ acpi_ds_load2_begin_op (
/* All other types are an error */
- ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s]\n",
+ ACPI_REPORT_ERROR ((
+ "Invalid type (%s) for target of Scope operator [%4.4s]\n",
acpi_ut_get_type_name (node->type), buffer_ptr));
return (AE_AML_OPERAND_TYPE);
@@ -621,8 +643,9 @@ acpi_ds_load2_begin_op (
/*
* Enter the named type into the internal namespace. We enter the name
- * as we go downward in the parse tree. Any necessary subobjects that involve
- * arguments to the opcode must be created as we go back up the parse tree later.
+ * as we go downward in the parse tree. Any necessary subobjects that
+ * involve arguments to the opcode must be created as we go back up the
+ * parse tree later.
*
* Note: Name may already exist if we are executing a deferred opcode.
*/
@@ -635,7 +658,8 @@ acpi_ds_load2_begin_op (
}
status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
- ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node));
+ ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH,
+ walk_state, &(node));
break;
}
@@ -678,8 +702,6 @@ acpi_ds_load2_begin_op (
* FUNCTION: acpi_ds_load2_end_op
*
* PARAMETERS: walk_state - Current state of the parse tree walk
- * Op - Op that has been just been completed in the
- * walk; Arguments have now been evaluated.
*
* RETURN: Status
*
@@ -738,7 +760,8 @@ acpi_ds_load2_end_op (
/* Pop the scope stack */
- if (acpi_ns_opens_scope (object_type) && (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
+ if (acpi_ns_opens_scope (object_type) &&
+ (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
acpi_ut_get_type_name (object_type), op));
@@ -803,7 +826,7 @@ acpi_ds_load2_end_op (
case AML_INDEX_FIELD_OP:
status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node,
- walk_state);
+ walk_state);
break;
case AML_BANK_FIELD_OP:
@@ -884,14 +907,16 @@ acpi_ds_load2_end_op (
#ifndef ACPI_NO_METHOD_EXECUTION
case AML_REGION_OP:
/*
- * The op_region is not fully parsed at this time. Only valid argument is the space_id.
- * (We must save the address of the AML of the address and length operands)
+ * The op_region is not fully parsed at this time. Only valid
+ * argument is the space_id. (We must save the address of the
+ * AML of the address and length operands)
*/
/*
* If we have a valid region, initialize it
* Namespace is NOT locked at this point.
*/
- status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node), FALSE);
+ status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node),
+ FALSE);
if (ACPI_FAILURE (status)) {
/*
* If AE_NOT_EXIST is returned, it is not fatal
@@ -942,15 +967,16 @@ acpi_ds_load2_end_op (
if (ACPI_SUCCESS (status)) {
/*
* Make sure that what we found is indeed a method
- * We didn't search for a method on purpose, to see if the name would resolve
+ * We didn't search for a method on purpose, to see if the name
+ * would resolve
*/
if (new_node->type != ACPI_TYPE_METHOD) {
status = AE_AML_OPERAND_TYPE;
}
- /* We could put the returned object (Node) on the object stack for later, but
- * for now, we will put it in the "op" object that the parser uses, so we
- * can get it again at the end of this scope
+ /* We could put the returned object (Node) on the object stack for
+ * later, but for now, we will put it in the "op" object that the
+ * parser uses, so we can get it again at the end of this scope
*/
op->common.node = new_node;
}
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index 65f456151e2..21f4548ff32 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -50,14 +50,13 @@
ACPI_MODULE_NAME ("dswscope")
-#define STACK_POP(head) head
-
-
/****************************************************************************
*
* FUNCTION: acpi_ds_scope_stack_clear
*
- * PARAMETERS: None
+ * PARAMETERS: walk_state - Current state
+ *
+ * RETURN: None
*
* DESCRIPTION: Pop (and free) everything on the scope stack except the
* root scope object (which remains at the stack top.)
@@ -80,7 +79,8 @@ acpi_ds_scope_stack_clear (
walk_state->scope_info = scope_info->scope.next;
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Popped object type (%s)\n", acpi_ut_get_type_name (scope_info->common.value)));
+ "Popped object type (%s)\n",
+ acpi_ut_get_type_name (scope_info->common.value)));
acpi_ut_delete_generic_state (scope_info);
}
}
@@ -90,8 +90,11 @@ acpi_ds_scope_stack_clear (
*
* FUNCTION: acpi_ds_scope_stack_push
*
- * PARAMETERS: *Node, - Name to be made current
- * Type, - Type of frame being pushed
+ * PARAMETERS: Node - Name to be made current
+ * Type - Type of frame being pushed
+ * walk_state - Current state
+ *
+ * RETURN: Status
*
* DESCRIPTION: Push the current scope on the scope stack, and make the
* passed Node current.
@@ -121,7 +124,8 @@ acpi_ds_scope_stack_push (
/* Make sure object type is valid */
if (!acpi_ut_valid_object_type (type)) {
- ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+ ACPI_REPORT_WARNING ((
+ "ds_scope_stack_push: Invalid object type: 0x%X\n", type));
}
/* Allocate a new scope object */
@@ -170,16 +174,11 @@ acpi_ds_scope_stack_push (
*
* FUNCTION: acpi_ds_scope_stack_pop
*
- * PARAMETERS: Type - The type of frame to be found
+ * PARAMETERS: walk_state - Current state
*
- * DESCRIPTION: Pop the scope stack until a frame of the requested type
- * is found.
+ * RETURN: Status
*
- * RETURN: Count of frames popped. If no frame of the requested type
- * was found, the count is returned as a negative number and
- * the scope stack is emptied (which sets the current scope
- * to the root). If the scope stack was empty at entry, the
- * function is a no-op and returns 0.
+ * DESCRIPTION: Pop the scope stack once.
*
***************************************************************************/
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index e555b3fbd5e..9cd3db652b3 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -50,67 +50,31 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dswstate")
+/* Local prototypes */
-#ifdef ACPI_FUTURE_USAGE
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ds_result_insert
- *
- * PARAMETERS: Object - Object to push
- * Index - Where to insert the object
- * walk_state - Current Walk state
- *
- * RETURN: Status
- *
- * DESCRIPTION: Insert an object onto this walk's result stack
- *
- ******************************************************************************/
-
+#ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_status
acpi_ds_result_insert (
void *object,
u32 index,
- struct acpi_walk_state *walk_state)
-{
- union acpi_generic_state *state;
-
+ struct acpi_walk_state *walk_state);
- ACPI_FUNCTION_NAME ("ds_result_insert");
-
-
- state = walk_state->results;
- if (!state) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
- walk_state));
- return (AE_NOT_EXIST);
- }
-
- if (index >= ACPI_OBJ_NUM_OPERANDS) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index out of range: %X Obj=%p State=%p Num=%X\n",
- index, object, walk_state, state->results.num_results));
- return (AE_BAD_PARAMETER);
- }
-
- if (!object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
- index, object, walk_state, state->results.num_results));
- return (AE_BAD_PARAMETER);
- }
-
- state->results.obj_desc [index] = object;
- state->results.num_results++;
+acpi_status
+acpi_ds_obj_stack_delete_all (
+ struct acpi_walk_state *walk_state);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
- object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
- walk_state, state->results.num_results, walk_state->current_result));
+acpi_status
+acpi_ds_obj_stack_pop_object (
+ union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state);
- return (AE_OK);
-}
+void *
+acpi_ds_obj_stack_get_value (
+ u32 index,
+ struct acpi_walk_state *walk_state);
+#endif
+#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
@@ -178,7 +142,6 @@ acpi_ds_result_remove (
#endif /* ACPI_FUTURE_USAGE */
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_result_pop
@@ -227,15 +190,18 @@ acpi_ds_result_pop (
*object = state->results.obj_desc [index -1];
state->results.obj_desc [index -1] = NULL;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
- *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Obj=%p [%s] Index=%X State=%p Num=%X\n",
+ *object,
+ (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
(u32) index -1, walk_state, state->results.num_results));
return (AE_OK);
}
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "No result objects! State=%p\n", walk_state));
return (AE_AML_NO_RETURN_VALUE);
}
@@ -274,7 +240,8 @@ acpi_ds_result_pop_from_bottom (
}
if (!state->results.num_results) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n",
+ walk_state));
return (AE_AML_NO_RETURN_VALUE);
}
@@ -293,7 +260,8 @@ acpi_ds_result_pop_from_bottom (
/* Check for a valid result object */
if (!*object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Null operand! State=%p #Ops=%X, Index=%X\n",
walk_state, state->results.num_results, (u32) index));
return (AE_AML_NO_RETURN_VALUE);
}
@@ -344,7 +312,8 @@ acpi_ds_result_push (
}
if (!object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Null Object! Obj=%p State=%p Num=%X\n",
object, walk_state, state->results.num_results));
return (AE_BAD_PARAMETER);
}
@@ -439,43 +408,6 @@ acpi_ds_result_stack_pop (
/*******************************************************************************
*
- * FUNCTION: acpi_ds_obj_stack_delete_all
- *
- * PARAMETERS: walk_state - Current Walk state
- *
- * RETURN: Status
- *
- * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
- * Should be used with great care, if at all!
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ds_obj_stack_delete_all (
- struct acpi_walk_state *walk_state)
-{
- u32 i;
-
-
- ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
-
-
- /* The stack size is configurable, but fixed */
-
- for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
- if (walk_state->operands[i]) {
- acpi_ut_remove_reference (walk_state->operands[i]);
- walk_state->operands[i] = NULL;
- }
- }
-
- return_ACPI_STATUS (AE_OK);
-}
-#endif /* ACPI_FUTURE_USAGE */
-
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ds_obj_stack_push
*
* PARAMETERS: Object - Object to push
@@ -517,67 +449,6 @@ acpi_ds_obj_stack_push (
}
-#if 0
-/*******************************************************************************
- *
- * FUNCTION: acpi_ds_obj_stack_pop_object
- *
- * PARAMETERS: pop_count - Number of objects/entries to pop
- * walk_state - Current Walk state
- *
- * RETURN: Status
- *
- * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
- * deleted by this routine.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_obj_stack_pop_object (
- union acpi_operand_object **object,
- struct acpi_walk_state *walk_state)
-{
- ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
-
-
- /* Check for stack underflow */
-
- if (walk_state->num_operands == 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Missing operand/stack empty! State=%p #Ops=%X\n",
- walk_state, walk_state->num_operands));
- *object = NULL;
- return (AE_AML_NO_OPERAND);
- }
-
- /* Pop the stack */
-
- walk_state->num_operands--;
-
- /* Check for a valid operand */
-
- if (!walk_state->operands [walk_state->num_operands]) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Null operand! State=%p #Ops=%X\n",
- walk_state, walk_state->num_operands));
- *object = NULL;
- return (AE_AML_NO_OPERAND);
- }
-
- /* Get operand and set stack entry to null */
-
- *object = walk_state->operands [walk_state->num_operands];
- walk_state->operands [walk_state->num_operands] = NULL;
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
- *object, acpi_ut_get_object_type_name (*object),
- walk_state, walk_state->num_operands));
-
- return (AE_OK);
-}
-#endif
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ds_obj_stack_pop
@@ -680,48 +551,6 @@ acpi_ds_obj_stack_pop_and_delete (
/*******************************************************************************
*
- * FUNCTION: acpi_ds_obj_stack_get_value
- *
- * PARAMETERS: Index - Stack index whose value is desired. Based
- * on the top of the stack (index=0 == top)
- * walk_state - Current Walk state
- *
- * RETURN: Status
- *
- * DESCRIPTION: Retrieve an object from this walk's object stack. Index must
- * be within the range of the current stack pointer.
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-void *
-acpi_ds_obj_stack_get_value (
- u32 index,
- struct acpi_walk_state *walk_state)
-{
-
- ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
-
-
- /* Can't do it if the stack is empty */
-
- if (walk_state->num_operands == 0) {
- return_PTR (NULL);
- }
-
- /* or if the index is past the top of the stack */
-
- if (index > (walk_state->num_operands - (u32) 1)) {
- return_PTR (NULL);
- }
-
- return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
- index]);
-}
-#endif /* ACPI_FUTURE_USAGE */
-
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ds_get_current_walk_state
*
* PARAMETERS: Thread - Get current active state for this Thread
@@ -757,11 +586,11 @@ acpi_ds_get_current_walk_state (
* FUNCTION: acpi_ds_push_walk_state
*
* PARAMETERS: walk_state - State to push
- * walk_list - The list that owns the walk stack
+ * Thread - Thread state object
*
* RETURN: None
*
- * DESCRIPTION: Place the walk_state at the head of the state list.
+ * DESCRIPTION: Place the Thread state at the head of the state list.
*
******************************************************************************/
@@ -784,9 +613,9 @@ acpi_ds_push_walk_state (
*
* FUNCTION: acpi_ds_pop_walk_state
*
- * PARAMETERS: walk_list - The list that owns the walk stack
+ * PARAMETERS: Thread - Current thread state
*
- * RETURN: A walk_state object popped from the stack
+ * RETURN: A walk_state object popped from the thread's stack
*
* DESCRIPTION: Remove and return the walkstate object that is at the head of
* the walk stack for the given walk list. NULL indicates that
@@ -814,7 +643,7 @@ acpi_ds_pop_walk_state (
/*
* Don't clear the NEXT field, this serves as an indicator
* that there is a parent WALK STATE
- * NO: walk_state->Next = NULL;
+ * Do Not: walk_state->Next = NULL;
*/
}
@@ -826,7 +655,9 @@ acpi_ds_pop_walk_state (
*
* FUNCTION: acpi_ds_create_walk_state
*
- * PARAMETERS: Origin - Starting point for this walk
+ * PARAMETERS: owner_id - ID for object creation
+ * Origin - Starting point for this walk
+ * mth_desc - Method object
* Thread - Current thread state
*
* RETURN: Pointer to the new walk state.
@@ -896,8 +727,7 @@ acpi_ds_create_walk_state (
* method_node - Control method NS node, if any
* aml_start - Start of AML
* aml_length - Length of AML
- * Params - Method args, if any
- * return_obj_desc - Where to store a return object, if any
+ * Info - Method info block (params, etc.)
* pass_number - 1, 2, or 3
*
* RETURN: Status
@@ -931,7 +761,7 @@ acpi_ds_init_aml_walk (
/* The next_op of the next_walk will be the beginning of the method */
- walk_state->next_op = NULL;
+ walk_state->next_op = NULL;
if (info) {
if (info->parameter_type == ACPI_PARAM_GPE) {
@@ -939,8 +769,8 @@ acpi_ds_init_aml_walk (
info->parameters);
}
else {
- walk_state->params = info->parameters;
- walk_state->caller_return_desc = &info->return_object;
+ walk_state->params = info->parameters;
+ walk_state->caller_return_desc = &info->return_object;
}
}
@@ -964,7 +794,8 @@ acpi_ds_init_aml_walk (
/* Init the method arguments */
- status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
+ status = acpi_ds_method_data_init_args (walk_state->params,
+ ACPI_METHOD_NUM_ARGS, walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -1031,12 +862,14 @@ acpi_ds_delete_walk_state (
}
if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n",
+ walk_state));
return;
}
if (walk_state->parser_state.scope) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n",
+ walk_state));
}
/* Always must free any linked control states */
@@ -1078,7 +911,7 @@ acpi_ds_delete_walk_state (
*
* PARAMETERS: None
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Purge the global state object cache. Used during subsystem
* termination.
@@ -1098,3 +931,200 @@ acpi_ds_delete_walk_state_cache (
#endif
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_result_insert
+ *
+ * PARAMETERS: Object - Object to push
+ * Index - Where to insert the object
+ * walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Insert an object onto this walk's result stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_insert (
+ void *object,
+ u32 index,
+ struct acpi_walk_state *walk_state)
+{
+ union acpi_generic_state *state;
+
+
+ ACPI_FUNCTION_NAME ("ds_result_insert");
+
+
+ state = walk_state->results;
+ if (!state) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
+ walk_state));
+ return (AE_NOT_EXIST);
+ }
+
+ if (index >= ACPI_OBJ_NUM_OPERANDS) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Index out of range: %X Obj=%p State=%p Num=%X\n",
+ index, object, walk_state, state->results.num_results));
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (!object) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
+ index, object, walk_state, state->results.num_results));
+ return (AE_BAD_PARAMETER);
+ }
+
+ state->results.obj_desc [index] = object;
+ state->results.num_results++;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+ object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
+ walk_state, state->results.num_results, walk_state->current_result));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_obj_stack_delete_all
+ *
+ * PARAMETERS: walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
+ * Should be used with great care, if at all!
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_delete_all (
+ struct acpi_walk_state *walk_state)
+{
+ u32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
+
+
+ /* The stack size is configurable, but fixed */
+
+ for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
+ if (walk_state->operands[i]) {
+ acpi_ut_remove_reference (walk_state->operands[i]);
+ walk_state->operands[i] = NULL;
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_obj_stack_pop_object
+ *
+ * PARAMETERS: Object - Where to return the popped object
+ * walk_state - Current Walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
+ * deleted by this routine.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_pop_object (
+ union acpi_operand_object **object,
+ struct acpi_walk_state *walk_state)
+{
+ ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
+
+
+ /* Check for stack underflow */
+
+ if (walk_state->num_operands == 0) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Missing operand/stack empty! State=%p #Ops=%X\n",
+ walk_state, walk_state->num_operands));
+ *object = NULL;
+ return (AE_AML_NO_OPERAND);
+ }
+
+ /* Pop the stack */
+
+ walk_state->num_operands--;
+
+ /* Check for a valid operand */
+
+ if (!walk_state->operands [walk_state->num_operands]) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Null operand! State=%p #Ops=%X\n",
+ walk_state, walk_state->num_operands));
+ *object = NULL;
+ return (AE_AML_NO_OPERAND);
+ }
+
+ /* Get operand and set stack entry to null */
+
+ *object = walk_state->operands [walk_state->num_operands];
+ walk_state->operands [walk_state->num_operands] = NULL;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+ *object, acpi_ut_get_object_type_name (*object),
+ walk_state, walk_state->num_operands));
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ds_obj_stack_get_value
+ *
+ * PARAMETERS: Index - Stack index whose value is desired. Based
+ * on the top of the stack (index=0 == top)
+ * walk_state - Current Walk state
+ *
+ * RETURN: Pointer to the requested operand
+ *
+ * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must
+ * be within the range of the current stack pointer.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ds_obj_stack_get_value (
+ u32 index,
+ struct acpi_walk_state *walk_state)
+{
+
+ ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
+
+
+ /* Can't do it if the stack is empty */
+
+ if (walk_state->num_operands == 0) {
+ return_PTR (NULL);
+ }
+
+ /* or if the index is past the top of the stack */
+
+ if (index > (walk_state->num_operands - (u32) 1)) {
+ return_PTR (NULL);
+ }
+
+ return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
+ index]);
+}
+#endif
+
+
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index fdf143b405b..8e665f2e313 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -31,6 +31,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -49,17 +50,19 @@ ACPI_MODULE_NAME ("acpi_ec")
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
+#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */
#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */
-#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
+#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
#define ACPI_EC_COMMAND_READ 0x80
#define ACPI_EC_COMMAND_WRITE 0x81
+#define ACPI_EC_BURST_ENABLE 0x82
+#define ACPI_EC_BURST_DISABLE 0x83
#define ACPI_EC_COMMAND_QUERY 0x84
static int acpi_ec_add (struct acpi_device *device);
@@ -87,7 +90,11 @@ struct acpi_ec {
struct acpi_generic_address command_addr;
struct acpi_generic_address data_addr;
unsigned long global_lock;
- spinlock_t lock;
+ unsigned int expect_event;
+ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
+ atomic_t pending_gpe;
+ struct semaphore sem;
+ wait_queue_head_t wait;
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -100,42 +107,122 @@ static struct acpi_device *first_ec;
Transaction Management
-------------------------------------------------------------------------- */
-static int
-acpi_ec_wait (
- struct acpi_ec *ec,
- u8 event)
+static inline u32 acpi_ec_read_status(struct acpi_ec *ec)
{
- u32 acpi_ec_status = 0;
- u32 i = ACPI_EC_UDELAY_COUNT;
+ u32 status = 0;
- if (!ec)
- return -EINVAL;
+ acpi_hw_low_level_read(8, &status, &ec->status_addr);
+ return status;
+}
+
+static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
+{
+ int result = 0;
+
+ ACPI_FUNCTION_TRACE("acpi_ec_wait");
- /* Poll the EC status register waiting for the event to occur. */
+ ec->expect_event = event;
+ smp_mb();
+
+ result = wait_event_interruptible_timeout(ec->wait,
+ !ec->expect_event,
+ msecs_to_jiffies(ACPI_EC_DELAY));
+
+ ec->expect_event = 0;
+ smp_mb();
+
+ if (result < 0){
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result = %d ", result));
+ return_VALUE(result);
+ }
+
+ /*
+ * Verify that the event in question has actually happened by
+ * querying EC status. Do the check even if operation timed-out
+ * to make sure that we did not miss interrupt.
+ */
switch (event) {
case ACPI_EC_EVENT_OBF:
- do {
- acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
- if (acpi_ec_status & ACPI_EC_FLAG_OBF)
- return 0;
- udelay(ACPI_EC_UDELAY);
- } while (--i>0);
+ if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+ return_VALUE(0);
break;
+
case ACPI_EC_EVENT_IBE:
- do {
- acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
- if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
- return 0;
- udelay(ACPI_EC_UDELAY);
- } while (--i>0);
+ if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
+ return_VALUE(0);
break;
- default:
- return -EINVAL;
}
- return -ETIME;
+ return_VALUE(-ETIME);
+}
+
+
+
+static int
+acpi_ec_enter_burst_mode (
+ struct acpi_ec *ec)
+{
+ u32 tmp = 0;
+ int status = 0;
+
+ ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");
+
+ status = acpi_ec_read_status(ec);
+ if (status != -EINVAL &&
+ !(status & ACPI_EC_FLAG_BURST)){
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"entering burst mode \n"));
+ acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+ if (status){
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR," status = %d\n", status));
+ return_VALUE(-EINVAL);
+ }
+ acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ if(tmp != 0x90 ) {/* Burst ACK byte*/
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Ack failed \n"));
+ return_VALUE(-EINVAL);
+ }
+ } else
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in burst mode \n"));
+ atomic_set(&ec->leaving_burst , 0);
+ return_VALUE(0);
}
+static int
+acpi_ec_leave_burst_mode (
+ struct acpi_ec *ec)
+{
+ int status =0;
+
+ ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
+
+ atomic_set(&ec->leaving_burst , 1);
+ status = acpi_ec_read_status(ec);
+ if (status != -EINVAL &&
+ (status & ACPI_EC_FLAG_BURST)){
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
+ acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr);
+ status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+ if (status){
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
+ return_VALUE(-EINVAL);
+ }
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ status = acpi_ec_read_status(ec);
+ if (status != -EINVAL &&
+ (status & ACPI_EC_FLAG_BURST)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->status fail\n"));
+ return_VALUE(-EINVAL);
+ }
+ }else
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in Non-burst mode \n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
+
+ return_VALUE(0);
+}
static int
acpi_ec_read (
@@ -143,16 +230,15 @@ acpi_ec_read (
u8 address,
u32 *data)
{
- acpi_status status = AE_OK;
- int result = 0;
- unsigned long flags = 0;
- u32 glk = 0;
+ int status = 0;
+ u32 glk;
ACPI_FUNCTION_TRACE("acpi_ec_read");
if (!ec || !data)
return_VALUE(-EINVAL);
+retry:
*data = 0;
if (ec->global_lock) {
@@ -160,32 +246,50 @@ acpi_ec_read (
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
}
-
- spin_lock_irqsave(&ec->lock, flags);
+
+ WARN_ON(in_interrupt());
+ down(&ec->sem);
+
+ if(acpi_ec_enter_burst_mode(ec))
+ goto end;
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ if (status) {
goto end;
+ }
acpi_hw_low_level_write(8, address, &ec->data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (result)
+ status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+ if (status){
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
goto end;
-
+ }
acpi_hw_low_level_read(8, data, &ec->data_addr);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
*data, address));
-
+
end:
- spin_unlock_irqrestore(&ec->lock, flags);
+ acpi_ec_leave_burst_mode(ec);
+ up(&ec->sem);
if (ec->global_lock)
acpi_release_global_lock(glk);
- return_VALUE(result);
+ if(atomic_read(&ec->leaving_burst) == 2){
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+ while(atomic_read(&ec->pending_gpe)){
+ msleep(1);
+ }
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ goto retry;
+ }
+
+ return_VALUE(status);
}
@@ -195,49 +299,80 @@ acpi_ec_write (
u8 address,
u8 data)
{
- int result = 0;
- acpi_status status = AE_OK;
- unsigned long flags = 0;
- u32 glk = 0;
+ int status = 0;
+ u32 glk;
+ u32 tmp;
ACPI_FUNCTION_TRACE("acpi_ec_write");
if (!ec)
return_VALUE(-EINVAL);
-
+retry:
if (ec->global_lock) {
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status))
return_VALUE(-ENODEV);
}
- spin_lock_irqsave(&ec->lock, flags);
+ WARN_ON(in_interrupt());
+ down(&ec->sem);
+
+ if(acpi_ec_enter_burst_mode(ec))
+ goto end;
+
+ status = acpi_ec_read_status(ec);
+ if (status != -EINVAL &&
+ !(status & ACPI_EC_FLAG_BURST)){
+ acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+ if (status)
+ goto end;
+ acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
+ if(tmp != 0x90 ) /* Burst ACK byte*/
+ goto end;
+ }
+ /*Now we are in burst mode*/
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ if (status){
goto end;
+ }
acpi_hw_low_level_write(8, address, &ec->data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ if (status){
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
goto end;
+ }
acpi_hw_low_level_write(8, data, &ec->data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ if (status)
goto end;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
data, address));
end:
- spin_unlock_irqrestore(&ec->lock, flags);
+ acpi_ec_leave_burst_mode(ec);
+ up(&ec->sem);
if (ec->global_lock)
acpi_release_global_lock(glk);
- return_VALUE(result);
+ if(atomic_read(&ec->leaving_burst) == 2){
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+ while(atomic_read(&ec->pending_gpe)){
+ msleep(1);
+ }
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ goto retry;
+ }
+
+ return_VALUE(status);
}
/*
@@ -289,16 +424,13 @@ acpi_ec_query (
struct acpi_ec *ec,
u32 *data)
{
- int result = 0;
- acpi_status status = AE_OK;
- unsigned long flags = 0;
- u32 glk = 0;
+ int status = 0;
+ u32 glk;
ACPI_FUNCTION_TRACE("acpi_ec_query");
if (!ec || !data)
return_VALUE(-EINVAL);
-
*data = 0;
if (ec->global_lock) {
@@ -307,29 +439,39 @@ acpi_ec_query (
return_VALUE(-ENODEV);
}
+ down(&ec->sem);
+ if(acpi_ec_enter_burst_mode(ec))
+ goto end;
/*
* Query the EC to find out which _Qxx method we need to evaluate.
* Note that successful completion of the query causes the ACPI_EC_SCI
* bit to be cleared (and thus clearing the interrupt source).
*/
- spin_lock_irqsave(&ec->lock, flags);
-
acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (result)
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+ if (status){
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
goto end;
-
+ }
+
acpi_hw_low_level_read(8, data, &ec->data_addr);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
if (!*data)
- result = -ENODATA;
+ status = -ENODATA;
end:
- spin_unlock_irqrestore(&ec->lock, flags);
+ acpi_ec_leave_burst_mode(ec);
+ up(&ec->sem);
if (ec->global_lock)
acpi_release_global_lock(glk);
- return_VALUE(result);
+ if(atomic_read(&ec->leaving_burst) == 2){
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+ status = -ENODATA;
+ }
+ return_VALUE(status);
}
@@ -347,42 +489,29 @@ acpi_ec_gpe_query (
void *ec_cxt)
{
struct acpi_ec *ec = (struct acpi_ec *) ec_cxt;
- u32 value = 0;
- unsigned long flags = 0;
+ u32 value;
+ int result = -ENODATA;
static char object_name[5] = {'_','Q','0','0','\0'};
const char hex[] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
- if (!ec_cxt)
- goto end;
-
- spin_lock_irqsave(&ec->lock, flags);
- acpi_hw_low_level_read(8, &value, &ec->command_addr);
- spin_unlock_irqrestore(&ec->lock, flags);
+ if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
+ result = acpi_ec_query(ec, &value);
- /* TBD: Implement asynch events!
- * NOTE: All we care about are EC-SCI's. Other EC events are
- * handled via polling (yuck!). This is because some systems
- * treat EC-SCIs as level (versus EDGE!) triggered, preventing
- * a purely interrupt-driven approach (grumble, grumble).
- */
- if (!(value & ACPI_EC_FLAG_SCI))
+ if (result)
goto end;
- if (acpi_ec_query(ec, &value))
- goto end;
-
object_name[2] = hex[((value >> 4) & 0x0F)];
object_name[3] = hex[(value & 0x0F)];
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
-
-end:
- acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+end:
+ atomic_dec(&ec->pending_gpe);
+ return;
}
static u32
@@ -390,6 +519,7 @@ acpi_ec_gpe_handler (
void *data)
{
acpi_status status = AE_OK;
+ u32 value;
struct acpi_ec *ec = (struct acpi_ec *) data;
if (!ec)
@@ -397,13 +527,41 @@ acpi_ec_gpe_handler (
acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
- status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
- acpi_ec_gpe_query, ec);
+ value = acpi_ec_read_status(ec);
- if (status == AE_OK)
- return ACPI_INTERRUPT_HANDLED;
- else
- return ACPI_INTERRUPT_NOT_HANDLED;
+ if((value & ACPI_EC_FLAG_IBF) &&
+ !(value & ACPI_EC_FLAG_BURST) &&
+ (atomic_read(&ec->leaving_burst) == 0)) {
+ /*
+ * the embedded controller disables
+ * burst mode for any reason other
+ * than the burst disable command
+ * to process critical event.
+ */
+ atomic_set(&ec->leaving_burst , 2); /* block current pending transaction
+ and retry */
+ wake_up(&ec->wait);
+ }else {
+ if ((ec->expect_event == ACPI_EC_EVENT_OBF &&
+ (value & ACPI_EC_FLAG_OBF)) ||
+ (ec->expect_event == ACPI_EC_EVENT_IBE &&
+ !(value & ACPI_EC_FLAG_IBF))) {
+ ec->expect_event = 0;
+ wake_up(&ec->wait);
+ return ACPI_INTERRUPT_HANDLED;
+ }
+ }
+
+ if (value & ACPI_EC_FLAG_SCI){
+ atomic_add(1, &ec->pending_gpe) ;
+ status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+ acpi_ec_gpe_query, ec);
+ return status == AE_OK ?
+ ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+ }
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+ return status == AE_OK ?
+ ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}
/* --------------------------------------------------------------------------
@@ -421,10 +579,8 @@ acpi_ec_space_setup (
* The EC object is in the handler context and is needed
* when calling the acpi_ec_space_handler.
*/
- if(function == ACPI_REGION_DEACTIVATE)
- *return_context = NULL;
- else
- *return_context = handler_context;
+ *return_context = (function != ACPI_REGION_DEACTIVATE) ?
+ handler_context : NULL;
return AE_OK;
}
@@ -441,7 +597,7 @@ acpi_ec_space_handler (
{
int result = 0;
struct acpi_ec *ec = NULL;
- u32 temp = 0;
+ u64 temp = *value;
acpi_integer f_v = 0;
int i = 0;
@@ -450,10 +606,9 @@ acpi_ec_space_handler (
if ((address > 0xFF) || !value || !handler_context)
return_VALUE(AE_BAD_PARAMETER);
- if(bit_width != 8) {
+ if (bit_width != 8 && acpi_strict) {
printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
- if (acpi_strict)
- return_VALUE(AE_BAD_PARAMETER);
+ return_VALUE(AE_BAD_PARAMETER);
}
ec = (struct acpi_ec *) handler_context;
@@ -461,11 +616,11 @@ acpi_ec_space_handler (
next_byte:
switch (function) {
case ACPI_READ:
- result = acpi_ec_read(ec, (u8) address, &temp);
- *value = (acpi_integer) temp;
+ temp = 0;
+ result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
break;
case ACPI_WRITE:
- result = acpi_ec_write(ec, (u8) address, (u8) *value);
+ result = acpi_ec_write(ec, (u8) address, (u8) temp);
break;
default:
result = -EINVAL;
@@ -474,19 +629,18 @@ next_byte:
}
bit_width -= 8;
- if(bit_width){
-
- if(function == ACPI_READ)
- f_v |= (acpi_integer) (*value) << 8*i;
- if(function == ACPI_WRITE)
- (*value) >>=8;
+ if (bit_width) {
+ if (function == ACPI_READ)
+ f_v |= temp << 8 * i;
+ if (function == ACPI_WRITE)
+ temp >>= 8;
i++;
+ address++;
goto next_byte;
}
-
- if(function == ACPI_READ){
- f_v |= (acpi_integer) (*value) << 8*i;
+ if (function == ACPI_READ) {
+ f_v |= temp << 8 * i;
*value = f_v;
}
@@ -505,8 +659,6 @@ out:
default:
return_VALUE(AE_OK);
}
-
-
}
@@ -533,6 +685,7 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
(u32) ec->status_addr.address, (u32) ec->data_addr.address);
seq_printf(seq, "use global lock: %s\n",
ec->global_lock?"yes":"no");
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
end:
return_VALUE(0);
@@ -555,7 +708,7 @@ static int
acpi_ec_add_fs (
struct acpi_device *device)
{
- struct proc_dir_entry *entry = NULL;
+ struct proc_dir_entry *entry;
ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
@@ -606,9 +759,9 @@ static int
acpi_ec_add (
struct acpi_device *device)
{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_ec *ec = NULL;
+ int result;
+ acpi_status status;
+ struct acpi_ec *ec;
unsigned long uid;
ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -623,7 +776,10 @@ acpi_ec_add (
ec->handle = device->handle;
ec->uid = -1;
- spin_lock_init(&ec->lock);
+ atomic_set(&ec->pending_gpe, 0);
+ atomic_set(&ec->leaving_burst , 1);
+ init_MUTEX(&ec->sem);
+ init_waitqueue_head(&ec->wait);
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
acpi_driver_data(device) = ec;
@@ -637,7 +793,7 @@ acpi_ec_add (
if (ec_ecdt && ec_ecdt->uid == uid) {
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
-
+
acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
kfree(ec_ecdt);
@@ -677,7 +833,7 @@ acpi_ec_remove (
struct acpi_device *device,
int type)
{
- struct acpi_ec *ec = NULL;
+ struct acpi_ec *ec;
ACPI_FUNCTION_TRACE("acpi_ec_remove");
@@ -732,8 +888,8 @@ static int
acpi_ec_start (
struct acpi_device *device)
{
- acpi_status status = AE_OK;
- struct acpi_ec *ec = NULL;
+ acpi_status status;
+ struct acpi_ec *ec;
ACPI_FUNCTION_TRACE("acpi_ec_start");
@@ -789,8 +945,8 @@ acpi_ec_stop (
struct acpi_device *device,
int type)
{
- acpi_status status = AE_OK;
- struct acpi_ec *ec = NULL;
+ acpi_status status;
+ struct acpi_ec *ec;
ACPI_FUNCTION_TRACE("acpi_ec_stop");
@@ -832,7 +988,6 @@ acpi_fake_ecdt_callback (
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
if (ACPI_FAILURE(status))
return status;
- spin_lock_init(&ec_ecdt->lock);
ec_ecdt->global_lock = TRUE;
ec_ecdt->handle = handle;
@@ -890,7 +1045,7 @@ acpi_ec_get_real_ecdt(void)
acpi_status status;
struct acpi_table_ecdt *ecdt_ptr;
- status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
+ status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
(struct acpi_table_header **) &ecdt_ptr);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -905,11 +1060,12 @@ acpi_ec_get_real_ecdt(void)
return -ENOMEM;
memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+ init_MUTEX(&ec_ecdt->sem);
+ init_waitqueue_head(&ec_ecdt->wait);
ec_ecdt->command_addr = ecdt_ptr->ec_control;
ec_ecdt->status_addr = ecdt_ptr->ec_control;
ec_ecdt->data_addr = ecdt_ptr->ec_data;
ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
- spin_lock_init(&ec_ecdt->lock);
/* use the GL just to be safe */
ec_ecdt->global_lock = TRUE;
ec_ecdt->uid = ecdt_ptr->uid;
@@ -978,7 +1134,7 @@ error:
static int __init acpi_ec_init (void)
{
- int result = 0;
+ int result;
ACPI_FUNCTION_TRACE("acpi_ec_init");
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 2a213604ae5..dd3a72a869f 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -47,6 +47,16 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evevent")
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_fixed_event_initialize (
+ void);
+
+static u32
+acpi_ev_fixed_event_dispatch (
+ u32 event);
+
/*******************************************************************************
*
@@ -56,7 +66,7 @@
*
* RETURN: Status
*
- * DESCRIPTION: Initialize global data structures for events.
+ * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
*
******************************************************************************/
@@ -78,9 +88,9 @@ acpi_ev_initialize_events (
}
/*
- * Initialize the Fixed and General Purpose Events. This is
- * done prior to enabling SCIs to prevent interrupts from
- * occurring before handers are installed.
+ * Initialize the Fixed and General Purpose Events. This is done prior to
+ * enabling SCIs to prevent interrupts from occurring before the handlers are
+ * installed.
*/
status = acpi_ev_fixed_event_initialize ();
if (ACPI_FAILURE (status)) {
@@ -161,7 +171,7 @@ acpi_ev_install_xrupt_handlers (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ev_fixed_event_initialize (
void)
{
@@ -180,7 +190,8 @@ acpi_ev_fixed_event_initialize (
/* Enable the fixed event */
if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
- status = acpi_set_register (acpi_gbl_fixed_event_info[i].enable_register_id,
+ status = acpi_set_register (
+ acpi_gbl_fixed_event_info[i].enable_register_id,
0, ACPI_MTX_LOCK);
if (ACPI_FAILURE (status)) {
return (status);
@@ -200,7 +211,7 @@ acpi_ev_fixed_event_initialize (
*
* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
*
- * DESCRIPTION: Checks the PM status register for fixed events
+ * DESCRIPTION: Checks the PM status register for active fixed events
*
******************************************************************************/
@@ -221,8 +232,10 @@ acpi_ev_fixed_event_detect (
* Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here.
*/
- (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, &fixed_status);
- (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+ (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
+ &fixed_status);
+ (void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE,
+ &fixed_enable);
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n",
@@ -259,7 +272,7 @@ acpi_ev_fixed_event_detect (
*
******************************************************************************/
-u32
+static u32
acpi_ev_fixed_event_dispatch (
u32 event)
{
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 118d72ac7c7..081120b109b 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -48,6 +48,12 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evgpe")
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_asynch_execute_gpe_method (
+ void *context);
+
/*******************************************************************************
*
@@ -335,8 +341,10 @@ acpi_ev_get_gpe_event_info (
gpe_block = acpi_gbl_gpe_fadt_blocks[i];
if (gpe_block) {
if ((gpe_number >= gpe_block->block_base_number) &&
- (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
+ (gpe_number < gpe_block->block_base_number +
+ (gpe_block->register_count * 8))) {
+ return (&gpe_block->event_info[gpe_number -
+ gpe_block->block_base_number]);
}
}
}
@@ -437,7 +445,7 @@ acpi_ev_gpe_detect (
"Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
gpe_register_info->base_gpe_number, status_reg, enable_reg));
- /* First check if there is anything active at all in this register */
+ /* Check if there is anything active at all in this register */
enabled_status_byte = (u8) (status_reg & enable_reg);
if (!enabled_status_byte) {
@@ -457,8 +465,8 @@ acpi_ev_gpe_detect (
* or method.
*/
int_status |= acpi_ev_gpe_dispatch (
- &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
- (u32) j + gpe_register_info->base_gpe_number);
+ &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
+ (u32) j + gpe_register_info->base_gpe_number);
}
}
}
@@ -523,7 +531,8 @@ acpi_ev_asynch_execute_gpe_method (
* Take a snapshot of the GPE info for this level - we copy the
* info to prevent a race condition with remove_handler/remove_block.
*/
- ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));
+ ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info,
+ sizeof (struct acpi_gpe_event_info));
status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) {
@@ -534,7 +543,8 @@ acpi_ev_asynch_execute_gpe_method (
* Must check for control method type dispatch one more
* time to avoid race with ev_gpe_install_handler
*/
- if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
+ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_METHOD) {
/*
* Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
* control method that corresponds to this GPE
@@ -553,7 +563,8 @@ acpi_ev_asynch_execute_gpe_method (
}
}
- if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+ if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_LEVEL_TRIGGERED) {
/*
* GPE is level-triggered, we clear the GPE status bit after
* handling the event.
@@ -575,7 +586,7 @@ acpi_ev_asynch_execute_gpe_method (
*
* FUNCTION: acpi_ev_gpe_dispatch
*
- * PARAMETERS: gpe_event_info - info for this GPE
+ * PARAMETERS: gpe_event_info - Info for this GPE
* gpe_number - Number relative to the parent GPE block
*
* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -602,10 +613,12 @@ acpi_ev_gpe_dispatch (
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
- if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_EDGE_TRIGGERED) {
+ if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_EDGE_TRIGGERED) {
status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
+ ACPI_REPORT_ERROR ((
+ "acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
acpi_format_exception (status), gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
@@ -639,7 +652,8 @@ acpi_ev_gpe_dispatch (
/* It is now safe to clear level-triggered events. */
- if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+ if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_LEVEL_TRIGGERED) {
status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR ((
@@ -704,7 +718,6 @@ acpi_ev_gpe_dispatch (
#ifdef ACPI_GPE_NOTIFY_CHECK
-
/*******************************************************************************
* TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
*
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 00d981f53c6..84186a7d17b 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -48,6 +48,39 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evgpeblk")
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_save_method_info (
+ acpi_handle obj_handle,
+ u32 level,
+ void *obj_desc,
+ void **return_value);
+
+static acpi_status
+acpi_ev_match_prw_and_gpe (
+ acpi_handle obj_handle,
+ u32 level,
+ void *info,
+ void **return_value);
+
+static struct acpi_gpe_xrupt_info *
+acpi_ev_get_gpe_xrupt_block (
+ u32 interrupt_level);
+
+static acpi_status
+acpi_ev_delete_gpe_xrupt (
+ struct acpi_gpe_xrupt_info *gpe_xrupt);
+
+static acpi_status
+acpi_ev_install_gpe_block (
+ struct acpi_gpe_block_info *gpe_block,
+ u32 interrupt_level);
+
+static acpi_status
+acpi_ev_create_gpe_info_blocks (
+ struct acpi_gpe_block_info *gpe_block);
+
/*******************************************************************************
*
@@ -155,7 +188,7 @@ unlock_and_exit:
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ev_delete_gpe_handlers
*
@@ -190,7 +223,8 @@ acpi_ev_delete_gpe_handlers (
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
- if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_HANDLER) {
ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
gpe_event_info->dispatch.handler = NULL;
gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
@@ -471,7 +505,7 @@ acpi_ev_get_gpe_xrupt_block (
ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block");
- /* No need for spin lock since we are not changing any list elements here */
+ /* No need for lock since we are not changing any list elements here */
next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
while (next_gpe_xrupt) {
@@ -619,7 +653,7 @@ acpi_ev_install_gpe_block (
goto unlock_and_exit;
}
- /* Install the new block at the end of the list for this interrupt with lock */
+ /* Install the new block at the end of the list with lock */
acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
if (gpe_xrupt_block->gpe_block_list_head) {
@@ -756,10 +790,12 @@ acpi_ev_create_gpe_info_blocks (
* per register. Initialization to zeros is sufficient.
*/
gpe_event_info = ACPI_MEM_CALLOCATE (
- ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) *
+ ((acpi_size) gpe_block->register_count *
+ ACPI_GPE_REGISTER_WIDTH) *
sizeof (struct acpi_gpe_event_info));
if (!gpe_event_info) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not allocate the gpe_event_info table\n"));
status = AE_NO_MEMORY;
goto error_exit;
}
@@ -899,7 +935,8 @@ acpi_ev_create_gpe_block (
gpe_block->block_base_number = gpe_block_base_number;
gpe_block->node = gpe_device;
- ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
+ ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address,
+ sizeof (struct acpi_generic_address));
/* Create the register_info and event_info sub-structures */
@@ -1061,8 +1098,9 @@ acpi_ev_gpe_initialize (
/* Install GPE Block 0 */
- status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe0_blk,
- register_count0, 0, acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
+ status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
+ &acpi_gbl_FADT->xgpe0_blk, register_count0, 0,
+ acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR ((
@@ -1094,8 +1132,9 @@ acpi_ev_gpe_initialize (
else {
/* Install GPE Block 1 */
- status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe1_blk,
- register_count1, acpi_gbl_FADT->gpe1_base,
+ status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
+ &acpi_gbl_FADT->xgpe1_blk, register_count1,
+ acpi_gbl_FADT->gpe1_base,
acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]);
if (ACPI_FAILURE (status)) {
@@ -1109,7 +1148,7 @@ acpi_ev_gpe_initialize (
* space. However, GPE0 always starts at GPE number zero.
*/
gpe_number_max = acpi_gbl_FADT->gpe1_base +
- ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+ ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
}
}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 2548efa7a45..659e9095611 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -50,6 +50,35 @@
ACPI_MODULE_NAME ("evmisc")
+#ifdef ACPI_DEBUG_OUTPUT
+static const char *acpi_notify_value_names[] =
+{
+ "Bus Check",
+ "Device Check",
+ "Device Wake",
+ "Eject request",
+ "Device Check Light",
+ "Frequency Mismatch",
+ "Bus Mode Mismatch",
+ "Power Fault"
+};
+#endif
+
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_notify_dispatch (
+ void *context);
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_global_lock_thread (
+ void *context);
+
+static u32
+acpi_ev_global_lock_handler (
+ void *context);
+
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_is_notify_object
@@ -98,20 +127,6 @@ acpi_ev_is_notify_object (
*
******************************************************************************/
-#ifdef ACPI_DEBUG_OUTPUT
-static const char *acpi_notify_value_names[] =
-{
- "Bus Check",
- "Device Check",
- "Device Wake",
- "Eject request",
- "Device Check Light",
- "Frequency Mismatch",
- "Bus Mode Mismatch",
- "Power Fault"
-};
-#endif
-
acpi_status
acpi_ev_queue_notify_request (
struct acpi_namespace_node *node,
@@ -128,9 +143,10 @@ acpi_ev_queue_notify_request (
/*
* For value 3 (Ejection Request), some device method may need to be run.
- * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run.
+ * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
+ * to be run.
* For value 0x80 (Status Change) on the power button or sleep button,
- * initiate soft-off or sleep operation?
+ * initiate soft-off or sleep operation?
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Dispatching Notify(%X) on node %p\n", notify_value, node));
@@ -140,8 +156,9 @@ acpi_ev_queue_notify_request (
acpi_notify_value_names[notify_value]));
}
else {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n",
- notify_value));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Notify value: 0x%2.2X **Device Specific**\n",
+ notify_value));
}
/* Get the notify object attached to the NS Node */
@@ -210,7 +227,7 @@ acpi_ev_queue_notify_request (
*
* FUNCTION: acpi_ev_notify_dispatch
*
- * PARAMETERS: Context - To be passsed to the notify handler
+ * PARAMETERS: Context - To be passed to the notify handler
*
* RETURN: None.
*
@@ -219,7 +236,7 @@ acpi_ev_queue_notify_request (
*
******************************************************************************/
-void ACPI_SYSTEM_XFACE
+static void ACPI_SYSTEM_XFACE
acpi_ev_notify_dispatch (
void *context)
{
@@ -234,7 +251,8 @@ acpi_ev_notify_dispatch (
/*
* We will invoke a global notify handler if installed.
- * This is done _before_ we invoke the per-device handler attached to the device.
+ * This is done _before_ we invoke the per-device handler attached
+ * to the device.
*/
if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
/* Global system notification handler */
@@ -256,15 +274,17 @@ acpi_ev_notify_dispatch (
/* Invoke the system handler first, if present */
if (global_handler) {
- global_handler (notify_info->notify.node, notify_info->notify.value, global_context);
+ global_handler (notify_info->notify.node, notify_info->notify.value,
+ global_context);
}
/* Now invoke the per-device handler, if present */
handler_obj = notify_info->notify.handler_obj;
if (handler_obj) {
- handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
- handler_obj->notify.context);
+ handler_obj->notify.handler (notify_info->notify.node,
+ notify_info->notify.value,
+ handler_obj->notify.context);
}
/* All done with the info object */
@@ -370,7 +390,8 @@ acpi_ev_global_lock_handler (
******************************************************************************/
acpi_status
-acpi_ev_init_global_lock_handler (void)
+acpi_ev_init_global_lock_handler (
+ void)
{
acpi_status status;
@@ -380,7 +401,7 @@ acpi_ev_init_global_lock_handler (void)
acpi_gbl_global_lock_present = TRUE;
status = acpi_install_fixed_event_handler (ACPI_EVENT_GLOBAL,
- acpi_ev_global_lock_handler, NULL);
+ acpi_ev_global_lock_handler, NULL);
/*
* If the global lock does not exist on this platform, the attempt
@@ -433,8 +454,10 @@ acpi_ev_acquire_global_lock (
acpi_gbl_global_lock_thread_count++;
- /* If we (OS side vs. BIOS side) have the hardware lock already, we are done */
-
+ /*
+ * If we (OS side vs. BIOS side) have the hardware lock already,
+ * we are done
+ */
if (acpi_gbl_global_lock_acquired) {
return_ACPI_STATUS (AE_OK);
}
@@ -480,7 +503,8 @@ acpi_ev_acquire_global_lock (
******************************************************************************/
acpi_status
-acpi_ev_release_global_lock (void)
+acpi_ev_release_global_lock (
+ void)
{
u8 pending = FALSE;
acpi_status status = AE_OK;
@@ -490,7 +514,8 @@ acpi_ev_release_global_lock (void)
if (!acpi_gbl_global_lock_thread_count) {
- ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n"));
+ ACPI_REPORT_WARNING((
+ "Cannot release HW Global Lock, it has not been acquired\n"));
return_ACPI_STATUS (AE_NOT_ACQUIRED);
}
@@ -515,7 +540,8 @@ acpi_ev_release_global_lock (void)
* register
*/
if (pending) {
- status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK);
+ status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+ 1, ACPI_MTX_LOCK);
}
return_ACPI_STATUS (status);
@@ -535,7 +561,8 @@ acpi_ev_release_global_lock (void)
******************************************************************************/
void
-acpi_ev_terminate (void)
+acpi_ev_terminate (
+ void)
{
acpi_native_uint i;
acpi_status status;
@@ -555,7 +582,8 @@ acpi_ev_terminate (void)
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
status = acpi_disable_event ((u32) i, 0);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (u32) i));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not disable fixed event %d\n", (u32) i));
}
}
@@ -567,7 +595,8 @@ acpi_ev_terminate (void)
status = acpi_ev_remove_sci_handler ();
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not remove SCI handler\n"));
}
}
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 772342708a7..a1d7276c574 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -58,6 +58,22 @@ static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPA
ACPI_ADR_SPACE_PCI_CONFIG,
ACPI_ADR_SPACE_DATA_TABLE};
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_reg_run (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+
+static acpi_status
+acpi_ev_install_handler (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+
/*******************************************************************************
*
@@ -179,8 +195,8 @@ acpi_ev_initialize_op_regions (
*
* FUNCTION: acpi_ev_execute_reg_method
*
- * PARAMETERS: region_obj - Object structure
- * Function - Passed to _REG: On (1) or Off (0)
+ * PARAMETERS: region_obj - Region object
+ * Function - Passed to _REG: On (1) or Off (0)
*
* RETURN: Status
*
@@ -323,14 +339,16 @@ acpi_ev_address_space_dispatch (
if (!region_setup) {
/* No initialization routine, exit with error */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "No init routine for region(%p) [%s]\n",
region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
return_ACPI_STATUS (AE_NOT_EXIST);
}
/*
- * We must exit the interpreter because the region setup will potentially
- * execute control methods (e.g., _REG method for this region)
+ * We must exit the interpreter because the region
+ * setup will potentially execute control methods
+ * (e.g., _REG method for this region)
*/
acpi_ex_exit_interpreter ();
@@ -621,7 +639,7 @@ acpi_ev_attach_region (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ev_install_handler (
acpi_handle obj_handle,
u32 level,
@@ -848,7 +866,8 @@ acpi_ev_install_space_handler (
if (handler_obj->address_space.handler == handler) {
/*
* It is (relatively) OK to attempt to install the SAME
- * handler twice. This can easily happen with PCI_Config space.
+ * handler twice. This can easily happen
+ * with PCI_Config space.
*/
status = AE_SAME_HANDLER;
goto unlock_and_exit;
@@ -1011,7 +1030,7 @@ acpi_ev_execute_reg_methods (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ev_reg_run (
acpi_handle obj_handle,
u32 level,
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 4983a3378be..95bc09c73a6 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -61,7 +61,7 @@
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling, a nop for now
+ * DESCRIPTION: Setup a system_memory operation region
*
******************************************************************************/
@@ -115,7 +115,7 @@ acpi_ev_system_memory_region_setup (
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a IO operation region
*
******************************************************************************/
@@ -144,14 +144,14 @@ acpi_ev_io_space_region_setup (
*
* FUNCTION: acpi_ev_pci_config_region_setup
*
- * PARAMETERS: Handle - Region we are interested in
+ * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop
* handler_context - Address space handler context
* region_context - Region specific context
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a PCI_Config operation region
*
* MUTEX: Assumes namespace is not locked
*
@@ -324,7 +324,7 @@ acpi_ev_pci_config_region_setup (
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a pci_bAR operation region
*
* MUTEX: Assumes namespace is not locked
*
@@ -355,7 +355,7 @@ acpi_ev_pci_bar_region_setup (
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a CMOS operation region
*
* MUTEX: Assumes namespace is not locked
*
@@ -386,7 +386,7 @@ acpi_ev_cmos_region_setup (
*
* RETURN: Status
*
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Default region initialization
*
******************************************************************************/
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 46b31995c82..f3123c26ae9 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -49,6 +49,12 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evsci")
+/* Local prototypes */
+
+static u32 ACPI_SYSTEM_XFACE
+acpi_ev_sci_xrupt_handler (
+ void *context);
+
/*******************************************************************************
*
@@ -146,7 +152,8 @@ acpi_ev_gpe_xrupt_handler (
******************************************************************************/
u32
-acpi_ev_install_sci_handler (void)
+acpi_ev_install_sci_handler (
+ void)
{
u32 status = AE_OK;
@@ -180,7 +187,8 @@ acpi_ev_install_sci_handler (void)
******************************************************************************/
acpi_status
-acpi_ev_remove_sci_handler (void)
+acpi_ev_remove_sci_handler (
+ void)
{
acpi_status status;
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 0bfec10a5f1..4092d47f675 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -64,6 +64,7 @@
* DESCRIPTION: Saves the pointer to the handler function
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_install_exception_handler (
@@ -457,7 +458,8 @@ acpi_remove_notify_handler (
/* Root Object */
if (device == ACPI_ROOT_OBJECT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Removing notify handler for ROOT object.\n"));
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
!acpi_gbl_system_notify.handler) ||
@@ -564,8 +566,9 @@ EXPORT_SYMBOL(acpi_remove_notify_handler);
*
* FUNCTION: acpi_install_gpe_handler
*
- * PARAMETERS: gpe_number - The GPE number within the GPE block
- * gpe_block - GPE block (NULL == FADT GPEs)
+ * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * gpe_number - The GPE number within the GPE block
* Type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
* Address - Address of the handler
@@ -662,8 +665,9 @@ EXPORT_SYMBOL(acpi_install_gpe_handler);
*
* FUNCTION: acpi_remove_gpe_handler
*
- * PARAMETERS: gpe_number - The event to remove a handler
- * gpe_block - GPE block (NULL == FADT GPEs)
+ * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
+ * defined GPEs)
+ * gpe_number - The event to remove a handler
* Address - Address of the handler
*
* RETURN: Status
@@ -766,7 +770,8 @@ EXPORT_SYMBOL(acpi_remove_gpe_handler);
* FUNCTION: acpi_acquire_global_lock
*
* PARAMETERS: Timeout - How long the caller is willing to wait
- * out_handle - A handle to the lock if acquired
+ * Handle - Where the handle to the lock is returned
+ * (if acquired)
*
* RETURN: Status
*
@@ -812,7 +817,7 @@ EXPORT_SYMBOL(acpi_acquire_global_lock);
*
* RETURN: Status
*
- * DESCRIPTION: Release the ACPI Global Lock
+ * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
*
******************************************************************************/
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index fa8d5f25be6..f337dc2cc56 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -64,7 +64,8 @@
******************************************************************************/
acpi_status
-acpi_enable (void)
+acpi_enable (
+ void)
{
acpi_status status = AE_OK;
@@ -91,7 +92,8 @@ acpi_enable (void)
return_ACPI_STATUS (status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Transition to ACPI mode successful\n"));
}
return_ACPI_STATUS (status);
@@ -106,12 +108,13 @@ acpi_enable (void)
*
* RETURN: Status
*
- * DESCRIPTION: Transfers the system into LEGACY mode.
+ * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
*
******************************************************************************/
acpi_status
-acpi_disable (void)
+acpi_disable (
+ void)
{
acpi_status status = AE_OK;
@@ -125,7 +128,8 @@ acpi_disable (void)
}
if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "System is already in legacy (non-ACPI) mode\n"));
}
else {
/* Transition to LEGACY mode */
@@ -133,7 +137,8 @@ acpi_disable (void)
status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not exit ACPI mode to legacy mode"));
return_ACPI_STATUS (status);
}
@@ -214,7 +219,7 @@ EXPORT_SYMBOL(acpi_enable_event);
*
* RETURN: Status
*
- * DESCRIPTION: Enable an ACPI event (general purpose)
+ * DESCRIPTION: Set the type of an individual GPE
*
******************************************************************************/
@@ -519,13 +524,12 @@ unlock_and_exit:
#ifdef ACPI_FUTURE_USAGE
-
/*******************************************************************************
*
* FUNCTION: acpi_get_event_status
*
* PARAMETERS: Event - The fixed event
- * Event Status - Where the current status of the event will
+ * event_status - Where the current status of the event will
* be returned
*
* RETURN: Status
@@ -571,7 +575,7 @@ acpi_get_event_status (
* PARAMETERS: gpe_device - Parent GPE Device
* gpe_number - GPE level within the GPE block
* Flags - Called from an ISR or not
- * Event Status - Where the current status of the event will
+ * event_status - Where the current status of the event will
* be returned
*
* RETURN: Status
@@ -775,4 +779,5 @@ unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (status);
}
+
EXPORT_SYMBOL(acpi_remove_gpe_block);
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index ac3c061967f..734b2f24af4 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -54,6 +54,14 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exconfig")
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_add_table (
+ struct acpi_table_header *table,
+ struct acpi_namespace_node *parent_node,
+ union acpi_operand_object **ddb_handle);
+
/*******************************************************************************
*
@@ -70,7 +78,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_add_table (
struct acpi_table_header *table,
struct acpi_namespace_node *parent_node,
@@ -95,10 +103,10 @@ acpi_ex_add_table (
ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
- table_info.type = ACPI_TABLE_SSDT;
- table_info.pointer = table;
- table_info.length = (acpi_size) table->length;
- table_info.allocation = ACPI_MEM_ALLOCATED;
+ table_info.type = ACPI_TABLE_SSDT;
+ table_info.pointer = table;
+ table_info.length = (acpi_size) table->length;
+ table_info.allocation = ACPI_MEM_ALLOCATED;
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
@@ -226,11 +234,10 @@ acpi_ex_load_table_op (
start_node = parent_node;
}
- /*
- * Find the node referenced by the parameter_path_string
- */
+ /* Find the node referenced by the parameter_path_string */
+
status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node,
- ACPI_NS_SEARCH_PARENT, &parameter_node);
+ ACPI_NS_SEARCH_PARENT, &parameter_node);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -248,7 +255,8 @@ acpi_ex_load_table_op (
if (parameter_node) {
/* Store the parameter data into the optional parameter object */
- status = acpi_ex_store (operand[5], ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
+ status = acpi_ex_store (operand[5],
+ ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
walk_state);
if (ACPI_FAILURE (status)) {
(void) acpi_ex_unload_table (ddb_handle);
@@ -371,7 +379,8 @@ acpi_ex_load_op (
goto cleanup;
}
- table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
+ table_ptr = ACPI_CAST_PTR (struct acpi_table_header,
+ buffer_desc->buffer.pointer);
/* Sanity check the table length */
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index df7ba1219bf..97856c48bd7 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -50,6 +50,15 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exconvrt")
+/* Local prototypes */
+
+static u32
+acpi_ex_convert_to_ascii (
+ acpi_integer integer,
+ u16 base,
+ u8 *string,
+ u8 max_length);
+
/*******************************************************************************
*
@@ -115,9 +124,8 @@ acpi_ex_convert_to_integer (
*/
result = 0;
- /*
- * String conversion is different than Buffer conversion
- */
+ /* String conversion is different than Buffer conversion */
+
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_STRING:
@@ -168,9 +176,8 @@ acpi_ex_convert_to_integer (
break;
}
- /*
- * Create a new integer
- */
+ /* Create a new integer */
+
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -251,7 +258,8 @@ acpi_ex_convert_to_buffer (
* ASL/AML code that depends on the null being transferred to the new
* buffer.
*/
- return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length + 1);
+ return_desc = acpi_ut_create_buffer_object (
+ (acpi_size) obj_desc->string.length + 1);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
@@ -291,7 +299,7 @@ acpi_ex_convert_to_buffer (
*
******************************************************************************/
-u32
+static u32
acpi_ex_convert_to_ascii (
acpi_integer integer,
u16 base,
@@ -357,8 +365,9 @@ acpi_ex_convert_to_ascii (
case 16:
- hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
+ /* hex_length: 2 ascii hex chars per data byte */
+ hex_length = ACPI_MUL_2 (data_width);
for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
/* Get one hex digit, most significant digits first */
@@ -475,7 +484,7 @@ acpi_ex_convert_to_string (
/* Setup string length, base, and separator */
switch (type) {
- case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
+ case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* decimal values separated by commas."
@@ -509,7 +518,7 @@ acpi_ex_convert_to_string (
string_length = (obj_desc->buffer.length * 3);
break;
- case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */
+ case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string */
/*
* From ACPI: "If Data is a buffer, it is converted to a string of
* hexadecimal values separated by commas."
@@ -530,9 +539,8 @@ acpi_ex_convert_to_string (
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
- /*
- * Create a new string object and string buffer
- */
+ /* Create a new string object and string buffer */
+
return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -551,8 +559,10 @@ acpi_ex_convert_to_string (
*new_buf++ = separator; /* each separated by a comma or space */
}
- /* Null terminate the string (overwrites final comma/space from above) */
-
+ /*
+ * Null terminate the string
+ * (overwrites final comma/space from above)
+ */
new_buf--;
*new_buf = 0;
break;
@@ -645,7 +655,6 @@ acpi_ex_convert_to_target_type (
case ACPI_TYPE_STRING:
-
/*
* The operand must be a String. We can convert an
* Integer or Buffer if necessary
@@ -656,7 +665,6 @@ acpi_ex_convert_to_target_type (
case ACPI_TYPE_BUFFER:
-
/*
* The operand must be a Buffer. We can convert an
* Integer or String if necessary
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index d94c260dac6..812cdcb2e37 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -55,7 +55,7 @@
#ifndef ACPI_NO_METHOD_EXECUTION
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_alias
*
@@ -65,7 +65,7 @@
*
* DESCRIPTION: Create a new named alias
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_alias (
@@ -140,8 +140,7 @@ acpi_ex_create_alias (
* target node or the alias Node
*/
status = acpi_ns_attach_object (alias_node,
- acpi_ns_get_attached_object (target_node),
- target_node->type);
+ acpi_ns_get_attached_object (target_node), target_node->type);
break;
}
@@ -151,7 +150,7 @@ acpi_ex_create_alias (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_event
*
@@ -161,7 +160,7 @@ acpi_ex_create_alias (
*
* DESCRIPTION: Create a new event object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_event (
@@ -185,7 +184,7 @@ acpi_ex_create_event (
* that the event is created in an unsignalled state
*/
status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0,
- &obj_desc->event.semaphore);
+ &obj_desc->event.semaphore);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
@@ -193,7 +192,7 @@ acpi_ex_create_event (
/* Attach object to the Node */
status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0],
- obj_desc, ACPI_TYPE_EVENT);
+ obj_desc, ACPI_TYPE_EVENT);
cleanup:
/*
@@ -205,7 +204,7 @@ cleanup:
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_mutex
*
@@ -217,7 +216,7 @@ cleanup:
*
* Mutex (Name[0], sync_level[1])
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_mutex (
@@ -267,20 +266,20 @@ cleanup:
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_region
*
* PARAMETERS: aml_start - Pointer to the region declaration AML
* aml_length - Max length of the declaration AML
- * Operands - List of operands for the opcode
+ * region_space - space_iD for the region
* walk_state - Current state
*
* RETURN: Status
*
* DESCRIPTION: Create a new operation region object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_region (
@@ -321,7 +320,7 @@ acpi_ex_create_region (
}
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
- acpi_ut_get_region_name (region_space), region_space));
+ acpi_ut_get_region_name (region_space), region_space));
/* Create the region descriptor */
@@ -360,7 +359,7 @@ cleanup:
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_table_region
*
@@ -370,7 +369,7 @@ cleanup:
*
* DESCRIPTION: Create a new data_table_region object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_table_region (
@@ -455,7 +454,7 @@ cleanup:
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_processor
*
@@ -467,7 +466,7 @@ cleanup:
*
* Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3])
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_processor (
@@ -488,9 +487,8 @@ acpi_ex_create_processor (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /*
- * Initialize the processor object from the operands
- */
+ /* Initialize the processor object from the operands */
+
obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value;
obj_desc->processor.length = (u8) operand[3]->integer.value;
@@ -507,7 +505,7 @@ acpi_ex_create_processor (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_power_resource
*
@@ -519,7 +517,7 @@ acpi_ex_create_processor (
*
* power_resource (Name[0], system_level[1], resource_order[2])
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_power_resource (
@@ -555,10 +553,10 @@ acpi_ex_create_power_resource (
acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
}
-
#endif
-/*****************************************************************************
+
+/*******************************************************************************
*
* FUNCTION: acpi_ex_create_method
*
@@ -570,7 +568,7 @@ acpi_ex_create_power_resource (
*
* DESCRIPTION: Create a new method object
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_ex_create_method (
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index e2f7c32f28d..40850064811 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -51,23 +51,48 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exdump")
+/* Local prototypes */
+
+#ifdef ACPI_FUTURE_USAGE
+static void
+acpi_ex_out_string (
+ char *title,
+ char *value);
+
+static void
+acpi_ex_out_pointer (
+ char *title,
+ void *value);
+
+static void
+acpi_ex_out_integer (
+ char *title,
+ u32 value);
+
+static void
+acpi_ex_out_address (
+ char *title,
+ acpi_physical_address value);
+#endif /* ACPI_FUTURE_USAGE */
+
/*
* The following routines are used for debug output only
*/
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_operand
*
- * PARAMETERS: *obj_desc - Pointer to entry to be dumped
+ * PARAMETERS: *obj_desc - Pointer to entry to be dumped
+ * Depth - Current nesting depth
*
* RETURN: None
*
* DESCRIPTION: Dump an operand object
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ex_dump_operand (
@@ -86,9 +111,8 @@ acpi_ex_dump_operand (
}
if (!obj_desc) {
- /*
- * This could be a null element of a package
- */
+ /* This could be a null element of a package */
+
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
return;
}
@@ -117,6 +141,8 @@ acpi_ex_dump_operand (
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
}
+ /* Decode object type */
+
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
@@ -274,7 +300,9 @@ acpi_ex_dump_operand (
case ACPI_TYPE_STRING:
acpi_os_printf ("String length %X @ %p ",
- obj_desc->string.length, obj_desc->string.pointer);
+ obj_desc->string.length,
+ obj_desc->string.pointer);
+
acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
acpi_os_printf ("\n");
break;
@@ -290,10 +318,13 @@ acpi_ex_dump_operand (
acpi_os_printf (
"region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
- obj_desc->field.bit_length, obj_desc->field.access_byte_width,
+ obj_desc->field.bit_length,
+ obj_desc->field.access_byte_width,
obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
- obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
+ obj_desc->field.base_byte_offset,
+ obj_desc->field.start_field_bit_offset);
+
acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
break;
@@ -308,13 +339,15 @@ acpi_ex_dump_operand (
acpi_os_printf (
"buffer_field: %X bits at byte %X bit %X of \n",
- obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset,
+ obj_desc->buffer_field.bit_length,
+ obj_desc->buffer_field.base_byte_offset,
obj_desc->buffer_field.start_field_bit_offset);
if (!obj_desc->buffer_field.buffer_obj) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
}
- else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) {
+ else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) !=
+ ACPI_TYPE_BUFFER) {
acpi_os_printf ("*not a Buffer* \n");
}
else {
@@ -331,10 +364,10 @@ acpi_ex_dump_operand (
case ACPI_TYPE_METHOD:
- acpi_os_printf (
- "Method(%X) @ %p:%X\n",
+ acpi_os_printf ("Method(%X) @ %p:%X\n",
obj_desc->method.param_count,
- obj_desc->method.aml_start, obj_desc->method.aml_length);
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length);
break;
@@ -379,7 +412,7 @@ acpi_ex_dump_operand (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_operands
*
@@ -393,7 +426,7 @@ acpi_ex_dump_operand (
*
* DESCRIPTION: Dump the object stack
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ex_dump_operands (
@@ -441,10 +474,9 @@ acpi_ex_dump_operands (
#ifdef ACPI_FUTURE_USAGE
-
-/*****************************************************************************
+/*******************************************************************************
*
- * FUNCTION: acpi_ex_out*
+ * FUNCTION: acpi_ex_out* functions
*
* PARAMETERS: Title - Descriptive text
* Value - Value to be displayed
@@ -453,9 +485,9 @@ acpi_ex_dump_operands (
* reduce the number of format strings required and keeps them
* all in one place for easy modification.
*
- ****************************************************************************/
+ ******************************************************************************/
-void
+static void
acpi_ex_out_string (
char *title,
char *value)
@@ -463,7 +495,7 @@ acpi_ex_out_string (
acpi_os_printf ("%20s : %s\n", title, value);
}
-void
+static void
acpi_ex_out_pointer (
char *title,
void *value)
@@ -471,7 +503,7 @@ acpi_ex_out_pointer (
acpi_os_printf ("%20s : %p\n", title, value);
}
-void
+static void
acpi_ex_out_integer (
char *title,
u32 value)
@@ -479,7 +511,7 @@ acpi_ex_out_integer (
acpi_os_printf ("%20s : %X\n", title, value);
}
-void
+static void
acpi_ex_out_address (
char *title,
acpi_physical_address value)
@@ -493,16 +525,16 @@ acpi_ex_out_address (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_node
*
* PARAMETERS: *Node - Descriptor to dump
- * Flags - Force display
+ * Flags - Force display if TRUE
*
* DESCRIPTION: Dumps the members of the given.Node
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ex_dump_node (
@@ -531,16 +563,16 @@ acpi_ex_dump_node (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ex_dump_object_descriptor
*
* PARAMETERS: *Object - Descriptor to dump
- * Flags - Force display
+ * Flags - Force display if TRUE
*
* DESCRIPTION: Dumps the members of the object descriptor given.
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ex_dump_object_descriptor (
@@ -553,6 +585,10 @@ acpi_ex_dump_object_descriptor (
ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");
+ if (!obj_desc) {
+ return_VOID;
+ }
+
if (!flags) {
if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
return_VOID;
@@ -747,11 +783,17 @@ acpi_ex_dump_object_descriptor (
case ACPI_TYPE_LOCAL_REFERENCE:
acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
- acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name);
+ acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (
+ obj_desc->reference.opcode))->name);
acpi_ex_out_integer ("Offset", obj_desc->reference.offset);
acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object);
acpi_ex_out_pointer ("Node", obj_desc->reference.node);
acpi_ex_out_pointer ("Where", obj_desc->reference.where);
+
+ if (obj_desc->reference.object) {
+ acpi_os_printf ("\nReferenced Object:\n");
+ acpi_ex_dump_object_descriptor (obj_desc->reference.object, flags);
+ }
break;
@@ -788,6 +830,5 @@ acpi_ex_dump_object_descriptor (
}
#endif /* ACPI_FUTURE_USAGE */
-
#endif
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index be7f2124fa0..22c8fa480f6 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -120,8 +120,8 @@ acpi_ex_read_data_from_field (
* Note: Smbus protocol value is passed in upper 16-bits of Function
*/
status = acpi_ex_access_region (obj_desc, 0,
- ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
- ACPI_READ | (obj_desc->field.attribute << 16));
+ ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
+ ACPI_READ | (obj_desc->field.attribute << 16));
acpi_ex_release_global_lock (locked);
goto exit;
}
@@ -196,6 +196,7 @@ exit:
*
* PARAMETERS: source_desc - Contains data to write
* obj_desc - The named field
+ * result_desc - Where the return value is returned, if any
*
* RETURN: Status
*
@@ -250,12 +251,15 @@ acpi_ex_write_data_to_field (
if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
acpi_ut_get_object_type_name (source_desc)));
+
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
- ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n",
+ ACPI_REPORT_ERROR ((
+ "SMBus write requires Buffer of length %X, found length %X\n",
ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
+
return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
}
@@ -265,14 +269,16 @@ acpi_ex_write_data_to_field (
}
buffer = buffer_desc->buffer.pointer;
- ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE);
+ ACPI_MEMCPY (buffer, source_desc->buffer.pointer,
+ ACPI_SMBUS_BUFFER_SIZE);
/* Lock entire transaction if requested */
locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
/*
- * Perform the write (returns status and perhaps data in the same buffer)
+ * Perform the write (returns status and perhaps data in the
+ * same buffer)
* Note: SMBus protocol type is passed in upper 16-bits of Function.
*/
status = acpi_ex_access_region (obj_desc, 0,
@@ -284,9 +290,8 @@ acpi_ex_write_data_to_field (
return_ACPI_STATUS (status);
}
- /*
- * Get a pointer to the data to be written
- */
+ /* Get a pointer to the data to be written */
+
switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
case ACPI_TYPE_INTEGER:
buffer = &source_desc->integer.value;
@@ -314,7 +319,8 @@ acpi_ex_write_data_to_field (
* the ACPI specification.
*/
new_buffer = NULL;
- required_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
+ required_length = ACPI_ROUND_BITS_UP_TO_BYTES (
+ obj_desc->common_field.bit_length);
if (length < required_length) {
/* We need to create a new buffer */
@@ -338,6 +344,7 @@ acpi_ex_write_data_to_field (
"field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
+
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 9d0f9d2e906..3c2f89e00f7 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -52,12 +52,31 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exfldio")
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_field_datum_io (
+ union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset,
+ acpi_integer *value,
+ u32 read_write);
+
+static u8
+acpi_ex_register_overflow (
+ union acpi_operand_object *obj_desc,
+ acpi_integer value);
+
+static acpi_status
+acpi_ex_setup_region (
+ union acpi_operand_object *obj_desc,
+ u32 field_datum_byte_offset);
+
/*******************************************************************************
*
* FUNCTION: acpi_ex_setup_region
*
- * PARAMETERS: *obj_desc - Field to be read or written
+ * PARAMETERS: obj_desc - Field to be read or written
* field_datum_byte_offset - Byte offset of this datum within the
* parent field
*
@@ -69,7 +88,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_setup_region (
union acpi_operand_object *obj_desc,
u32 field_datum_byte_offset)
@@ -127,9 +146,9 @@ acpi_ex_setup_region (
* length of one field datum (access width) must fit within the region.
* (Region length is specified in bytes)
*/
- if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
- + field_datum_byte_offset
- + obj_desc->common_field.access_byte_width)) {
+ if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
+ field_datum_byte_offset +
+ obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpreter_slack) {
/*
* Slack mode only: We will go ahead and allow access to this
@@ -155,7 +174,8 @@ acpi_ex_setup_region (
"Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
acpi_ut_get_node_name (obj_desc->common_field.node),
obj_desc->common_field.access_byte_width,
- acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+ acpi_ut_get_node_name (rgn_desc->region.node),
+ rgn_desc->region.length));
}
/*
@@ -167,7 +187,8 @@ acpi_ex_setup_region (
acpi_ut_get_node_name (obj_desc->common_field.node),
obj_desc->common_field.base_byte_offset,
field_datum_byte_offset, obj_desc->common_field.access_byte_width,
- acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+ acpi_ut_get_node_name (rgn_desc->region.node),
+ rgn_desc->region.length));
return_ACPI_STATUS (AE_AML_REGION_LIMIT);
}
@@ -180,10 +201,10 @@ acpi_ex_setup_region (
*
* FUNCTION: acpi_ex_access_region
*
- * PARAMETERS: *obj_desc - Field to be read
+ * PARAMETERS: obj_desc - Field to be read
* field_datum_byte_offset - Byte offset of this datum within the
* parent field
- * *Value - Where to store value (must at least
+ * Value - Where to store value (must at least
* the size of acpi_integer)
* Function - Read or Write flag plus other region-
* dependent flags
@@ -226,9 +247,9 @@ acpi_ex_access_region (
* 3) The current offset into the field
*/
rgn_desc = obj_desc->common_field.region_obj;
- address = rgn_desc->region.address
- + obj_desc->common_field.base_byte_offset
- + field_datum_byte_offset;
+ address = rgn_desc->region.address +
+ obj_desc->common_field.base_byte_offset +
+ field_datum_byte_offset;
if ((function & ACPI_IO_MASK) == ACPI_READ) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
@@ -249,7 +270,8 @@ acpi_ex_access_region (
/* Invoke the appropriate address_space/op_region handler */
status = acpi_ev_address_space_dispatch (rgn_desc, function,
- address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
+ address,
+ ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
if (ACPI_FAILURE (status)) {
if (status == AE_NOT_IMPLEMENTED) {
@@ -274,7 +296,7 @@ acpi_ex_access_region (
*
* FUNCTION: acpi_ex_register_overflow
*
- * PARAMETERS: *obj_desc - Register(Field) to be written
+ * PARAMETERS: obj_desc - Register(Field) to be written
* Value - Value to be stored
*
* RETURN: TRUE if value overflows the field, FALSE otherwise
@@ -287,7 +309,7 @@ acpi_ex_access_region (
*
******************************************************************************/
-u8
+static u8
acpi_ex_register_overflow (
union acpi_operand_object *obj_desc,
acpi_integer value)
@@ -319,10 +341,10 @@ acpi_ex_register_overflow (
*
* FUNCTION: acpi_ex_field_datum_io
*
- * PARAMETERS: *obj_desc - Field to be read
+ * PARAMETERS: obj_desc - Field to be read
* field_datum_byte_offset - Byte offset of this datum within the
* parent field
- * *Value - Where to store value (must be 64 bits)
+ * Value - Where to store value (must be 64 bits)
* read_write - Read or Write flag
*
* RETURN: Status
@@ -333,7 +355,7 @@ acpi_ex_register_overflow (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_field_datum_io (
union acpi_operand_object *obj_desc,
u32 field_datum_byte_offset,
@@ -350,7 +372,9 @@ acpi_ex_field_datum_io (
if (read_write == ACPI_READ) {
if (!value) {
local_value = 0;
- value = &local_value; /* To support reads without saving return value */
+
+ /* To support reads without saving return value */
+ value = &local_value;
}
/* Clear the entire return buffer first, [Very Important!] */
@@ -363,8 +387,10 @@ acpi_ex_field_datum_io (
*
* buffer_field - Read/write from/to a Buffer
* region_field - Read/write from/to a Operation Region.
- * bank_field - Write to a Bank Register, then read/write from/to an op_region
- * index_field - Write to an Index Register, then read/write from/to a Data Register
+ * bank_field - Write to a Bank Register, then read/write from/to an
+ * operation_region
+ * index_field - Write to an Index Register, then read/write from/to a
+ * Data Register
*/
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_BUFFER_FIELD:
@@ -384,19 +410,20 @@ acpi_ex_field_datum_io (
* Copy the data from the source buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
- + obj_desc->buffer_field.base_byte_offset
- + field_datum_byte_offset,
- obj_desc->common_field.access_byte_width);
+ ACPI_MEMCPY (value,
+ (obj_desc->buffer_field.buffer_obj)->buffer.pointer +
+ obj_desc->buffer_field.base_byte_offset +
+ field_datum_byte_offset,
+ obj_desc->common_field.access_byte_width);
}
else {
/*
* Copy the data to the target buffer.
* Length is the field width in bytes.
*/
- ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
- + obj_desc->buffer_field.base_byte_offset
- + field_datum_byte_offset,
+ ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer +
+ obj_desc->buffer_field.base_byte_offset +
+ field_datum_byte_offset,
value, obj_desc->common_field.access_byte_width);
}
@@ -406,8 +433,10 @@ acpi_ex_field_datum_io (
case ACPI_TYPE_LOCAL_BANK_FIELD:
- /* Ensure that the bank_value is not beyond the capacity of the register */
-
+ /*
+ * Ensure that the bank_value is not beyond the capacity of
+ * the register
+ */
if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
(acpi_integer) obj_desc->bank_field.value)) {
return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
@@ -445,8 +474,10 @@ acpi_ex_field_datum_io (
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- /* Ensure that the index_value is not beyond the capacity of the register */
-
+ /*
+ * Ensure that the index_value is not beyond the capacity of
+ * the register
+ */
if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
(acpi_integer) obj_desc->index_field.value)) {
return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
@@ -496,14 +527,16 @@ acpi_ex_field_datum_io (
if (ACPI_SUCCESS (status)) {
if (read_write == ACPI_READ) {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
- ACPI_FORMAT_UINT64 (*value),
- obj_desc->common_field.access_byte_width));
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Value Read %8.8X%8.8X, Width %d\n",
+ ACPI_FORMAT_UINT64 (*value),
+ obj_desc->common_field.access_byte_width));
}
else {
- ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
- ACPI_FORMAT_UINT64 (*value),
- obj_desc->common_field.access_byte_width));
+ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+ "Value Written %8.8X%8.8X, Width %d\n",
+ ACPI_FORMAT_UINT64 (*value),
+ obj_desc->common_field.access_byte_width));
}
}
@@ -515,8 +548,10 @@ acpi_ex_field_datum_io (
*
* FUNCTION: acpi_ex_write_with_update_rule
*
- * PARAMETERS: *obj_desc - Field to be set
- * Value - Value to store
+ * PARAMETERS: obj_desc - Field to be written
+ * Mask - bitmask within field datum
+ * field_value - Value to write
+ * field_datum_byte_offset - Offset of datum within field
*
* RETURN: Status
*
@@ -689,7 +724,8 @@ acpi_ex_extract_from_field (
/* Merge with previous datum if necessary */
merged_datum |= raw_datum <<
- (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+ (obj_desc->common_field.access_bit_width -
+ obj_desc->common_field.start_field_bit_offset);
if (i == datum_count) {
break;
@@ -707,7 +743,8 @@ acpi_ex_extract_from_field (
/* Mask off any extra bits in the last datum */
- buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width;
+ buffer_tail_bits = obj_desc->common_field.bit_length %
+ obj_desc->common_field.access_bit_width;
if (buffer_tail_bits) {
merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
}
@@ -791,7 +828,8 @@ acpi_ex_insert_into_field (
/* Write merged datum to the target field */
merged_datum &= mask;
- status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+ status = acpi_ex_write_with_update_rule (obj_desc, mask,
+ merged_datum, field_offset);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -800,7 +838,8 @@ acpi_ex_insert_into_field (
field_offset += obj_desc->common_field.access_byte_width;
merged_datum = raw_datum >>
- (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+ (obj_desc->common_field.access_bit_width -
+ obj_desc->common_field.start_field_bit_offset);
mask = ACPI_INTEGER_MAX;
if (i == datum_count) {
@@ -819,7 +858,8 @@ acpi_ex_insert_into_field (
/* Mask off any extra bits in the last datum */
buffer_tail_bits = (obj_desc->common_field.bit_length +
- obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width;
+ obj_desc->common_field.start_field_bit_offset) %
+ obj_desc->common_field.access_bit_width;
if (buffer_tail_bits) {
mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
}
@@ -827,7 +867,8 @@ acpi_ex_insert_into_field (
/* Write the last datum to the field */
merged_datum &= mask;
- status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+ status = acpi_ex_write_with_update_rule (obj_desc,
+ mask, merged_datum, field_offset);
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index b542dcd58c0..022f281345b 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -139,8 +139,9 @@ acpi_ex_get_object_reference (
reference_obj->reference.object = referenced_obj;
*return_desc = reference_obj;
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
- obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Object %p Type [%s], returning Reference %p\n",
+ obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
return_ACPI_STATUS (AE_OK);
}
@@ -456,7 +457,7 @@ acpi_ex_do_math_op (
return (integer0 * integer1);
- case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
+ case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result)*/
return (integer0 << integer1);
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 68c4bb1970a..c3cb714d2cb 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -49,6 +49,13 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exmutex")
+/* Local prototypes */
+
+static void
+acpi_ex_link_mutex (
+ union acpi_operand_object *obj_desc,
+ struct acpi_thread_state *thread);
+
/*******************************************************************************
*
@@ -56,7 +63,7 @@
*
* PARAMETERS: obj_desc - The mutex to be unlinked
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Remove a mutex from the "acquired_mutex" list
*
@@ -92,16 +99,16 @@ acpi_ex_unlink_mutex (
*
* FUNCTION: acpi_ex_link_mutex
*
- * PARAMETERS: obj_desc - The mutex to be linked
- * list_head - head of the "acquired_mutex" list
+ * PARAMETERS: obj_desc - The mutex to be linked
+ * Thread - Current executing thread object
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk
*
******************************************************************************/
-void
+static void
acpi_ex_link_mutex (
union acpi_operand_object *obj_desc,
struct acpi_thread_state *thread)
@@ -132,8 +139,9 @@ acpi_ex_link_mutex (
*
* FUNCTION: acpi_ex_acquire_mutex
*
- * PARAMETERS: time_desc - The 'time to delay' object descriptor
- * obj_desc - The object descriptor for this op
+ * PARAMETERS: time_desc - Timeout integer
+ * obj_desc - Mutex object
+ * walk_state - Current method execution state
*
* RETURN: Status
*
@@ -161,7 +169,7 @@ acpi_ex_acquire_mutex (
if (!walk_state->thread) {
ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
+ acpi_ut_get_node_name (obj_desc->mutex.node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -170,8 +178,9 @@ acpi_ex_acquire_mutex (
* mutex. This mechanism provides some deadlock prevention
*/
if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
- ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
+ ACPI_REPORT_ERROR ((
+ "Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
+ acpi_ut_get_node_name (obj_desc->mutex.node)));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
@@ -180,8 +189,10 @@ acpi_ex_acquire_mutex (
if (obj_desc->mutex.owner_thread) {
/* Special case for Global Lock, allow all threads */
- if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
- (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
+ if ((obj_desc->mutex.owner_thread->thread_id ==
+ walk_state->thread->thread_id) ||
+ (obj_desc->mutex.semaphore ==
+ acpi_gbl_global_lock_semaphore)) {
/*
* The mutex is already owned by this thread,
* just increment the acquisition depth
@@ -221,6 +232,7 @@ acpi_ex_acquire_mutex (
* FUNCTION: acpi_ex_release_mutex
*
* PARAMETERS: obj_desc - The object descriptor for this op
+ * walk_state - Current method execution state
*
* RETURN: Status
*
@@ -278,8 +290,9 @@ acpi_ex_release_mutex (
* equal to the current sync level
*/
if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
- ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
- acpi_ut_get_node_name (obj_desc->mutex.node)));
+ ACPI_REPORT_ERROR ((
+ "Cannot release Mutex [%4.4s], incorrect sync_level\n",
+ acpi_ut_get_node_name (obj_desc->mutex.node)));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
@@ -313,11 +326,11 @@ acpi_ex_release_mutex (
*
* FUNCTION: acpi_ex_release_all_mutexes
*
- * PARAMETERS: mutex_list - Head of the mutex list
+ * PARAMETERS: Thread - Current executing thread object
*
* RETURN: Status
*
- * DESCRIPTION: Release all mutexes in the list
+ * DESCRIPTION: Release all mutexes held by this thread
*
******************************************************************************/
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index 7911c533c26..639f0bd3f6d 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -50,13 +50,17 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exnames")
+/* Local prototypes */
-/* AML Package Length encodings */
+static char *
+acpi_ex_allocate_name_string (
+ u32 prefix_count,
+ u32 num_name_segs);
-#define ACPI_AML_PACKAGE_TYPE1 0x40
-#define ACPI_AML_PACKAGE_TYPE2 0x4000
-#define ACPI_AML_PACKAGE_TYPE3 0x400000
-#define ACPI_AML_PACKAGE_TYPE4 0x40000000
+static acpi_status
+acpi_ex_name_segment (
+ u8 **in_aml_address,
+ char *name_string);
/*******************************************************************************
@@ -64,7 +68,7 @@
* FUNCTION: acpi_ex_allocate_name_string
*
* PARAMETERS: prefix_count - Count of parent levels. Special cases:
- * (-1) = root, 0 = none
+ * (-1)==root, 0==none
* num_name_segs - count of 4-character name segments
*
* RETURN: A pointer to the allocated string segment. This segment must
@@ -75,7 +79,7 @@
*
******************************************************************************/
-char *
+static char *
acpi_ex_allocate_name_string (
u32 prefix_count,
u32 num_name_segs)
@@ -88,7 +92,7 @@ acpi_ex_allocate_name_string (
/*
- * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
+ * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
* Also, one byte for the null terminator.
* This may actually be somewhat longer than needed.
*/
@@ -107,7 +111,8 @@ acpi_ex_allocate_name_string (
*/
name_string = ACPI_MEM_ALLOCATE (size_needed);
if (!name_string) {
- ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
+ ACPI_REPORT_ERROR ((
+ "ex_allocate_name_string: Could not allocate size %d\n", size_needed));
return_PTR (NULL);
}
@@ -152,15 +157,17 @@ acpi_ex_allocate_name_string (
*
* FUNCTION: acpi_ex_name_segment
*
- * PARAMETERS: interpreter_mode - Current running mode (load1/Load2/Exec)
+ * PARAMETERS: in_aml_address - Pointer to the name in the AML code
+ * name_string - Where to return the name. The name is appended
+ * to any existing string to form a namepath
*
* RETURN: Status
*
- * DESCRIPTION: Execute a name segment (4 bytes)
+ * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_name_segment (
u8 **in_aml_address,
char *name_string)
@@ -223,10 +230,13 @@ acpi_ex_name_segment (
status = AE_CTRL_PENDING;
}
else {
- /* Segment started with one or more valid characters, but fewer than 4 */
-
+ /*
+ * Segment started with one or more valid characters, but fewer than
+ * the required 4
+ */
status = AE_AML_BAD_NAME;
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Bad character %02x in name, at %p\n",
*aml_address, aml_address));
}
@@ -239,11 +249,16 @@ acpi_ex_name_segment (
*
* FUNCTION: acpi_ex_get_name_string
*
- * PARAMETERS: data_type - Data type to be associated with this name
+ * PARAMETERS: data_type - Object type to be associated with this
+ * name
+ * in_aml_address - Pointer to the namestring in the AML code
+ * out_name_string - Where the namestring is returned
+ * out_name_length - Length of the returned string
*
- * RETURN: Status
+ * RETURN: Status, namestring and length
*
- * DESCRIPTION: Get a name, including any prefixes.
+ * DESCRIPTION: Extract a full namepath from the AML byte stream,
+ * including any prefixes.
*
******************************************************************************/
@@ -286,7 +301,8 @@ acpi_ex_get_name_string (
switch (*aml_address) {
case AML_ROOT_PREFIX:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n",
+ aml_address));
/*
* Remember that we have a root_prefix --
@@ -303,7 +319,8 @@ acpi_ex_get_name_string (
/* Increment past possibly multiple parent prefixes */
do {
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n",
+ aml_address));
aml_address++;
prefix_count++;
@@ -321,13 +338,13 @@ acpi_ex_get_name_string (
break;
}
-
/* Examine first character of name for name segment prefix operator */
switch (*aml_address) {
case AML_DUAL_NAME_PREFIX:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n",
+ aml_address));
aml_address++;
name_string = acpi_ex_allocate_name_string (prefix_count, 2);
@@ -349,7 +366,8 @@ acpi_ex_get_name_string (
case AML_MULTI_NAME_PREFIX_OP:
- ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
+ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n",
+ aml_address));
/* Fetch count of segments remaining in name path */
@@ -368,7 +386,8 @@ acpi_ex_get_name_string (
has_prefix = TRUE;
while (num_segments &&
- (status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
+ (status = acpi_ex_name_segment (&aml_address, name_string)) ==
+ AE_OK) {
num_segments--;
}
@@ -380,7 +399,8 @@ acpi_ex_get_name_string (
/* null_name valid as of 8-12-98 ASL/AML Grammar Update */
if (prefix_count == ACPI_UINT32_MAX) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "name_seg is \"\\\" followed by NULL\n"));
}
/* Consume the NULL byte */
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 8482aefaf38..dbdf8262ba0 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -97,7 +97,8 @@ acpi_ex_opcode_0A_0T_1R (
union acpi_operand_object *return_desc = NULL;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
@@ -161,7 +162,8 @@ acpi_ex_opcode_1A_0T_0R (
acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
@@ -236,7 +238,8 @@ acpi_ex_opcode_1A_1T_0R (
union acpi_operand_object **operand = &walk_state->operands[0];
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
@@ -289,7 +292,8 @@ acpi_ex_opcode_1A_1T_1R (
acpi_integer digit;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
@@ -409,8 +413,10 @@ acpi_ex_opcode_1A_1T_1R (
for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
(void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
- /* Insert the BCD digit that resides in the remainder from above */
-
+ /*
+ * Insert the BCD digit that resides in the
+ * remainder from above
+ */
return_desc->integer.value |= (((acpi_integer) temp32) <<
ACPI_MUL_4 (i));
}
@@ -445,7 +451,8 @@ acpi_ex_opcode_1A_1T_1R (
/* Get the object reference, store it, and remove our reference */
- status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
+ status = acpi_ex_get_object_reference (operand[0],
+ &return_desc2, walk_state);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
@@ -482,10 +489,10 @@ acpi_ex_opcode_1A_1T_1R (
if (!walk_state->result_obj) {
/*
- * Normally, we would remove a reference on the Operand[0] parameter;
- * But since it is being used as the internal return object
- * (meaning we would normally increment it), the two cancel out,
- * and we simply don't do anything.
+ * Normally, we would remove a reference on the Operand[0]
+ * parameter; But since it is being used as the internal return
+ * object (meaning we would normally increment it), the two
+ * cancel out, and we simply don't do anything.
*/
walk_state->result_obj = operand[0];
walk_state->operands[0] = NULL; /* Prevent deletion */
@@ -549,9 +556,8 @@ acpi_ex_opcode_1A_1T_1R (
case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */
case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */
- /*
- * These are two obsolete opcodes
- */
+ /* These are two obsolete opcodes */
+
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"%s is obsolete and not implemented\n",
acpi_ps_get_opcode_name (walk_state->opcode)));
@@ -568,9 +574,8 @@ acpi_ex_opcode_1A_1T_1R (
}
if (ACPI_SUCCESS (status)) {
- /*
- * Store the return value computed above into the target object
- */
+ /* Store the return value computed above into the target object */
+
status = acpi_ex_store (return_desc, operand[1], walk_state);
}
@@ -615,7 +620,8 @@ acpi_ex_opcode_1A_0T_1R (
acpi_integer value;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
@@ -706,9 +712,9 @@ acpi_ex_opcode_1A_0T_1R (
/*
* Note: The operand is not resolved at this point because we want to
- * get the associated object, not its value. For example, we don't want
- * to resolve a field_unit to its value, we want the actual field_unit
- * object.
+ * get the associated object, not its value. For example, we don't
+ * want to resolve a field_unit to its value, we want the actual
+ * field_unit object.
*/
/* Get the type of the base object */
@@ -738,7 +744,8 @@ acpi_ex_opcode_1A_0T_1R (
/* Get the base object */
- status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
+ status = acpi_ex_resolve_multiple (walk_state,
+ operand[0], &type, &temp_desc);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
@@ -818,8 +825,10 @@ acpi_ex_opcode_1A_0T_1R (
/* Set Operand[0] to the value of the local/arg */
- status = acpi_ds_method_data_get_value (operand[0]->reference.opcode,
- operand[0]->reference.offset, walk_state, &temp_desc);
+ status = acpi_ds_method_data_get_value (
+ operand[0]->reference.opcode,
+ operand[0]->reference.offset,
+ walk_state, &temp_desc);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
@@ -852,21 +861,26 @@ acpi_ex_opcode_1A_0T_1R (
case ACPI_TYPE_STRING:
/*
- * This is a deref_of (String). The string is a reference to a named ACPI object.
+ * This is a deref_of (String). The string is a reference
+ * to a named ACPI object.
*
* 1) Find the owning Node
- * 2) Dereference the node to an actual object. Could be a Field, so we nee
- * to resolve the node to a value.
+ * 2) Dereference the node to an actual object. Could be a
+ * Field, so we need to resolve the node to a value.
*/
status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
- walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT,
- ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc));
+ walk_state->scope_info->scope.node,
+ ACPI_NS_SEARCH_PARENT,
+ ACPI_CAST_INDIRECT_PTR (
+ struct acpi_namespace_node, &return_desc));
if (ACPI_FAILURE (status)) {
goto cleanup;
}
status = acpi_ex_resolve_node_to_value (
- ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state);
+ ACPI_CAST_INDIRECT_PTR (
+ struct acpi_namespace_node, &return_desc),
+ walk_state);
goto cleanup;
@@ -883,14 +897,16 @@ acpi_ex_opcode_1A_0T_1R (
/*
* This is a deref_of (object_reference)
* Get the actual object from the Node (This is the dereference).
- * -- This case may only happen when a local_x or arg_x is dereferenced above.
+ * This case may only happen when a local_x or arg_x is
+ * dereferenced above.
*/
- return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]);
+ return_desc = acpi_ns_get_attached_object (
+ (struct acpi_namespace_node *) operand[0]);
}
else {
/*
- * This must be a reference object produced by either the Index() or
- * ref_of() operator
+ * This must be a reference object produced by either the
+ * Index() or ref_of() operator
*/
switch (operand[0]->reference.opcode) {
case AML_INDEX_OP:
@@ -931,8 +947,8 @@ acpi_ex_opcode_1A_0T_1R (
case ACPI_TYPE_PACKAGE:
/*
- * Return the referenced element of the package. We must add
- * another reference to the referenced object, however.
+ * Return the referenced element of the package. We must
+ * add another reference to the referenced object, however.
*/
return_desc = *(operand[0]->reference.where);
if (!return_desc) {
@@ -967,9 +983,11 @@ acpi_ex_opcode_1A_0T_1R (
return_desc = operand[0]->reference.object;
- if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) ==
+ ACPI_DESC_TYPE_NAMED) {
- return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc);
+ return_desc = acpi_ns_get_attached_object (
+ (struct acpi_namespace_node *) return_desc);
}
/* Add another reference to the object! */
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 8be4d80ceed..7429032c2b6 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -118,7 +118,7 @@ acpi_ex_opcode_2A_0T_0R (
value = (u32) operand[1]->integer.value;
- /* Notifies allowed on this object? */
+ /* Are notifies allowed on this object? */
if (!acpi_ev_is_notify_object (node)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -203,11 +203,12 @@ acpi_ex_opcode_2A_2T_1R (
acpi_ps_get_opcode_name (walk_state->opcode));
- /*
- * Execute the opcode
- */
+ /* Execute the opcode */
+
switch (walk_state->opcode) {
- case AML_DIVIDE_OP: /* Divide (Dividend, Divisor, remainder_result quotient_result) */
+ case AML_DIVIDE_OP:
+
+ /* Divide (Dividend, Divisor, remainder_result quotient_result) */
return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc1) {
@@ -241,7 +242,6 @@ acpi_ex_opcode_2A_2T_1R (
goto cleanup;
}
-
/* Store the results to the target reference operands */
status = acpi_ex_store (return_desc2, operand[2], walk_state);
@@ -295,7 +295,7 @@ acpi_ex_opcode_2A_1T_1R (
{
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *return_desc = NULL;
- u32 index;
+ acpi_integer index;
acpi_status status = AE_OK;
acpi_size length;
@@ -304,9 +304,8 @@ acpi_ex_opcode_2A_1T_1R (
acpi_ps_get_opcode_name (walk_state->opcode));
- /*
- * Execute the opcode
- */
+ /* Execute the opcode */
+
if (walk_state->op_info->flags & AML_MATH) {
/* All simple math opcodes (add, etc.) */
@@ -322,9 +321,8 @@ acpi_ex_opcode_2A_1T_1R (
goto store_result_to_target;
}
-
switch (walk_state->opcode) {
- case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
+ case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
@@ -341,18 +339,19 @@ acpi_ex_opcode_2A_1T_1R (
break;
- case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
+ case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
status = acpi_ex_do_concatenate (operand[0], operand[1],
&return_desc, walk_state);
break;
- case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
+ case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
/*
* Input object is guaranteed to be a buffer at this point (it may have
- * been converted.) Copy the raw buffer data to a new object of type String.
+ * been converted.) Copy the raw buffer data to a new object of
+ * type String.
*/
/*
@@ -383,14 +382,16 @@ acpi_ex_opcode_2A_1T_1R (
goto cleanup;
}
- /* Copy the raw buffer data with no transform. NULL terminated already. */
+ /* Copy the raw buffer data with no transform. NULL terminated already*/
ACPI_MEMCPY (return_desc->string.pointer,
operand[0]->buffer.pointer, length);
break;
- case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
+ case AML_CONCAT_RES_OP:
+
+ /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
status = acpi_ex_concat_template (operand[0], operand[1],
&return_desc, walk_state);
@@ -407,33 +408,33 @@ acpi_ex_opcode_2A_1T_1R (
goto cleanup;
}
- index = (u32) operand[1]->integer.value;
+ index = operand[1]->integer.value;
+
+ /* At this point, the Source operand is a Package, Buffer, or String */
- /*
- * At this point, the Source operand is a Package, Buffer, or String
- */
if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index value (%X) beyond package end (%X)\n",
- index, operand[0]->package.count));
+ "Index value (%X%8.8X) beyond package end (%X)\n",
+ ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
return_desc->reference.object = operand[0];
- return_desc->reference.where = &operand[0]->package.elements [index];
+ return_desc->reference.where = &operand[0]->package.elements [
+ index];
}
else {
/* Object to be indexed is a Buffer/String */
if (index >= operand[0]->buffer.length) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Index value (%X) beyond end of buffer (%X)\n",
- index, operand[0]->buffer.length));
+ "Index value (%X%8.8X) beyond end of buffer (%X)\n",
+ ACPI_FORMAT_UINT64 (index), operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
}
@@ -451,7 +452,7 @@ acpi_ex_opcode_2A_1T_1R (
/* Complete the Index reference object */
return_desc->reference.opcode = AML_INDEX_OP;
- return_desc->reference.offset = index;
+ return_desc->reference.offset = (u32) index;
/* Store the reference to the Target */
@@ -536,22 +537,24 @@ acpi_ex_opcode_2A_0T_1R (
goto cleanup;
}
- /*
- * Execute the Opcode
- */
- if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
+ /* Execute the Opcode */
+
+ if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
+ /* logical_op (Operand0, Operand1) */
+
status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
operand[0]->integer.value, operand[1]->integer.value,
&logical_result);
goto store_logical_result;
}
- else if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
+ else if (walk_state->op_info->flags & AML_LOGICAL) {
+ /* logical_op (Operand0, Operand1) */
+
status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
operand[1], &logical_result);
goto store_logical_result;
}
-
switch (walk_state->opcode) {
case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index 29d0b167745..23b068adbf5 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -97,11 +97,12 @@ acpi_ex_opcode_3A_0T_0R (
acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
switch (walk_state->opcode) {
- case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
+ case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
@@ -116,9 +117,8 @@ acpi_ex_opcode_3A_0T_0R (
fatal->argument = (u32) operand[2]->integer.value;
}
- /*
- * Always signal the OS!
- */
+ /* Always signal the OS! */
+
status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
/* Might return while OS is shutting down, just continue */
@@ -162,21 +162,23 @@ acpi_ex_opcode_3A_1T_1R (
union acpi_operand_object *return_desc = NULL;
char *buffer;
acpi_status status = AE_OK;
- acpi_native_uint index;
+ acpi_integer index;
acpi_size length;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
switch (walk_state->opcode) {
- case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
+ case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
/*
* Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
- return_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (operand[0]));
+ return_desc = acpi_ut_create_internal_object (
+ ACPI_GET_OBJECT_TYPE (operand[0]));
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -184,7 +186,7 @@ acpi_ex_opcode_3A_1T_1R (
/* Get the Integer values from the objects */
- index = (acpi_native_uint) operand[1]->integer.value;
+ index = operand[1]->integer.value;
length = (acpi_size) operand[2]->integer.value;
/*
@@ -197,7 +199,8 @@ acpi_ex_opcode_3A_1T_1R (
if ((index + length) >
operand[0]->string.length) {
- length = (acpi_size) operand[0]->string.length - index;
+ length = (acpi_size) operand[0]->string.length -
+ (acpi_size) index;
}
/* Allocate a new buffer for the String/Buffer */
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index d3262433162..17f81d42ee4 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -75,6 +75,14 @@
* fully resolved operands.
!*/
+/* Local prototypes */
+
+static u8
+acpi_ex_do_match (
+ u32 match_op,
+ union acpi_operand_object *package_obj,
+ union acpi_operand_object *match_obj);
+
/*******************************************************************************
*
@@ -92,7 +100,7 @@
*
******************************************************************************/
-u8
+static u8
acpi_ex_do_match (
u32 match_op,
union acpi_operand_object *package_obj,
@@ -216,11 +224,12 @@ acpi_ex_opcode_6A_0T_1R (
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *return_desc = NULL;
acpi_status status = AE_OK;
- u32 index;
+ acpi_integer index;
union acpi_operand_object *this_element;
- ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+ ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R",
+ acpi_ps_get_opcode_name (walk_state->opcode));
switch (walk_state->opcode) {
@@ -241,9 +250,11 @@ acpi_ex_opcode_6A_0T_1R (
/* Get the package start_index, validate against the package length */
- index = (u32) operand[5]->integer.value;
- if (index >= (u32) operand[0]->package.count) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
+ index = operand[5]->integer.value;
+ if (index >= operand[0]->package.count) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Index (%X%8.8X) beyond package end (%X)\n",
+ ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
@@ -314,13 +325,12 @@ acpi_ex_opcode_6A_0T_1R (
default:
- ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
+ ACPI_REPORT_ERROR (("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n",
walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
-
walk_state->result_obj = return_desc;
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index 264ef3bba31..c9e3c68b554 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -52,8 +52,23 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exprep")
+/* Local prototypes */
+
+static u32
+acpi_ex_decode_field_access (
+ union acpi_operand_object *obj_desc,
+ u8 field_flags,
+ u32 *return_byte_alignment);
+
#ifdef ACPI_UNDER_DEVELOPMENT
+
+static u32
+acpi_ex_generate_access (
+ u32 field_bit_offset,
+ u32 field_bit_length,
+ u32 region_length);
+
/*******************************************************************************
*
* FUNCTION: acpi_ex_generate_access
@@ -99,12 +114,14 @@ acpi_ex_generate_access (
/* Round Field start offset and length to "minimal" byte boundaries */
field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
- field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8));
+ field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length +
+ field_bit_offset, 8));
field_byte_length = field_byte_end_offset - field_byte_offset;
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Bit length %d, Bit offset %d\n",
field_bit_length, field_bit_offset));
+
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Byte Length %d, Byte Offset %d, End Offset %d\n",
field_byte_length, field_byte_offset, field_byte_end_offset));
@@ -117,20 +134,26 @@ acpi_ex_generate_access (
*/
for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
/*
- * 1) Round end offset up to next access boundary and make sure that this
- * does not go beyond the end of the parent region.
- * 2) When the Access width is greater than the field_byte_length, we are done.
- * (This does not optimize for the perfectly aligned case yet).
+ * 1) Round end offset up to next access boundary and make sure that
+ * this does not go beyond the end of the parent region.
+ * 2) When the Access width is greater than the field_byte_length, we
+ * are done. (This does not optimize for the perfectly aligned
+ * case yet).
*/
if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
- field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
- access_byte_width;
- field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
- access_byte_width) / access_byte_width;
- accesses = field_end_offset - field_start_offset;
+ field_start_offset =
+ ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
+ access_byte_width;
+
+ field_end_offset =
+ ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
+ access_byte_width) / access_byte_width;
+
+ accesses = field_end_offset - field_start_offset;
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"access_width %d end is within region\n", access_byte_width));
+
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field Start %d, Field End %d -- requires %d accesses\n",
field_start_offset, field_end_offset, accesses));
@@ -139,8 +162,8 @@ acpi_ex_generate_access (
if (accesses <= 1) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "Entire field can be accessed with one operation of size %d\n",
- access_byte_width));
+ "Entire field can be accessed with one operation of size %d\n",
+ access_byte_width));
return_VALUE (access_byte_width);
}
@@ -155,15 +178,20 @@ acpi_ex_generate_access (
}
else {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
- "access_width %d end is NOT within region\n", access_byte_width));
+ "access_width %d end is NOT within region\n", access_byte_width));
if (access_byte_width == 1) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field goes beyond end-of-region!\n"));
- return_VALUE (0); /* Field does not fit in the region at all */
- }
- /* This width goes beyond the end-of-region, back off to previous access */
+ /* Field does not fit in the region at all */
+ return_VALUE (0);
+ }
+
+ /*
+ * This width goes beyond the end-of-region, back off to
+ * previous access
+ */
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Backing off to previous optimal access width of %d\n",
minimum_access_width));
@@ -171,8 +199,10 @@ acpi_ex_generate_access (
}
}
- /* Could not read/write field with one operation, just use max access width */
-
+ /*
+ * Could not read/write field with one operation,
+ * just use max access width
+ */
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Cannot access field in one operation, using width 8\n"));
return_VALUE (8);
@@ -184,8 +214,9 @@ acpi_ex_generate_access (
*
* FUNCTION: acpi_ex_decode_field_access
*
- * PARAMETERS: Access - Encoded field access bits
- * Length - Field length.
+ * PARAMETERS: obj_desc - Field object
+ * field_flags - Encoded fieldflags (contains access bits)
+ * return_byte_alignment - Where the byte alignment is returned
*
* RETURN: Field granularity (8, 16, 32 or 64) and
* byte_alignment (1, 2, 3, or 4)
@@ -214,9 +245,10 @@ acpi_ex_decode_field_access (
case AML_FIELD_ACCESS_ANY:
#ifdef ACPI_UNDER_DEVELOPMENT
- byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
- obj_desc->common_field.bit_length,
- 0xFFFFFFFF /* Temp until we pass region_length as param */);
+ byte_alignment =
+ acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
+ obj_desc->common_field.bit_length,
+ 0xFFFFFFFF /* Temp until we pass region_length as parameter */);
bit_length = byte_alignment * 8;
#endif
@@ -276,6 +308,7 @@ acpi_ex_decode_field_access (
* field_flags - Access, lock_rule, and update_rule.
* The format of a field_flag is described
* in the ACPI specification
+ * field_attribute - Special attributes (not used)
* field_bit_position - Field start position
* field_bit_length - Field length in number of bits
*
@@ -337,7 +370,7 @@ acpi_ex_prep_common_field_object (
/* Setup width (access granularity) fields */
obj_desc->common_field.access_byte_width = (u8)
- ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */
+ ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */
obj_desc->common_field.access_bit_width = (u8) access_bit_width;
@@ -380,11 +413,7 @@ acpi_ex_prep_common_field_object (
*
* FUNCTION: acpi_ex_prep_field_value
*
- * PARAMETERS: Node - Owning Node
- * region_node - Region in which field is being defined
- * field_flags - Access, lock_rule, and update_rule.
- * field_bit_position - Field start position
- * field_bit_length - Field length in number of bits
+ * PARAMETERS: Info - Contains all field creation info
*
* RETURN: Status
*
@@ -445,7 +474,7 @@ acpi_ex_prep_field_value (
switch (info->field_type) {
case ACPI_TYPE_LOCAL_REGION_FIELD:
- obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node);
+ obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node);
/* An additional reference for the container */
@@ -461,8 +490,10 @@ acpi_ex_prep_field_value (
case ACPI_TYPE_LOCAL_BANK_FIELD:
obj_desc->bank_field.value = info->bank_value;
- obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node);
- obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node);
+ obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (
+ info->region_node);
+ obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (
+ info->register_node);
/* An additional reference for the attached objects */
@@ -481,10 +512,13 @@ acpi_ex_prep_field_value (
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node);
- obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node);
+ obj_desc->index_field.index_obj = acpi_ns_get_attached_object (
+ info->register_node);
+ obj_desc->index_field.data_obj = acpi_ns_get_attached_object (
+ info->data_register_node);
obj_desc->index_field.value = (u32)
- (info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width));
+ (info->field_bit_position / ACPI_MUL_8 (
+ obj_desc->field.access_byte_width));
if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 7cfd0684c70..723aaef4bb4 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -115,7 +115,6 @@ acpi_ex_system_memory_space_handler (
return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
}
-
#ifndef ACPI_MISALIGNED_TRANSFERS
/*
* Hardware does not support non-aligned data transfers, we must verify
@@ -134,7 +133,8 @@ acpi_ex_system_memory_space_handler (
*/
if ((address < mem_info->mapped_physical_address) ||
(((acpi_integer) address + length) >
- ((acpi_integer) mem_info->mapped_physical_address + mem_info->mapped_length))) {
+ ((acpi_integer)
+ mem_info->mapped_physical_address + mem_info->mapped_length))) {
/*
* The request cannot be resolved by the current memory mapping;
* Delete the existing mapping and create a new one.
@@ -150,7 +150,9 @@ acpi_ex_system_memory_space_handler (
* Don't attempt to map memory beyond the end of the region, and
* constrain the maximum mapping size to something reasonable.
*/
- window_size = (acpi_size) ((mem_info->address + mem_info->length) - address);
+ window_size = (acpi_size)
+ ((mem_info->address + mem_info->length) - address);
+
if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
}
@@ -160,8 +162,9 @@ acpi_ex_system_memory_space_handler (
status = acpi_os_map_memory (address, window_size,
(void **) &mem_info->mapped_logical_address);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
- ACPI_FORMAT_UINT64 (address), (u32) window_size));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not map memory at %8.8X%8.8X, size %X\n",
+ ACPI_FORMAT_UINT64 (address), (u32) window_size));
mem_info->mapped_length = 0;
return_ACPI_STATUS (status);
}
@@ -177,10 +180,12 @@ acpi_ex_system_memory_space_handler (
* access
*/
logical_addr_ptr = mem_info->mapped_logical_address +
- ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
+ ((acpi_integer) address -
+ (acpi_integer) mem_info->mapped_physical_address);
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+ "system_memory %d (%d width) Address=%8.8X%8.8X\n",
+ function, bit_width,
ACPI_FORMAT_UINT64 (address)));
/*
@@ -298,13 +303,15 @@ acpi_ex_system_io_space_handler (
switch (function) {
case ACPI_READ:
- status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width);
+ status = acpi_os_read_port ((acpi_io_address) address,
+ &value32, bit_width);
*value = value32;
break;
case ACPI_WRITE:
- status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width);
+ status = acpi_os_write_port ((acpi_io_address) address,
+ (u32) *value, bit_width);
break;
default:
@@ -375,12 +382,14 @@ acpi_ex_pci_config_space_handler (
case ACPI_READ:
*value = 0;
- status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width);
+ status = acpi_os_read_pci_configuration (pci_id, pci_register,
+ value, bit_width);
break;
case ACPI_WRITE:
- status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width);
+ status = acpi_os_write_pci_configuration (pci_id, pci_register,
+ *value, bit_width);
break;
default:
@@ -505,8 +514,7 @@ acpi_ex_data_table_space_handler (
logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
-
- /* Perform the memory read or write */
+ /* Perform the memory read or write */
switch (function) {
case ACPI_READ:
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 7936329a0e3..21d5c74fa30 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -210,15 +210,15 @@ acpi_ex_resolve_node_to_value (
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read Node=%p source_desc=%p Type=%X\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "field_read Node=%p source_desc=%p Type=%X\n",
node, source_desc, entry_type));
status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc);
break;
- /*
- * For these objects, just return the object attached to the Node
- */
+ /* For these objects, just return the object attached to the Node */
+
case ACPI_TYPE_MUTEX:
case ACPI_TYPE_METHOD:
case ACPI_TYPE_POWER:
@@ -233,12 +233,12 @@ acpi_ex_resolve_node_to_value (
acpi_ut_add_reference (obj_desc);
break;
-
/* TYPE_ANY is untyped, and thus there is no object associated with it */
case ACPI_TYPE_ANY:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Untyped entry %p, no attached object!\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Untyped entry %p, no attached object!\n",
node));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
@@ -259,7 +259,8 @@ acpi_ex_resolve_node_to_value (
default:
/* No named references are allowed here */
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unsupported Reference opcode %X (%s)\n",
source_desc->reference.opcode,
acpi_ps_get_opcode_name (source_desc->reference.opcode)));
@@ -268,11 +269,12 @@ acpi_ex_resolve_node_to_value (
break;
- /* Default case is for unknown types */
-
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Node %p - Unknown object type %X\n",
+ /* Default case is for unknown types */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Node %p - Unknown object type %X\n",
node, entry_type));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
@@ -280,7 +282,7 @@ acpi_ex_resolve_node_to_value (
} /* switch (entry_type) */
- /* Put the object descriptor on the stack */
+ /* Return the object descriptor */
*object_ptr = (void *) obj_desc;
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 7be60491115..3de45672379 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -54,6 +54,13 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exresolv")
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_resolve_object_to_value (
+ union acpi_operand_object **stack_ptr,
+ struct acpi_walk_state *walk_state);
+
/*******************************************************************************
*
@@ -96,6 +103,11 @@ acpi_ex_resolve_to_value (
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
+
+ if (!*stack_ptr) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
}
/*
@@ -120,18 +132,17 @@ acpi_ex_resolve_to_value (
*
* FUNCTION: acpi_ex_resolve_object_to_value
*
- * PARAMETERS: stack_ptr - Pointer to a stack location that contains a
- * ptr to an internal object.
+ * PARAMETERS: stack_ptr - Pointer to an internal object
* walk_state - Current method state
*
* RETURN: Status
*
- * DESCRIPTION: Retrieve the value from an internal object. The Reference type
+ * DESCRIPTION: Retrieve the value from an internal object. The Reference type
* uses the associated AML opcode to determine the value.
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_resolve_object_to_value (
union acpi_operand_object **stack_ptr,
struct acpi_walk_state *walk_state)
@@ -159,7 +170,7 @@ acpi_ex_resolve_object_to_value (
case AML_NAME_OP:
/*
- * Convert indirect name ptr to a direct name ptr.
+ * Convert name reference to a namespace node
* Then, acpi_ex_resolve_node_to_value can be used to get the value
*/
temp_node = stack_desc->reference.object;
@@ -168,7 +179,7 @@ acpi_ex_resolve_object_to_value (
acpi_ut_remove_reference (stack_desc);
- /* Put direct name pointer onto stack and exit */
+ /* Return the namespace node */
(*stack_ptr) = temp_node;
break;
@@ -255,10 +266,19 @@ acpi_ex_resolve_object_to_value (
break;
+ case AML_INT_NAMEPATH_OP: /* Reference to a named object */
+
+ /* Get the object pointed to by the namespace node */
+
+ *stack_ptr = (stack_desc->reference.node)->object;
+ acpi_ut_add_reference (*stack_ptr);
+ acpi_ut_remove_reference (stack_desc);
+ break;
default:
- ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n",
+ ACPI_REPORT_ERROR ((
+ "During resolve, Unknown Reference opcode %X (%s) in %p\n",
opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
status = AE_AML_INTERNAL;
break;
@@ -278,9 +298,8 @@ acpi_ex_resolve_object_to_value (
break;
- /*
- * These cases may never happen here, but just in case..
- */
+ /* These cases may never happen here, but just in case.. */
+
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
@@ -333,9 +352,8 @@ acpi_ex_resolve_multiple (
ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
- /*
- * Operand can be either a namespace node or an operand descriptor
- */
+ /* Operand can be either a namespace node or an operand descriptor */
+
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
type = obj_desc->common.type;
@@ -357,10 +375,8 @@ acpi_ex_resolve_multiple (
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
+ /* If type is anything other than a reference, we are done */
- /*
- * If type is anything other than a reference, we are done
- */
if (type != ACPI_TYPE_LOCAL_REFERENCE) {
goto exit;
}
@@ -382,8 +398,9 @@ acpi_ex_resolve_multiple (
/* All "References" point to a NS node */
if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
- ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
- node, acpi_ut_get_descriptor_name (node)));
+ ACPI_REPORT_ERROR ((
+ "acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+ node, acpi_ut_get_descriptor_name (node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -440,8 +457,9 @@ acpi_ex_resolve_multiple (
/* All "References" point to a NS node */
if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
- ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
- node, acpi_ut_get_descriptor_name (node)));
+ ACPI_REPORT_ERROR ((
+ "acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+ node, acpi_ut_get_descriptor_name (node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@@ -468,7 +486,7 @@ acpi_ex_resolve_multiple (
if (return_desc) {
status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
- obj_desc->reference.offset, walk_state, &obj_desc);
+ obj_desc->reference.offset, walk_state, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -500,7 +518,8 @@ acpi_ex_resolve_multiple (
default:
- ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
+ ACPI_REPORT_ERROR ((
+ "acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
obj_desc->reference.opcode));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index c92890220c3..d8b470eefe7 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -52,6 +52,14 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exresop")
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_check_object_type (
+ acpi_object_type type_needed,
+ acpi_object_type this_type,
+ void *object);
+
/*******************************************************************************
*
@@ -67,7 +75,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_check_object_type (
acpi_object_type type_needed,
acpi_object_type this_type,
@@ -142,6 +150,7 @@ acpi_ex_resolve_operands (
const struct acpi_opcode_info *op_info;
u32 this_arg_type;
acpi_object_type type_needed;
+ u16 target_op = 0;
ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode);
@@ -160,7 +169,8 @@ acpi_ex_resolve_operands (
return_ACPI_STATUS (AE_AML_INTERNAL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Opcode %X [%s] required_operand_types=%8.8X \n",
opcode, op_info->name, arg_types));
/*
@@ -187,7 +197,7 @@ acpi_ex_resolve_operands (
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
case ACPI_DESC_TYPE_NAMED:
- /* Node */
+ /* Namespace Node */
object_type = ((struct acpi_namespace_node *) obj_desc)->type;
break;
@@ -202,16 +212,16 @@ acpi_ex_resolve_operands (
/* Check for bad acpi_object_type */
if (!acpi_ut_valid_object_type (object_type)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Bad operand object type [%X]\n",
object_type));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
- /*
- * Decode the Reference
- */
+ /* Decode the Reference */
+
op_info = acpi_ps_get_opcode_info (opcode);
if (op_info->class == AML_CLASS_UNKNOWN) {
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
@@ -219,12 +229,17 @@ acpi_ex_resolve_operands (
switch (obj_desc->reference.opcode) {
case AML_DEBUG_OP:
+ target_op = AML_DEBUG_OP;
+
+ /*lint -fallthrough */
+
case AML_NAME_OP:
case AML_INDEX_OP:
case AML_REF_OF_OP:
case AML_ARG_OP:
case AML_LOCAL_OP:
- case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+ case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+ case AML_INT_NAMEPATH_OP: /* Reference to a named object */
ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Operand is a Reference, ref_opcode [%s]\n",
@@ -254,10 +269,8 @@ acpi_ex_resolve_operands (
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
+ /* Get one argument type, point to the next */
- /*
- * Get one argument type, point to the next
- */
this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
INCREMENT_ARG_LIST (arg_types);
@@ -271,26 +284,31 @@ acpi_ex_resolve_operands (
if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
(ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) {
/*
- * String found - the string references a named object and must be
- * resolved to a node
+ * String found - the string references a named object and
+ * must be resolved to a node
*/
goto next_operand;
}
- /* Else not a string - fall through to the normal Reference case below */
+ /*
+ * Else not a string - fall through to the normal Reference
+ * case below
+ */
/*lint -fallthrough */
case ARGI_REFERENCE: /* References: */
case ARGI_INTEGER_REF:
case ARGI_OBJECT_REF:
case ARGI_DEVICE_REF:
- case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
- case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
- case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
-
- /* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE */
+ case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
+ case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
+ case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
- if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) /* Node (name) ptr OK as-is */ {
+ /*
+ * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
+ * A Namespace Node is OK as-is
+ */
+ if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
goto next_operand;
}
@@ -300,11 +318,9 @@ acpi_ex_resolve_operands (
return_ACPI_STATUS (status);
}
- if (AML_NAME_OP == obj_desc->reference.opcode) {
- /*
- * Convert an indirect name ptr to direct name ptr and put
- * it on the stack
- */
+ if (obj_desc->reference.opcode == AML_NAME_OP) {
+ /* Convert a named reference to the actual named object */
+
temp_node = obj_desc->reference.object;
acpi_ut_remove_reference (obj_desc);
(*stack_ptr) = temp_node;
@@ -332,7 +348,6 @@ acpi_ex_resolve_operands (
break;
}
-
/*
* Resolve this object to a value
*/
@@ -392,7 +407,7 @@ acpi_ex_resolve_operands (
/*
* The more complex cases allow multiple resolved object types
*/
- case ARGI_INTEGER: /* Number */
+ case ARGI_INTEGER:
/*
* Need an operand of type ACPI_TYPE_INTEGER,
@@ -563,7 +578,7 @@ acpi_ex_resolve_operands (
case ARGI_REGION_OR_FIELD:
- /* Need an operand of type ACPI_TYPE_REGION or a FIELD in a region */
+ /* Need an operand of type REGION or a FIELD in a region */
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_REGION:
@@ -614,6 +629,12 @@ acpi_ex_resolve_operands (
break;
}
+ if (target_op == AML_DEBUG_OP) {
+ /* Allow store of any object to the Debug object */
+
+ break;
+ }
+
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
acpi_ut_get_object_type_name (obj_desc), obj_desc));
@@ -652,8 +673,7 @@ next_operand:
if (GET_CURRENT_ARG_TYPE (arg_types)) {
stack_ptr--;
}
-
- } /* while (*Types) */
+ }
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index e0fc6aba125..2725db0901b 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -48,11 +48,171 @@
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exstore")
+/* Local prototypes */
+
+static void
+acpi_ex_do_debug_object (
+ union acpi_operand_object *source_desc,
+ u32 level,
+ u32 index);
+
+static acpi_status
+acpi_ex_store_object_to_index (
+ union acpi_operand_object *val_desc,
+ union acpi_operand_object *dest_desc,
+ struct acpi_walk_state *walk_state);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ex_do_debug_object
+ *
+ * PARAMETERS: source_desc - Value to be stored
+ * Level - Indentation level (used for packages)
+ * Index - Current package element, zero if not pkg
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Handles stores to the Debug Object.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_do_debug_object (
+ union acpi_operand_object *source_desc,
+ u32 level,
+ u32 index)
+{
+ u32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ex_do_debug_object", source_desc);
+
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
+ level, " "));
+
+ /* Display index for package output only */
+
+ if (index > 0) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
+ "(%.2u) ", index -1));
+ }
+
+ if (!source_desc) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
+ return_VOID;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_OPERAND) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: ",
+ acpi_ut_get_object_type_name (source_desc)));
+
+ if (!acpi_ut_valid_internal_object (source_desc)) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
+ "%p, Invalid Internal Object!\n", source_desc));
+ return_VOID;
+ }
+ }
+ else if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
+ acpi_ut_get_type_name (((struct acpi_namespace_node *) source_desc)->type),
+ source_desc));
+ return_VOID;
+ }
+ else {
+ return_VOID;
+ }
+
+ switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+ case ACPI_TYPE_INTEGER:
+
+ /* Output correct integer width */
+
+ if (acpi_gbl_integer_byte_width == 4) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
+ (u32) source_desc->integer.value));
+ }
+ else {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (source_desc->integer.value)));
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
+ (u32) source_desc->buffer.length));
+ ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
+ (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
+ break;
+
+ case ACPI_TYPE_STRING:
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
+ source_desc->string.length, source_desc->string.pointer));
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X Elements]\n",
+ source_desc->package.count));
+
+ /* Output the entire contents of the package */
+
+ for (i = 0; i < source_desc->package.count; i++) {
+ acpi_ex_do_debug_object (source_desc->package.elements[i],
+ level+4, i+1);
+ }
+ break;
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ if (source_desc->reference.opcode == AML_INDEX_OP) {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s, 0x%X]\n",
+ acpi_ps_get_opcode_name (source_desc->reference.opcode),
+ source_desc->reference.offset));
+ }
+ else {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s]\n",
+ acpi_ps_get_opcode_name (source_desc->reference.opcode)));
+ }
+
+
+ if (source_desc->reference.object) {
+ if (ACPI_GET_DESCRIPTOR_TYPE (source_desc->reference.object) ==
+ ACPI_DESC_TYPE_NAMED) {
+ acpi_ex_do_debug_object (((struct acpi_namespace_node *)
+ source_desc->reference.object)->object,
+ level+4, 0);
+ }
+ else {
+ acpi_ex_do_debug_object (source_desc->reference.object, level+4, 0);
+ }
+ }
+ else if (source_desc->reference.node) {
+ acpi_ex_do_debug_object ((source_desc->reference.node)->object,
+ level+4, 0);
+ }
+ break;
+
+ default:
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
+ source_desc, acpi_ut_get_object_type_name (source_desc)));
+ break;
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+ return_VOID;
+}
+
/*******************************************************************************
*
@@ -154,8 +314,9 @@ acpi_ex_store (
/* Storing an object into a Name "container" */
- status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
- walk_state, ACPI_IMPLICIT_CONVERSION);
+ status = acpi_ex_store_object_to_node (source_desc,
+ ref_desc->reference.object,
+ walk_state, ACPI_IMPLICIT_CONVERSION);
break;
@@ -173,7 +334,7 @@ acpi_ex_store (
/* Store to a method local/arg */
status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
- ref_desc->reference.offset, source_desc, walk_state);
+ ref_desc->reference.offset, source_desc, walk_state);
break;
@@ -187,60 +348,7 @@ acpi_ex_store (
"**** Write to Debug Object: Object %p %s ****:\n\n",
source_desc, acpi_ut_get_object_type_name (source_desc)));
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
- acpi_ut_get_object_type_name (source_desc)));
-
- if (!acpi_ut_valid_internal_object (source_desc)) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
- "%p, Invalid Internal Object!\n", source_desc));
- break;
- }
-
- switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
- case ACPI_TYPE_INTEGER:
-
- if (acpi_gbl_integer_byte_width == 4) {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
- (u32) source_desc->integer.value));
- }
- else {
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (source_desc->integer.value)));
- }
- break;
-
-
- case ACPI_TYPE_BUFFER:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
- (u32) source_desc->buffer.length));
- ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
- (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
- break;
-
-
- case ACPI_TYPE_STRING:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
- source_desc->string.length, source_desc->string.pointer));
- break;
-
-
- case ACPI_TYPE_PACKAGE:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] Elements Ptr - %p\n",
- source_desc->package.count, source_desc->package.elements));
- break;
-
-
- default:
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
- source_desc));
- break;
- }
-
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+ acpi_ex_do_debug_object (source_desc, 0, 0);
break;
@@ -272,7 +380,7 @@ acpi_ex_store (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ex_store_object_to_index (
union acpi_operand_object *source_desc,
union acpi_operand_object *index_desc,
@@ -313,16 +421,22 @@ acpi_ex_store_object_to_index (
if (obj_desc) {
/* Decrement reference count by the ref count of the parent package */
- for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+ for (i = 0;
+ i < ((union acpi_operand_object *)
+ index_desc->reference.object)->common.reference_count;
+ i++) {
acpi_ut_remove_reference (obj_desc);
}
}
*(index_desc->reference.where) = new_desc;
- /* Increment reference count by the ref count of the parent package -1 */
+ /* Increment ref count by the ref count of the parent package-1 */
- for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+ for (i = 1;
+ i < ((union acpi_operand_object *)
+ index_desc->reference.object)->common.reference_count;
+ i++) {
acpi_ut_add_reference (new_desc);
}
@@ -440,9 +554,8 @@ acpi_ex_store_object_to_node (
ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
- /*
- * Get current type of the node, and object attached to Node
- */
+ /* Get current type of the node, and object attached to Node */
+
target_type = acpi_ns_get_type (node);
target_desc = acpi_ns_get_attached_object (node);
@@ -467,19 +580,18 @@ acpi_ex_store_object_to_node (
target_type = ACPI_TYPE_ANY;
}
- /*
- * Do the actual store operation
- */
+ /* Do the actual store operation */
+
switch (target_type) {
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
case ACPI_TYPE_LOCAL_BANK_FIELD:
case ACPI_TYPE_LOCAL_INDEX_FIELD:
- /*
- * For fields, copy the source data to the target field.
- */
- status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
+ /* For fields, copy the source data to the target field. */
+
+ status = acpi_ex_write_data_to_field (source_desc, target_desc,
+ &walk_state->result_obj);
break;
@@ -493,7 +605,8 @@ acpi_ex_store_object_to_node (
*
* Copy and/or convert the source object to a new target object
*/
- status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state);
+ status = acpi_ex_store_object_to_object (source_desc, target_desc,
+ &new_desc, walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -526,7 +639,8 @@ acpi_ex_store_object_to_node (
/* No conversions for all other types. Just attach the source object */
- status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc));
+ status = acpi_ns_attach_object (node, source_desc,
+ ACPI_GET_OBJECT_TYPE (source_desc));
break;
}
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index d3677feb07f..120f30ed0bd 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -81,9 +81,8 @@ acpi_ex_resolve_object (
ACPI_FUNCTION_TRACE ("ex_resolve_object");
- /*
- * Ensure we have a Target that can be stored to
- */
+ /* Ensure we have a Target that can be stored to */
+
switch (target_type) {
case ACPI_TYPE_BUFFER_FIELD:
case ACPI_TYPE_LOCAL_REGION_FIELD:
@@ -118,16 +117,14 @@ acpi_ex_resolve_object (
break;
}
- /*
- * Must have a Integer, Buffer, or String
- */
+ /* Must have a Integer, Buffer, or String */
+
if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) &&
!((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
- /*
- * Conversion successful but still not a valid type
- */
+ /* Conversion successful but still not a valid type */
+
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
acpi_ut_get_object_type_name (source_desc),
@@ -140,9 +137,8 @@ acpi_ex_resolve_object (
case ACPI_TYPE_LOCAL_ALIAS:
case ACPI_TYPE_LOCAL_METHOD_ALIAS:
- /*
- * Aliases are resolved by acpi_ex_prep_operands
- */
+ /* Aliases are resolved by acpi_ex_prep_operands */
+
ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
status = AE_AML_INTERNAL;
break;
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 05e1ecae8d9..12d1527669c 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -128,7 +128,8 @@ acpi_ex_store_buffer_to_buffer (
else {
/* Truncate the source, copy only what will fit */
- ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
+ ACPI_MEMCPY (target_desc->buffer.pointer, buffer,
+ target_desc->buffer.length);
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Truncating source buffer from %X to %X\n",
@@ -183,7 +184,8 @@ acpi_ex_store_string_to_string (
* String will fit in existing non-static buffer.
* Clear old string and copy in the new one
*/
- ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1);
+ ACPI_MEMSET (target_desc->string.pointer, 0,
+ (acpi_size) target_desc->string.length + 1);
ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
}
else {
@@ -198,7 +200,8 @@ acpi_ex_store_string_to_string (
ACPI_MEM_FREE (target_desc->string.pointer);
}
- target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
+ target_desc->string.pointer = ACPI_MEM_CALLOCATE (
+ (acpi_size) length + 1);
if (!target_desc->string.pointer) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index f92efc51289..cafa702108d 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -55,8 +55,8 @@
*
* FUNCTION: acpi_ex_system_wait_semaphore
*
- * PARAMETERS: Semaphore - OSD semaphore to wait on
- * Timeout - Max time to wait
+ * PARAMETERS: Semaphore - Semaphore to wait on
+ * Timeout - Max time to wait
*
* RETURN: Status
*
@@ -90,7 +90,8 @@ acpi_ex_system_wait_semaphore (
status = acpi_os_wait_semaphore (semaphore, 1, timeout);
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*** Thread awake after blocking, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "*** Thread awake after blocking, %s\n",
acpi_format_exception (status)));
/* Reacquire the interpreter */
@@ -111,8 +112,8 @@ acpi_ex_system_wait_semaphore (
*
* FUNCTION: acpi_ex_system_do_stall
*
- * PARAMETERS: how_long - The amount of time to stall,
- * in microseconds
+ * PARAMETERS: how_long - The amount of time to stall,
+ * in microseconds
*
* RETURN: Status
*
@@ -141,7 +142,8 @@ acpi_ex_system_do_stall (
* (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs)
*/
- ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
+ ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n",
+ how_long));
status = AE_AML_OPERAND_VALUE;
}
else {
@@ -156,8 +158,8 @@ acpi_ex_system_do_stall (
*
* FUNCTION: acpi_ex_system_do_suspend
*
- * PARAMETERS: how_long - The amount of time to suspend,
- * in milliseconds
+ * PARAMETERS: how_long - The amount of time to suspend,
+ * in milliseconds
*
* RETURN: None
*
@@ -192,8 +194,8 @@ acpi_ex_system_do_suspend (
*
* FUNCTION: acpi_ex_system_acquire_mutex
*
- * PARAMETERS: *time_desc - The 'time to delay' object descriptor
- * *obj_desc - The object descriptor for this op
+ * PARAMETERS: time_desc - The 'time to delay' object descriptor
+ * obj_desc - The object descriptor for this op
*
* RETURN: Status
*
@@ -218,16 +220,15 @@ acpi_ex_system_acquire_mutex (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /*
- * Support for the _GL_ Mutex object -- go get the global lock
- */
+ /* Support for the _GL_ Mutex object -- go get the global lock */
+
if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
return_ACPI_STATUS (status);
}
status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
- (u16) time_desc->integer.value);
+ (u16) time_desc->integer.value);
return_ACPI_STATUS (status);
}
@@ -236,7 +237,7 @@ acpi_ex_system_acquire_mutex (
*
* FUNCTION: acpi_ex_system_release_mutex
*
- * PARAMETERS: *obj_desc - The object descriptor for this op
+ * PARAMETERS: obj_desc - The object descriptor for this op
*
* RETURN: Status
*
@@ -261,9 +262,8 @@ acpi_ex_system_release_mutex (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /*
- * Support for the _GL_ Mutex object -- release the global lock
- */
+ /* Support for the _GL_ Mutex object -- release the global lock */
+
if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
status = acpi_ev_release_global_lock ();
return_ACPI_STATUS (status);
@@ -278,9 +278,9 @@ acpi_ex_system_release_mutex (
*
* FUNCTION: acpi_ex_system_signal_event
*
- * PARAMETERS: *obj_desc - The object descriptor for this op
+ * PARAMETERS: obj_desc - The object descriptor for this op
*
- * RETURN: AE_OK
+ * RETURN: Status
*
* DESCRIPTION: Provides an access point to perform synchronization operations
* within the AML.
@@ -309,8 +309,8 @@ acpi_ex_system_signal_event (
*
* FUNCTION: acpi_ex_system_wait_event
*
- * PARAMETERS: *time_desc - The 'time to delay' object descriptor
- * *obj_desc - The object descriptor for this op
+ * PARAMETERS: time_desc - The 'time to delay' object descriptor
+ * obj_desc - The object descriptor for this op
*
* RETURN: Status
*
@@ -333,7 +333,7 @@ acpi_ex_system_wait_event (
if (obj_desc) {
status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
- (u16) time_desc->integer.value);
+ (u16) time_desc->integer.value);
}
return_ACPI_STATUS (status);
@@ -344,7 +344,7 @@ acpi_ex_system_wait_event (
*
* FUNCTION: acpi_ex_system_reset_event
*
- * PARAMETERS: *obj_desc - The object descriptor for this op
+ * PARAMETERS: obj_desc - The object descriptor for this op
*
* RETURN: Status
*
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 40c6abb8b49..5c7ec0c0417 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -67,22 +67,31 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME ("exutils")
+/* Local prototypes */
-#ifndef ACPI_NO_METHOD_EXECUTION
+static u32
+acpi_ex_digits_needed (
+ acpi_integer value,
+ u32 base);
+
+#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
*
* FUNCTION: acpi_ex_enter_interpreter
*
* PARAMETERS: None
*
+ * RETURN: Status
+ *
* DESCRIPTION: Enter the interpreter execution region. Failure to enter
* the interpreter region is a fatal system error
*
******************************************************************************/
acpi_status
-acpi_ex_enter_interpreter (void)
+acpi_ex_enter_interpreter (
+ void)
{
acpi_status status;
@@ -104,6 +113,8 @@ acpi_ex_enter_interpreter (void)
*
* PARAMETERS: None
*
+ * RETURN: None
+ *
* DESCRIPTION: Exit the interpreter execution region
*
* Cases where the interpreter is unlocked:
@@ -119,7 +130,8 @@ acpi_ex_enter_interpreter (void)
******************************************************************************/
void
-acpi_ex_exit_interpreter (void)
+acpi_ex_exit_interpreter (
+ void)
{
acpi_status status;
@@ -212,7 +224,8 @@ acpi_ex_acquire_global_lock (
locked = TRUE;
}
else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not acquire Global Lock, %s\n",
acpi_format_exception (status)));
}
}
@@ -228,7 +241,7 @@ acpi_ex_acquire_global_lock (
* PARAMETERS: locked_by_me - Return value from corresponding call to
* acquire_global_lock.
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Release the global lock if it is locked.
*
@@ -269,11 +282,14 @@ acpi_ex_release_global_lock (
* PARAMETERS: Value - Value to be represented
* Base - Base of representation
*
- * RETURN: the number of digits needed to represent Value in Base
+ * RETURN: The number of digits.
+ *
+ * DESCRIPTION: Calculate the number of digits needed to represent the Value
+ * in the given Base (Radix)
*
******************************************************************************/
-u32
+static u32
acpi_ex_digits_needed (
acpi_integer value,
u32 base)
@@ -312,6 +328,8 @@ acpi_ex_digits_needed (
* PARAMETERS: numeric_id - EISA ID to be converted
* out_string - Where to put the converted string (8 bytes)
*
+ * RETURN: None
+ *
* DESCRIPTION: Convert a numeric EISA ID to string representation
*
******************************************************************************/
@@ -349,7 +367,10 @@ acpi_ex_eisa_id_to_string (
* PARAMETERS: Value - Value to be converted
* out_string - Where to put the converted string (8 bytes)
*
- * RETURN: Convert a number to string representation
+ * RETURN: None, string
+ *
+ * DESCRIPTOIN: Convert a number to string representation. Assumes string
+ * buffer is large enough to hold the string.
*
******************************************************************************/
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
new file mode 100644
index 00000000000..770cfc8b17e
--- /dev/null
+++ b/drivers/acpi/glue.c
@@ -0,0 +1,360 @@
+/*
+ * Link physical devices with ACPI devices support
+ *
+ * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (c) 2005 Intel Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/rwsem.h>
+#include <linux/acpi.h>
+
+#define ACPI_GLUE_DEBUG 0
+#if ACPI_GLUE_DEBUG
+#define DBG(x...) printk(PREFIX x)
+#else
+#define DBG(x...)
+#endif
+static LIST_HEAD(bus_type_list);
+static DECLARE_RWSEM(bus_type_sem);
+
+int register_acpi_bus_type(struct acpi_bus_type *type)
+{
+ if (acpi_disabled)
+ return -ENODEV;
+ if (type && type->bus && type->find_device) {
+ down_write(&bus_type_sem);
+ list_add_tail(&type->list, &bus_type_list);
+ up_write(&bus_type_sem);
+ printk(KERN_INFO PREFIX "bus type %s registered\n", type->bus->name);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+EXPORT_SYMBOL(register_acpi_bus_type);
+
+int unregister_acpi_bus_type(struct acpi_bus_type *type)
+{
+ if (acpi_disabled)
+ return 0;
+ if (type) {
+ down_write(&bus_type_sem);
+ list_del_init(&type->list);
+ up_write(&bus_type_sem);
+ printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", type->bus->name);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+EXPORT_SYMBOL(unregister_acpi_bus_type);
+
+static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
+{
+ struct acpi_bus_type *tmp, *ret = NULL;
+
+ down_read(&bus_type_sem);
+ list_for_each_entry(tmp, &bus_type_list, list) {
+ if (tmp->bus == type) {
+ ret = tmp;
+ break;
+ }
+ }
+ up_read(&bus_type_sem);
+ return ret;
+}
+
+static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
+{
+ struct acpi_bus_type *tmp;
+ int ret = -ENODEV;
+
+ down_read(&bus_type_sem);
+ list_for_each_entry(tmp, &bus_type_list, list) {
+ if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
+ ret = 0;
+ break;
+ }
+ }
+ up_read(&bus_type_sem);
+ return ret;
+}
+
+/* Get PCI root bridge's handle from its segment and bus number */
+struct acpi_find_pci_root {
+ unsigned int seg;
+ unsigned int bus;
+ acpi_handle handle;
+};
+
+static acpi_status
+do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
+{
+ int *busnr = (int *)data;
+ struct acpi_resource_address64 address;
+
+ if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+ resource->id != ACPI_RSTYPE_ADDRESS32 &&
+ resource->id != ACPI_RSTYPE_ADDRESS64)
+ return AE_OK;
+
+ acpi_resource_to_address64(resource, &address);
+ if ((address.address_length > 0) &&
+ (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+ *busnr = address.min_address_range;
+
+ return AE_OK;
+}
+
+static int get_root_bridge_busnr(acpi_handle handle)
+{
+ acpi_status status;
+ int bus, bbn;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+ status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
+ (unsigned long *)&bbn);
+ if (status == AE_NOT_FOUND) {
+ /* Assume bus = 0 */
+ printk(KERN_INFO PREFIX
+ "Assume root bridge [%s] bus is 0\n",
+ (char *)buffer.pointer);
+ status = AE_OK;
+ bbn = 0;
+ }
+ if (ACPI_FAILURE(status)) {
+ bbn = -ENODEV;
+ goto exit;
+ }
+ if (bbn > 0)
+ goto exit;
+
+ /* _BBN in some systems return 0 for all root bridges */
+ bus = -1;
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+ do_root_bridge_busnr_callback, &bus);
+ /* If _CRS failed, we just use _BBN */
+ if (ACPI_FAILURE(status) || (bus == -1))
+ goto exit;
+ /* We select _CRS */
+ if (bbn != bus) {
+ printk(KERN_INFO PREFIX
+ "_BBN and _CRS returns different value for %s. Select _CRS\n",
+ (char *)buffer.pointer);
+ bbn = bus;
+ }
+ exit:
+ acpi_os_free(buffer.pointer);
+ return bbn;
+}
+
+static acpi_status
+find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
+ unsigned long seg, bus;
+ acpi_status status;
+ int tmp;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+ status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
+ if (status == AE_NOT_FOUND) {
+ /* Assume seg = 0 */
+ printk(KERN_INFO PREFIX
+ "Assume root bridge [%s] segment is 0\n",
+ (char *)buffer.pointer);
+ status = AE_OK;
+ seg = 0;
+ }
+ if (ACPI_FAILURE(status)) {
+ status = AE_CTRL_DEPTH;
+ goto exit;
+ }
+
+ tmp = get_root_bridge_busnr(handle);
+ if (tmp < 0) {
+ printk(KERN_ERR PREFIX
+ "Find root bridge failed for %s\n",
+ (char *)buffer.pointer);
+ status = AE_CTRL_DEPTH;
+ goto exit;
+ }
+ bus = tmp;
+
+ if (seg == find->seg && bus == find->bus)
+ find->handle = handle;
+ status = AE_OK;
+ exit:
+ acpi_os_free(buffer.pointer);
+ return status;
+}
+
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
+{
+ struct acpi_find_pci_root find = { seg, bus, NULL };
+
+ acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
+ return find.handle;
+}
+
+/* Get device's handler per its address under its parent */
+struct acpi_find_child {
+ acpi_handle handle;
+ acpi_integer address;
+};
+
+static acpi_status
+do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ acpi_status status;
+ struct acpi_device_info *info;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_find_child *find = (struct acpi_find_child *)context;
+
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_SUCCESS(status)) {
+ info = buffer.pointer;
+ if (info->address == find->address)
+ find->handle = handle;
+ acpi_os_free(buffer.pointer);
+ }
+ return AE_OK;
+}
+
+acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
+{
+ struct acpi_find_child find = { NULL, address };
+
+ if (!parent)
+ return NULL;
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
+ 1, do_acpi_find_child, &find, NULL);
+ return find.handle;
+}
+
+EXPORT_SYMBOL(acpi_get_child);
+
+/* Link ACPI devices with physical devices */
+static void acpi_glue_data_handler(acpi_handle handle,
+ u32 function, void *context)
+{
+ /* we provide an empty handler */
+}
+
+/* Note: a success call will increase reference count by one */
+struct device *acpi_get_physical_device(acpi_handle handle)
+{
+ acpi_status status;
+ struct device *dev;
+
+ status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
+ if (ACPI_SUCCESS(status))
+ return get_device(dev);
+ return NULL;
+}
+
+EXPORT_SYMBOL(acpi_get_physical_device);
+
+static int acpi_bind_one(struct device *dev, acpi_handle handle)
+{
+ acpi_status status;
+
+ if (dev->firmware_data) {
+ printk(KERN_WARNING PREFIX
+ "Drivers changed 'firmware_data' for %s\n", dev->bus_id);
+ return -EINVAL;
+ }
+ get_device(dev);
+ status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
+ if (ACPI_FAILURE(status)) {
+ put_device(dev);
+ return -EINVAL;
+ }
+ dev->firmware_data = handle;
+
+ return 0;
+}
+
+static int acpi_unbind_one(struct device *dev)
+{
+ if (!dev->firmware_data)
+ return 0;
+ if (dev == acpi_get_physical_device(dev->firmware_data)) {
+ /* acpi_get_physical_device increase refcnt by one */
+ put_device(dev);
+ acpi_detach_data(dev->firmware_data, acpi_glue_data_handler);
+ dev->firmware_data = NULL;
+ /* acpi_bind_one increase refcnt by one */
+ put_device(dev);
+ } else {
+ printk(KERN_ERR PREFIX
+ "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id);
+ }
+ return 0;
+}
+
+static int acpi_platform_notify(struct device *dev)
+{
+ struct acpi_bus_type *type;
+ acpi_handle handle;
+ int ret = -EINVAL;
+
+ if (!dev->bus || !dev->parent) {
+ /* bridge devices genernally haven't bus or parent */
+ ret = acpi_find_bridge_device(dev, &handle);
+ goto end;
+ }
+ type = acpi_get_bus_type(dev->bus);
+ if (!type) {
+ DBG("No ACPI bus support for %s\n", dev->bus_id);
+ ret = -EINVAL;
+ goto end;
+ }
+ if ((ret = type->find_device(dev, &handle)) != 0)
+ DBG("Can't get handler for %s\n", dev->bus_id);
+ end:
+ if (!ret)
+ acpi_bind_one(dev, handle);
+
+#if ACPI_GLUE_DEBUG
+ if (!ret) {
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer);
+ DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+ acpi_os_free(buffer.pointer);
+ } else
+ DBG("Device %s -> No ACPI support\n", dev->bus_id);
+#endif
+
+ return ret;
+}
+
+static int acpi_platform_notify_remove(struct device *dev)
+{
+ acpi_unbind_one(dev);
+ return 0;
+}
+
+static int __init init_acpi_device_notify(void)
+{
+ if (acpi_disabled)
+ return 0;
+ if (platform_notify || platform_notify_remove) {
+ printk(KERN_ERR PREFIX "Can't use platform_notify\n");
+ return 0;
+ }
+ platform_notify = acpi_platform_notify;
+ platform_notify_remove = acpi_platform_notify_remove;
+ return 0;
+}
+
+arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index 529e922bdc8..b51001e74ee 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -58,7 +58,8 @@
*
* RETURN: Status
*
- * DESCRIPTION: Initialize and validate various ACPI registers
+ * DESCRIPTION: Initialize and validate the various ACPI registers defined in
+ * the FADT.
*
******************************************************************************/
@@ -75,7 +76,7 @@ acpi_hw_initialize (
/* We must have the ACPI tables by the time we get here */
if (!acpi_gbl_FADT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "A FADT is not loaded\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT is present\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
@@ -131,7 +132,8 @@ acpi_hw_set_mode (
* transitions are not supported.
*/
if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
- ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+ ACPI_REPORT_ERROR ((
+ "No ACPI mode transition supported in this system (enable/disable both zero)\n"));
return_ACPI_STATUS (AE_OK);
}
@@ -162,7 +164,8 @@ acpi_hw_set_mode (
}
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Could not write mode change, %s\n",
+ acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
@@ -173,7 +176,8 @@ acpi_hw_set_mode (
retry = 3000;
while (retry) {
if (acpi_hw_get_mode() == mode) {
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n",
+ mode));
return_ACPI_STATUS (AE_OK);
}
acpi_os_stall(1000);
@@ -185,7 +189,7 @@ acpi_hw_set_mode (
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_hw_get_mode
*
@@ -199,7 +203,8 @@ acpi_hw_set_mode (
******************************************************************************/
u32
-acpi_hw_get_mode (void)
+acpi_hw_get_mode (
+ void)
{
acpi_status status;
u32 value;
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 9ac1d639bf5..8daeabb2fc7 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -48,6 +48,13 @@
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME ("hwgpe")
+/* Local prototypes */
+
+static acpi_status
+acpi_hw_enable_wakeup_gpe_block (
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
+
/******************************************************************************
*
@@ -135,6 +142,7 @@ acpi_hw_clear_gpe (
* DESCRIPTION: Return the status of a single GPE.
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_hw_get_gpe_status (
@@ -206,7 +214,7 @@ unlock_and_exit:
*
* RETURN: Status
*
- * DESCRIPTION: Disable all GPEs within a GPE block
+ * DESCRIPTION: Disable all GPEs within a single GPE block
*
******************************************************************************/
@@ -244,7 +252,7 @@ acpi_hw_disable_gpe_block (
*
* RETURN: Status
*
- * DESCRIPTION: Clear status bits for all GPEs within a GPE block
+ * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
*
******************************************************************************/
@@ -282,8 +290,8 @@ acpi_hw_clear_gpe_block (
*
* RETURN: Status
*
- * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
- * combination wake/run GPEs.)
+ * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
+ * combination wake/run GPEs.
*
******************************************************************************/
@@ -327,12 +335,12 @@ acpi_hw_enable_runtime_gpe_block (
*
* RETURN: Status
*
- * DESCRIPTION: Enable all "wake" GPEs within a GPE block. (Includes
- * combination wake/run GPEs.)
+ * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
+ * combination wake/run GPEs.
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_hw_enable_wakeup_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
@@ -350,7 +358,8 @@ acpi_hw_enable_wakeup_gpe_block (
/* Enable all "wake" GPEs in this register */
- status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake,
+ status = acpi_hw_low_level_write (8,
+ gpe_block->register_info[i].enable_for_wake,
&gpe_block->register_info[i].enable_address);
if (ACPI_FAILURE (status)) {
return (status);
@@ -369,7 +378,7 @@ acpi_hw_enable_wakeup_gpe_block (
*
* RETURN: Status
*
- * DESCRIPTION: Disable and clear all GPEs
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
*
******************************************************************************/
@@ -397,7 +406,7 @@ acpi_hw_disable_all_gpes (
*
* RETURN: Status
*
- * DESCRIPTION: Enable all GPEs of the given type
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
*
******************************************************************************/
@@ -424,7 +433,7 @@ acpi_hw_enable_all_runtime_gpes (
*
* RETURN: Status
*
- * DESCRIPTION: Enable all GPEs of the given type
+ * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
*
******************************************************************************/
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 91af0c2ddcf..6d9e4eb8483 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -87,8 +87,9 @@ acpi_hw_clear_acpi_status (
}
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
- ACPI_BITMASK_ALL_FIXED_STATUS);
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
+ ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
@@ -138,28 +139,30 @@ acpi_get_sleep_type_data (
{
acpi_status status = AE_OK;
struct acpi_parameter_info info;
+ char *sleep_state_name;
ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
- /*
- * Validate parameters
- */
+ /* Validate parameters */
+
if ((sleep_state > ACPI_S_STATES_MAX) ||
!sleep_type_a || !sleep_type_b) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /*
- * Evaluate the namespace object containing the values for this state
- */
+ /* Evaluate the namespace object containing the values for this state */
+
info.parameters = NULL;
- status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
- &info);
+ info.return_object = NULL;
+ sleep_state_name = (char *) acpi_gbl_sleep_state_names[sleep_state];
+
+ status = acpi_ns_evaluate_by_name (sleep_state_name, &info);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
- acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "%s while evaluating sleep_state [%s]\n",
+ acpi_format_exception (status), sleep_state_name));
return_ACPI_STATUS (status);
}
@@ -167,45 +170,57 @@ acpi_get_sleep_type_data (
/* Must have a return object */
if (!info.return_object) {
- ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
+ ACPI_REPORT_ERROR (("No Sleep State object returned from [%s]\n",
+ sleep_state_name));
status = AE_NOT_EXIST;
}
/* It must be of type Package */
else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
- ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
+ ACPI_REPORT_ERROR (("Sleep State return object is not a Package\n"));
status = AE_AML_OPERAND_TYPE;
}
- /* The package must have at least two elements */
-
+ /*
+ * The package must have at least two elements. NOTE (March 2005): This
+ * goes against the current ACPI spec which defines this object as a
+ * package with one encoded DWORD element. However, existing practice
+ * by BIOS vendors seems to be to have 2 or more elements, at least
+ * one per sleep type (A/B).
+ */
else if (info.return_object->package.count < 2) {
- ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
+ ACPI_REPORT_ERROR ((
+ "Sleep State return package does not have at least two elements\n"));
status = AE_AML_NO_OPERAND;
}
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) {
- ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
+ else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0])
+ != ACPI_TYPE_INTEGER) ||
+ (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1])
+ != ACPI_TYPE_INTEGER)) {
+ ACPI_REPORT_ERROR ((
+ "Sleep State return package elements are not both Integers (%s, %s)\n",
acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
status = AE_AML_OPERAND_TYPE;
}
else {
- /*
- * Valid _Sx_ package size, type, and value
- */
- *sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value;
- *sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value;
+ /* Valid _Sx_ package size, type, and value */
+
+ *sleep_type_a = (u8)
+ (info.return_object->package.elements[0])->integer.value;
+ *sleep_type_b = (u8)
+ (info.return_object->package.elements[1])->integer.value;
}
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
- acpi_gbl_sleep_state_names[sleep_state], info.return_object,
+ "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+ acpi_format_exception (status),
+ sleep_state_name, info.return_object,
acpi_ut_get_object_type_name (info.return_object)));
}
@@ -221,9 +236,9 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
*
* PARAMETERS: register_id - Index of ACPI Register to access
*
- * RETURN: The bit mask to be used when accessing the register
+ * RETURN: The bitmask to be used when accessing the register
*
- * DESCRIPTION: Map register_id into a register bit mask.
+ * DESCRIPTION: Map register_id into a register bitmask.
*
******************************************************************************/
@@ -359,7 +374,7 @@ acpi_set_register (
/* Always do a register read first so we can insert the new bits */
status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
- bit_reg_info->parent_register, &register_value);
+ bit_reg_info->parent_register, &register_value);
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
@@ -396,7 +411,7 @@ acpi_set_register (
bit_reg_info->access_bit_mask, value);
status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_ENABLE, (u16) register_value);
+ ACPI_REGISTER_PM1_ENABLE, (u16) register_value);
break;
@@ -413,7 +428,7 @@ acpi_set_register (
bit_reg_info->access_bit_mask, value);
status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
+ ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
break;
@@ -427,17 +442,19 @@ acpi_set_register (
ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
register_value,
- ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+ ACPI_FORMAT_UINT64 (
+ acpi_gbl_FADT->xpm2_cnt_blk.address)));
ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
bit_reg_info->access_bit_mask, value);
ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
register_value,
- ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+ ACPI_FORMAT_UINT64 (
+ acpi_gbl_FADT->xpm2_cnt_blk.address)));
status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
+ ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
break;
@@ -454,7 +471,9 @@ unlock_and_exit:
/* Normalize the value that was read */
- ACPI_DEBUG_EXEC (register_value = ((register_value & bit_reg_info->access_bit_mask) >> bit_reg_info->bit_position));
+ ACPI_DEBUG_EXEC (register_value =
+ ((register_value & bit_reg_info->access_bit_mask) >>
+ bit_reg_info->bit_position));
ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n",
value, register_value, bit_reg_info->parent_register));
@@ -469,7 +488,7 @@ EXPORT_SYMBOL(acpi_set_register);
*
* PARAMETERS: use_lock - Mutex hw access
* register_id - register_iD + Offset
- * return_value - Value that was read from the register
+ * return_value - Where the register value is returned
*
* RETURN: Status and the value read.
*
@@ -557,7 +576,8 @@ acpi_hw_register_read (
break;
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", register_id));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
+ register_id));
status = AE_BAD_PARAMETER;
break;
}
@@ -763,10 +783,11 @@ acpi_hw_low_level_read (
return (AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
- *value, width,
- ACPI_FORMAT_UINT64 (address),
- acpi_ut_get_region_name (reg->address_space_id)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
+ *value, width,
+ ACPI_FORMAT_UINT64 (address),
+ acpi_ut_get_region_name (reg->address_space_id)));
return (status);
}
@@ -841,10 +862,11 @@ acpi_hw_low_level_write (
return (AE_BAD_PARAMETER);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
- value, width,
- ACPI_FORMAT_UINT64 (address),
- acpi_ut_get_region_name (reg->address_space_id)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+ "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
+ value, width,
+ ACPI_FORMAT_UINT64 (address),
+ acpi_ut_get_region_name (reg->address_space_id)));
return (status);
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 77b3e9a8550..415d342aeab 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -43,27 +43,13 @@
*/
#include <linux/module.h>
-
#include <acpi/acpi.h>
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME ("hwsleep")
-#define METHOD_NAME__BFS "\\_BFS"
-#define METHOD_NAME__GTS "\\_GTS"
-#define METHOD_NAME__PTS "\\_PTS"
-#define METHOD_NAME__SST "\\_SI._SST"
-#define METHOD_NAME__WAK "\\_WAK"
-
-#define ACPI_SST_INDICATOR_OFF 0
-#define ACPI_SST_WORKING 1
-#define ACPI_SST_WAKING 2
-#define ACPI_SST_SLEEPING 3
-#define ACPI_SST_SLEEP_CONTEXT 4
-
-
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_set_firmware_waking_vector
*
@@ -72,7 +58,7 @@
*
* RETURN: Status
*
- * DESCRIPTION: access function for d_firmware_waking_vector field in FACS
+ * DESCRIPTION: Access function for the firmware_waking_vector field in FACS
*
******************************************************************************/
@@ -99,19 +85,20 @@ acpi_set_firmware_waking_vector (
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_get_firmware_waking_vector
*
- * PARAMETERS: *physical_address - Output buffer where contents of
+ * PARAMETERS: *physical_address - Where the contents of
* the firmware_waking_vector field of
- * the FACS will be stored.
+ * the FACS will be returned.
*
- * RETURN: Status
+ * RETURN: Status, vector
*
- * DESCRIPTION: Access function for firmware_waking_vector field in FACS
+ * DESCRIPTION: Access function for the firmware_waking_vector field in FACS
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_get_firmware_waking_vector (
@@ -141,7 +128,7 @@ acpi_get_firmware_waking_vector (
#endif
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state_prep
*
@@ -215,7 +202,7 @@ acpi_enter_sleep_state_prep (
break;
default:
- arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
+ arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
break;
}
@@ -223,14 +210,15 @@ acpi_enter_sleep_state_prep (
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+ acpi_format_exception (status)));
}
return_ACPI_STATUS (AE_OK);
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state
*
@@ -299,15 +287,18 @@ acpi_enter_sleep_state (
/* Get current value of PM1A control */
- status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "Entering sleep state [S%d]\n", sleep_state));
/* Clear SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask);
+ PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->access_bit_mask);
PM1Bcontrol = PM1Acontrol;
/* Insert SLP_TYP bits */
@@ -322,12 +313,14 @@ acpi_enter_sleep_state (
/* Write #1: fill in SLP_TYP data */
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -341,22 +334,25 @@ acpi_enter_sleep_state (
ACPI_FLUSH_CPU_CACHE ();
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
if (sleep_state > ACPI_STATE_S3) {
/*
- * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
- * we are still executing!)
+ * We wanted to sleep > S3, but it didn't happen (by virtue of the
+ * fact that we are still executing!)
*
- * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
+ * Wait ten seconds, then try again. This is to get S4/S5 to work on
+ * all machines.
*
* We wait so long to allow chipsets that poll this reg very slowly to
* still read the right value. Ideally, this block would go
@@ -364,7 +360,8 @@ acpi_enter_sleep_state (
*/
acpi_os_stall (10000000);
- status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info->access_bit_mask);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
@@ -374,7 +371,8 @@ acpi_enter_sleep_state (
/* Wait until we enter sleep state */
do {
- status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+ status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
+ ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -388,7 +386,7 @@ acpi_enter_sleep_state (
EXPORT_SYMBOL(acpi_enter_sleep_state);
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state_s4bios
*
@@ -439,11 +437,13 @@ acpi_enter_sleep_state_s4bios (
ACPI_FLUSH_CPU_CACHE ();
- status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8);
+ status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
+ (u32) acpi_gbl_FADT->S4bios_req, 8);
do {
acpi_os_stall(1000);
- status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+ status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
+ ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -454,7 +454,7 @@ acpi_enter_sleep_state_s4bios (
EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_leave_sleep_state
*
@@ -534,18 +534,21 @@ acpi_leave_sleep_state (
arg.integer.value = ACPI_SST_WAKING;
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+ acpi_format_exception (status)));
}
arg.integer.value = sleep_state;
status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Method _BFS failed, %s\n",
+ acpi_format_exception (status)));
}
status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Method _WAK failed, %s\n",
+ acpi_format_exception (status)));
}
/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
@@ -567,15 +570,19 @@ acpi_leave_sleep_state (
/* Enable power button */
- (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
+ (void) acpi_set_register(
+ acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
- (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
+
+ (void) acpi_set_register(
+ acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
1, ACPI_MTX_DO_NOT_LOCK);
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
- ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+ ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+ acpi_format_exception (status)));
}
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index 1906167d729..49d7b395322 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -43,7 +43,6 @@
*/
#include <linux/module.h>
-
#include <acpi/acpi.h>
#define _COMPONENT ACPI_HARDWARE
@@ -90,7 +89,7 @@ acpi_get_timer_resolution (
*
* PARAMETERS: Ticks - Where the timer value is returned
*
- * RETURN: Status and current ticks
+ * RETURN: Status and current timer value (ticks)
*
* DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
*
@@ -199,5 +198,6 @@ acpi_get_timer_duration (
*time_elapsed = (u32) quotient;
return_ACPI_STATUS (status);
}
+
EXPORT_SYMBOL(acpi_get_timer_duration);
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
new file mode 100644
index 00000000000..babdf762ead
--- /dev/null
+++ b/drivers/acpi/hotkey.c
@@ -0,0 +1,1019 @@
+/*
+ * hotkey.c - ACPI Hotkey Driver ($Revision:$)
+ *
+ * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define HOTKEY_ACPI_VERSION "0.1"
+
+#define HOTKEY_PROC "hotkey"
+#define HOTKEY_EV_CONFIG "event_config"
+#define HOTKEY_PL_CONFIG "poll_config"
+#define HOTKEY_ACTION "action"
+#define HOTKEY_INFO "info"
+
+#define ACPI_HOTK_NAME "Generic Hotkey Driver"
+#define ACPI_HOTK_CLASS "Hotkey"
+#define ACPI_HOTK_DEVICE_NAME "Hotkey"
+#define ACPI_HOTK_HID "Unknown?"
+#define ACPI_HOTKEY_COMPONENT 0x20000000
+
+#define ACPI_HOTKEY_EVENT 0x1
+#define ACPI_HOTKEY_POLLING 0x2
+#define ACPI_UNDEFINED_EVENT 0xf
+
+#define MAX_CONFIG_RECORD_LEN 80
+#define MAX_NAME_PATH_LEN 80
+#define MAX_CALL_PARM 80
+
+#define IS_EVENT(e) 0xff /* ((e) & 0x40000000) */
+#define IS_POLL(e) 0xff /* (~((e) & 0x40000000)) */
+
+#define _COMPONENT ACPI_HOTKEY_COMPONENT
+ACPI_MODULE_NAME("acpi_hotkey")
+
+ MODULE_AUTHOR("luming.yu@intel.com");
+MODULE_DESCRIPTION(ACPI_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+/* standardized internal hotkey number/event */
+enum {
+ /* Video Extension event */
+ HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
+ HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
+ HK_EVENT_CYCLE_DISPLAY_OUTPUT,
+ HK_EVENT_NEXT_DISPLAY_OUTPUT,
+ HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
+ HK_EVENT_CYCLE_BRIGHTNESS,
+ HK_EVENT_INCREASE_BRIGHTNESS,
+ HK_EVENT_DECREASE_BRIGHTNESS,
+ HK_EVENT_ZERO_BRIGHTNESS,
+ HK_EVENT_DISPLAY_DEVICE_OFF,
+
+ /* Snd Card event */
+ HK_EVENT_VOLUME_MUTE,
+ HK_EVENT_VOLUME_INCLREASE,
+ HK_EVENT_VOLUME_DECREASE,
+
+ /* running state control */
+ HK_EVENT_ENTERRING_S3,
+ HK_EVENT_ENTERRING_S4,
+ HK_EVENT_ENTERRING_S5,
+};
+
+/* procdir we use */
+static struct proc_dir_entry *hotkey_proc_dir;
+static struct proc_dir_entry *hotkey_config;
+static struct proc_dir_entry *hotkey_poll_config;
+static struct proc_dir_entry *hotkey_action;
+static struct proc_dir_entry *hotkey_info;
+
+/* linkage for all type of hotkey */
+struct acpi_hotkey_link {
+ struct list_head entries;
+ int hotkey_type; /* event or polling based hotkey */
+ int hotkey_standard_num; /* standardized hotkey(event) number */
+};
+
+/* event based hotkey */
+struct acpi_event_hotkey {
+ struct acpi_hotkey_link hotkey_link;
+ int flag;
+ acpi_handle bus_handle; /* bus to install notify handler */
+ int external_hotkey_num; /* external hotkey/event number */
+ acpi_handle action_handle; /* acpi handle attached aml action method */
+ char *action_method; /* action method */
+};
+
+/*
+ * There are two ways to poll status
+ * 1. directy call read_xxx method, without any arguments passed in
+ * 2. call write_xxx method, with arguments passed in, you need
+ * the result is saved in acpi_polling_hotkey.poll_result.
+ * anthoer read command through polling interface.
+ *
+ */
+
+/* polling based hotkey */
+struct acpi_polling_hotkey {
+ struct acpi_hotkey_link hotkey_link;
+ int flag;
+ acpi_handle poll_handle; /* acpi handle attached polling method */
+ char *poll_method; /* poll method */
+ acpi_handle action_handle; /* acpi handle attached action method */
+ char *action_method; /* action method */
+ void *poll_result; /* polling_result */
+ struct proc_dir_entry *proc;
+};
+
+/* hotkey object union */
+union acpi_hotkey {
+ struct list_head entries;
+ struct acpi_hotkey_link link;
+ struct acpi_event_hotkey event_hotkey;
+ struct acpi_polling_hotkey poll_hotkey;
+};
+
+/* hotkey object list */
+struct acpi_hotkey_list {
+ struct list_head *entries;
+ int count;
+};
+
+static int auto_hotkey_add(struct acpi_device *device);
+static int auto_hotkey_remove(struct acpi_device *device, int type);
+
+static struct acpi_driver hotkey_driver = {
+ .name = ACPI_HOTK_NAME,
+ .class = ACPI_HOTK_CLASS,
+ .ids = ACPI_HOTK_HID,
+ .ops = {
+ .add = auto_hotkey_add,
+ .remove = auto_hotkey_remove,
+ },
+};
+
+static int hotkey_open_config(struct inode *inode, struct file *file);
+static ssize_t hotkey_write_config(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data);
+static ssize_t hotkey_write_poll_config(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data);
+static int hotkey_info_open_fs(struct inode *inode, struct file *file);
+static int hotkey_action_open_fs(struct inode *inode, struct file *file);
+static ssize_t hotkey_execute_aml_method(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data);
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
+
+/* event based config */
+static struct file_operations hotkey_config_fops = {
+ .open = hotkey_open_config,
+ .read = seq_read,
+ .write = hotkey_write_config,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* polling based config */
+static struct file_operations hotkey_poll_config_fops = {
+ .open = hotkey_open_config,
+ .read = seq_read,
+ .write = hotkey_write_poll_config,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* hotkey driver info */
+static struct file_operations hotkey_info_fops = {
+ .open = hotkey_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* action */
+static struct file_operations hotkey_action_fops = {
+ .open = hotkey_action_open_fs,
+ .read = seq_read,
+ .write = hotkey_execute_aml_method,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* polling results */
+static struct file_operations hotkey_polling_fops = {
+ .open = hotkey_polling_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+struct acpi_hotkey_list global_hotkey_list; /* link all ev or pl hotkey */
+struct list_head hotkey_entries; /* head of the list of hotkey_list */
+
+static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
+{
+ ACPI_FUNCTION_TRACE("hotkey_info_seq_show");
+
+ seq_printf(seq, "Hotkey generic driver ver: %s", HOTKEY_ACPI_VERSION);
+
+ return_VALUE(0);
+}
+
+static int hotkey_info_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+static char *format_result(union acpi_object *object)
+{
+ char *buf = (char *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+
+ memset(buf, 0, sizeof(union acpi_object));
+
+ /* Now, just support integer type */
+ if (object->type == ACPI_TYPE_INTEGER)
+ sprintf(buf, "%d", (u32) object->integer.value);
+
+ return buf;
+}
+
+static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
+{
+ struct acpi_polling_hotkey *poll_hotkey =
+ (struct acpi_polling_hotkey *)seq->private;
+
+ ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
+
+ if (poll_hotkey->poll_result)
+ seq_printf(seq, "%s", format_result(poll_hotkey->poll_result));
+
+ return_VALUE(0);
+}
+
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
+}
+
+static int hotkey_action_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+/* Mapping external hotkey number to standardized hotkey event num */
+static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
+{
+ struct list_head *entries, *next;
+ int val = 0;
+
+ ACPI_FUNCTION_TRACE("hotkey_get_internal_event");
+
+ list_for_each_safe(entries, next, list->entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
+ && key->event_hotkey.external_hotkey_num == event)
+ val = key->link.hotkey_standard_num;
+ else
+ val = -1;
+ }
+
+ return_VALUE(val);
+}
+
+static void
+acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_device *device = NULL;
+ u32 internal_event;
+
+ ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");
+
+ if (acpi_bus_get_device(handle, &device))
+ return_VOID;
+
+ internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
+ acpi_bus_generate_event(device, event, 0);
+
+ return_VOID;
+}
+
+/* Need to invent automatically hotkey add method */
+static int auto_hotkey_add(struct acpi_device *device)
+{
+ /* Implement me */
+ return 0;
+}
+
+/* Need to invent automatically hotkey remove method */
+static int auto_hotkey_remove(struct acpi_device *device, int type)
+{
+ /* Implement me */
+ return 0;
+}
+
+/* Create a proc file for each polling method */
+static int create_polling_proc(union acpi_hotkey *device)
+{
+ struct proc_dir_entry *proc;
+ mode_t mode;
+
+ ACPI_FUNCTION_TRACE("create_polling_proc");
+ mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+ proc = create_proc_entry(device->poll_hotkey.action_method,
+ mode, hotkey_proc_dir);
+
+ if (!proc) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ device->poll_hotkey.poll_method));
+ return_VALUE(-ENODEV);
+ } else {
+ proc->proc_fops = &hotkey_polling_fops;
+ proc->owner = THIS_MODULE;
+ proc->data = device;
+ proc->uid = 0;
+ proc->gid = 0;
+ device->poll_hotkey.proc = proc;
+ }
+ return_VALUE(0);
+}
+
+static int is_valid_acpi_path(const char *pathname)
+{
+ acpi_handle handle;
+ acpi_status status;
+ ACPI_FUNCTION_TRACE("is_valid_acpi_path");
+
+ status = acpi_get_handle(NULL, (char *)pathname, &handle);
+ return_VALUE(!ACPI_FAILURE(status));
+}
+
+static int is_valid_hotkey(union acpi_hotkey *device)
+{
+ ACPI_FUNCTION_TRACE("is_valid_hotkey");
+ /* Implement valid check */
+ return_VALUE(1);
+}
+
+static int hotkey_add(union acpi_hotkey *device)
+{
+ int status = 0;
+ struct acpi_device *dev = NULL;
+
+ ACPI_FUNCTION_TRACE("hotkey_add");
+
+ if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+ status =
+ acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
+ if (status)
+ return_VALUE(status);
+
+ status = acpi_install_notify_handler(dev->handle,
+ ACPI_SYSTEM_NOTIFY,
+ acpi_hotkey_notify_handler,
+ device);
+ } else /* Add polling hotkey */
+ create_polling_proc(device);
+
+ global_hotkey_list.count++;
+
+ list_add_tail(&device->link.entries, global_hotkey_list.entries);
+
+ return_VALUE(status);
+}
+
+static int hotkey_remove(union acpi_hotkey *device)
+{
+ struct list_head *entries, *next;
+
+ ACPI_FUNCTION_TRACE("hotkey_remove");
+
+ list_for_each_safe(entries, next, global_hotkey_list.entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_standard_num ==
+ device->link.hotkey_standard_num) {
+ list_del(&key->link.entries);
+ remove_proc_entry(key->poll_hotkey.action_method,
+ hotkey_proc_dir);
+ global_hotkey_list.count--;
+ break;
+ }
+ }
+ return_VALUE(0);
+}
+
+static void hotkey_update(union acpi_hotkey *key)
+{
+ struct list_head *entries, *next;
+
+ ACPI_FUNCTION_TRACE("hotkey_update");
+
+ list_for_each_safe(entries, next, global_hotkey_list.entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_standard_num ==
+ key->link.hotkey_standard_num) {
+ key->event_hotkey.bus_handle =
+ key->event_hotkey.bus_handle;
+ key->event_hotkey.external_hotkey_num =
+ key->event_hotkey.external_hotkey_num;
+ key->event_hotkey.action_handle =
+ key->event_hotkey.action_handle;
+ key->event_hotkey.action_method =
+ key->event_hotkey.action_method;
+ break;
+ }
+ }
+
+ return_VOID;
+}
+
+static void free_hotkey_device(union acpi_hotkey *key)
+{
+ struct acpi_device *dev;
+ int status;
+
+ ACPI_FUNCTION_TRACE("free_hotkey_device");
+
+ if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+ status =
+ acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
+ if (dev->handle)
+ acpi_remove_notify_handler(dev->handle,
+ ACPI_SYSTEM_NOTIFY,
+ acpi_hotkey_notify_handler);
+ } else
+ remove_proc_entry(key->poll_hotkey.action_method,
+ hotkey_proc_dir);
+ kfree(key);
+ return_VOID;
+}
+
+static int
+init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
+ char *method, int std_num, int external_num)
+{
+ ACPI_FUNCTION_TRACE("init_hotkey_device");
+
+ key->link.hotkey_type = ACPI_HOTKEY_EVENT;
+ key->link.hotkey_standard_num = std_num;
+ key->event_hotkey.flag = 0;
+ if (is_valid_acpi_path(bus_str))
+ acpi_get_handle((acpi_handle) 0,
+ bus_str, &(key->event_hotkey.bus_handle));
+ else
+ return_VALUE(-ENODEV);
+ key->event_hotkey.external_hotkey_num = external_num;
+ if (is_valid_acpi_path(action_str))
+ acpi_get_handle((acpi_handle) 0,
+ action_str, &(key->event_hotkey.action_handle));
+ key->event_hotkey.action_method = kmalloc(sizeof(method), GFP_KERNEL);
+ strcpy(key->event_hotkey.action_method, method);
+
+ return_VALUE(!is_valid_hotkey(key));
+}
+
+static int
+init_poll_hotkey_device(union acpi_hotkey *key,
+ char *poll_str,
+ char *poll_method,
+ char *action_str, char *action_method, int std_num)
+{
+ ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
+
+ key->link.hotkey_type = ACPI_HOTKEY_POLLING;
+ key->link.hotkey_standard_num = std_num;
+ key->poll_hotkey.flag = 0;
+ if (is_valid_acpi_path(poll_str))
+ acpi_get_handle((acpi_handle) 0,
+ poll_str, &(key->poll_hotkey.poll_handle));
+ else
+ return_VALUE(-ENODEV);
+ key->poll_hotkey.poll_method = poll_method;
+ if (is_valid_acpi_path(action_str))
+ acpi_get_handle((acpi_handle) 0,
+ action_str, &(key->poll_hotkey.action_handle));
+ key->poll_hotkey.action_method =
+ kmalloc(sizeof(action_method), GFP_KERNEL);
+ strcpy(key->poll_hotkey.action_method, action_method);
+ key->poll_hotkey.poll_result =
+ (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+ return_VALUE(is_valid_hotkey(key));
+}
+
+static int check_hotkey_valid(union acpi_hotkey *key,
+ struct acpi_hotkey_list *list)
+{
+ ACPI_FUNCTION_TRACE("check_hotkey_valid");
+ return_VALUE(0);
+}
+
+static int hotkey_open_config(struct inode *inode, struct file *file)
+{
+ ACPI_FUNCTION_TRACE("hotkey_open_config");
+ return_VALUE(single_open
+ (file, hotkey_config_seq_show, PDE(inode)->data));
+}
+
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
+{
+ struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+ struct list_head *entries, *next;
+ char bus_name[ACPI_PATHNAME_MAX] = { 0 };
+ char action_name[ACPI_PATHNAME_MAX] = { 0 };
+ struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
+ struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
+
+ ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
+
+ if (!hotkey_list)
+ goto end;
+
+ list_for_each_safe(entries, next, hotkey_list->entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+ acpi_get_name(key->event_hotkey.bus_handle,
+ ACPI_NAME_TYPE_MAX, &bus);
+ acpi_get_name(key->event_hotkey.action_handle,
+ ACPI_NAME_TYPE_MAX, &act);
+ seq_printf(seq, "%s:%s:%s:%d:%d", bus_name,
+ action_name,
+ key->event_hotkey.action_method,
+ key->link.hotkey_standard_num,
+ key->event_hotkey.external_hotkey_num);
+ } /* ACPI_HOTKEY_POLLING */
+ else {
+ acpi_get_name(key->poll_hotkey.poll_handle,
+ ACPI_NAME_TYPE_MAX, &bus);
+ acpi_get_name(key->poll_hotkey.action_handle,
+ ACPI_NAME_TYPE_MAX, &act);
+ seq_printf(seq, "%s:%s:%s:%s:%d", bus_name,
+ key->poll_hotkey.poll_method,
+ action_name,
+ key->poll_hotkey.action_method,
+ key->link.hotkey_standard_num);
+ }
+ }
+ seq_puts(seq, "\n");
+ end:
+ return_VALUE(0);
+}
+
+static int
+get_parms(char *config_record,
+ int *cmd,
+ char *bus_handle,
+ char *bus_method,
+ char *action_handle,
+ char *method, int *internal_event_num, int *external_event_num)
+{
+ char *tmp, *tmp1;
+ ACPI_FUNCTION_TRACE(("get_parms"));
+
+ sscanf(config_record, "%d", cmd);
+
+ tmp = strchr(config_record, ':');
+ tmp++;
+ tmp1 = strchr(tmp, ':');
+ strncpy(bus_handle, tmp, tmp1 - tmp);
+ bus_handle[tmp1 - tmp] = 0;
+
+ tmp = tmp1;
+ tmp++;
+ tmp1 = strchr(tmp, ':');
+ strncpy(bus_method, tmp, tmp1 - tmp);
+ bus_method[tmp1 - tmp] = 0;
+
+ tmp = tmp1;
+ tmp++;
+ tmp1 = strchr(tmp, ':');
+ strncpy(action_handle, tmp, tmp1 - tmp);
+ action_handle[tmp1 - tmp] = 0;
+
+ tmp = tmp1;
+ tmp++;
+ tmp1 = strchr(tmp, ':');
+ strncpy(method, tmp, tmp1 - tmp);
+ method[tmp1 - tmp] = 0;
+
+ sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num);
+ return_VALUE(6);
+}
+
+/* count is length for one input record */
+static ssize_t hotkey_write_config(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
+{
+ struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+ char config_record[MAX_CONFIG_RECORD_LEN];
+ char bus_handle[MAX_NAME_PATH_LEN];
+ char bus_method[MAX_NAME_PATH_LEN];
+ char action_handle[MAX_NAME_PATH_LEN];
+ char method[20];
+ int cmd, internal_event_num, external_event_num;
+ int ret = 0;
+ union acpi_hotkey *key = NULL;
+
+ ACPI_FUNCTION_TRACE(("hotkey_write_config"));
+
+ if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
+ return_VALUE(-EINVAL);
+ }
+
+ if (copy_from_user(config_record, buffer, count)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
+ return_VALUE(-EINVAL);
+ }
+ config_record[count] = '\0';
+
+ ret = get_parms(config_record,
+ &cmd,
+ bus_handle,
+ bus_method,
+ action_handle,
+ method, &internal_event_num, &external_event_num);
+ if (ret != 6) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Invalid data format ret=%d\n", ret));
+ return_VALUE(-EINVAL);
+ }
+
+ key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
+ ret = init_hotkey_device(key, bus_handle, action_handle, method,
+ internal_event_num, external_event_num);
+
+ if (ret || check_hotkey_valid(key, hotkey_list)) {
+ kfree(key);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
+ return_VALUE(-EINVAL);
+ }
+ switch (cmd) {
+ case 0:
+ hotkey_add(key);
+ break;
+ case 1:
+ hotkey_remove(key);
+ free_hotkey_device(key);
+ break;
+ case 2:
+ hotkey_update(key);
+ break;
+ default:
+ break;
+ }
+ return_VALUE(count);
+}
+
+/* count is length for one input record */
+static ssize_t hotkey_write_poll_config(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
+{
+ struct seq_file *m = (struct seq_file *)file->private_data;
+ struct acpi_hotkey_list *hotkey_list =
+ (struct acpi_hotkey_list *)m->private;
+
+ char config_record[MAX_CONFIG_RECORD_LEN];
+ char polling_handle[MAX_NAME_PATH_LEN];
+ char action_handle[MAX_NAME_PATH_LEN];
+ char poll_method[20], action_method[20];
+ int ret, internal_event_num, cmd, external_event_num;
+ union acpi_hotkey *key = NULL;
+
+ ACPI_FUNCTION_TRACE("hotkey_write_poll_config");
+
+ if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
+ return_VALUE(-EINVAL);
+ }
+
+ if (copy_from_user(config_record, buffer, count)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
+ return_VALUE(-EINVAL);
+ }
+ config_record[count] = '\0';
+
+ ret = get_parms(config_record,
+ &cmd,
+ polling_handle,
+ poll_method,
+ action_handle,
+ action_method,
+ &internal_event_num, &external_event_num);
+
+ if (ret != 6) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
+ return_VALUE(-EINVAL);
+ }
+
+ key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
+ ret = init_poll_hotkey_device(key, polling_handle, poll_method,
+ action_handle, action_method,
+ internal_event_num);
+ if (ret || check_hotkey_valid(key, hotkey_list)) {
+ kfree(key);
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
+ return_VALUE(-EINVAL);
+ }
+ switch (cmd) {
+ case 0:
+ hotkey_add(key);
+ break;
+ case 1:
+ hotkey_remove(key);
+ break;
+ case 2:
+ hotkey_update(key);
+ break;
+ default:
+ break;
+ }
+ return_VALUE(count);
+}
+
+/*
+ * This function evaluates an ACPI method, given an int as parameter, the
+ * method is searched within the scope of the handle, can be NULL. The output
+ * of the method is written is output, which can also be NULL
+ *
+ * returns 1 if write is successful, 0 else.
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+ struct acpi_buffer *output)
+{
+ struct acpi_object_list params; /* list of input parameters (an int here) */
+ union acpi_object in_obj; /* the only param we use */
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("write_acpi_int");
+ params.count = 1;
+ params.pointer = &in_obj;
+ in_obj.type = ACPI_TYPE_INTEGER;
+ in_obj.integer.value = val;
+
+ status = acpi_evaluate_object(handle, (char *)method, &params, output);
+
+ return_VALUE(status == AE_OK);
+}
+
+static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+{
+ struct acpi_buffer output;
+ union acpi_object out_obj;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE("read_acpi_int");
+ output.length = sizeof(out_obj);
+ output.pointer = &out_obj;
+
+ status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
+ *val = out_obj.integer.value;
+ return_VALUE((status == AE_OK)
+ && (out_obj.type == ACPI_TYPE_INTEGER));
+}
+
+static acpi_handle
+get_handle_from_hotkeylist(struct acpi_hotkey_list *hotkey_list, int event_num)
+{
+ struct list_head *entries, *next;
+
+ list_for_each_safe(entries, next, hotkey_list->entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
+ && key->link.hotkey_standard_num == event_num) {
+ return (key->event_hotkey.action_handle);
+ }
+ }
+ return (NULL);
+}
+
+static
+char *get_method_from_hotkeylist(struct acpi_hotkey_list *hotkey_list,
+ int event_num)
+{
+ struct list_head *entries, *next;
+
+ list_for_each_safe(entries, next, hotkey_list->entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+
+ if (key->link.hotkey_type == ACPI_HOTKEY_EVENT &&
+ key->link.hotkey_standard_num == event_num)
+ return (key->event_hotkey.action_method);
+ }
+ return (NULL);
+}
+
+static struct acpi_polling_hotkey *get_hotkey_by_event(struct
+ acpi_hotkey_list
+ *hotkey_list, int event)
+{
+ struct list_head *entries, *next;
+
+ list_for_each_safe(entries, next, hotkey_list->entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+ if (key->link.hotkey_type == ACPI_HOTKEY_POLLING
+ && key->link.hotkey_standard_num == event) {
+ return (&key->poll_hotkey);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * user call AML method interface:
+ * Call convention:
+ * echo "event_num: arg type : value"
+ * example: echo "1:1:30" > /proc/acpi/action
+ * Just support 1 integer arg passing to AML method
+ */
+
+static ssize_t hotkey_execute_aml_method(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * data)
+{
+ struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+ char arg[MAX_CALL_PARM];
+ int event, type, value;
+
+ char *method;
+ acpi_handle handle;
+
+ ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
+
+ if (!hotkey_list || count > MAX_CALL_PARM) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 1"));
+ return_VALUE(-EINVAL);
+ }
+
+ if (copy_from_user(arg, buffer, count)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2"));
+ return_VALUE(-EINVAL);
+ }
+
+ arg[count] = '\0';
+
+ if (sscanf(arg, "%d:%d:%d", &event, &type, &value) != 3) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
+ return_VALUE(-EINVAL);
+ }
+
+ if (type == ACPI_TYPE_INTEGER) {
+ handle = get_handle_from_hotkeylist(hotkey_list, event);
+ method = (char *)get_method_from_hotkeylist(hotkey_list, event);
+ if (IS_EVENT(event))
+ write_acpi_int(handle, method, value, NULL);
+ else if (IS_POLL(event)) {
+ struct acpi_polling_hotkey *key;
+ key = (struct acpi_polling_hotkey *)
+ get_hotkey_by_event(hotkey_list, event);
+ read_acpi_int(handle, method, key->poll_result);
+ }
+ } else {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported"));
+ return_VALUE(-EINVAL);
+ }
+
+ return_VALUE(count);
+}
+
+static int __init hotkey_init(void)
+{
+ int result;
+ mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+ ACPI_FUNCTION_TRACE("hotkey_init");
+
+ if (acpi_disabled)
+ return -ENODEV;
+
+ if (acpi_specific_hotkey_enabled) {
+ printk("Using specific hotkey driver\n");
+ return -ENODEV;
+ }
+
+ hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
+ if (!hotkey_proc_dir) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ HOTKEY_PROC));
+ return (-ENODEV);
+ }
+ hotkey_proc_dir->owner = THIS_MODULE;
+
+ hotkey_config =
+ create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
+ if (!hotkey_config) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ HOTKEY_EV_CONFIG));
+ return (-ENODEV);
+ } else {
+ hotkey_config->proc_fops = &hotkey_config_fops;
+ hotkey_config->data = &global_hotkey_list;
+ hotkey_config->owner = THIS_MODULE;
+ hotkey_config->uid = 0;
+ hotkey_config->gid = 0;
+ }
+
+ hotkey_poll_config =
+ create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
+ if (!hotkey_poll_config) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ HOTKEY_EV_CONFIG));
+ return (-ENODEV);
+ } else {
+ hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
+ hotkey_poll_config->data = &global_hotkey_list;
+ hotkey_poll_config->owner = THIS_MODULE;
+ hotkey_poll_config->uid = 0;
+ hotkey_poll_config->gid = 0;
+ }
+
+ hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
+ if (!hotkey_action) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ HOTKEY_ACTION));
+ return (-ENODEV);
+ } else {
+ hotkey_action->proc_fops = &hotkey_action_fops;
+ hotkey_action->owner = THIS_MODULE;
+ hotkey_action->uid = 0;
+ hotkey_action->gid = 0;
+ }
+
+ hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
+ if (!hotkey_info) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Hotkey: Unable to create %s entry\n",
+ HOTKEY_INFO));
+ return (-ENODEV);
+ } else {
+ hotkey_info->proc_fops = &hotkey_info_fops;
+ hotkey_info->owner = THIS_MODULE;
+ hotkey_info->uid = 0;
+ hotkey_info->gid = 0;
+ }
+
+ result = acpi_bus_register_driver(&hotkey_driver);
+ if (result < 0) {
+ remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+ return (-ENODEV);
+ }
+ global_hotkey_list.count = 0;
+ global_hotkey_list.entries = &hotkey_entries;
+
+ INIT_LIST_HEAD(&hotkey_entries);
+
+ return (0);
+}
+
+static void __exit hotkey_exit(void)
+{
+ struct list_head *entries, *next;
+
+ ACPI_FUNCTION_TRACE("hotkey_remove");
+
+ list_for_each_safe(entries, next, global_hotkey_list.entries) {
+ union acpi_hotkey *key =
+ container_of(entries, union acpi_hotkey, entries);
+
+ acpi_os_wait_events_complete(NULL);
+ list_del(&key->link.entries);
+ global_hotkey_list.count--;
+ free_hotkey_device(key);
+ }
+ acpi_bus_unregister_driver(&hotkey_driver);
+ remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
+ remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
+ remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
+ remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
+ remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+ return;
+}
+
+module_init(hotkey_init);
+module_exit(hotkey_exit);
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 0fb731a470d..ad85e10001f 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1025,7 +1025,7 @@ static int setup_notify(struct ibm_struct *ibm)
return 0;
}
-static int device_add(struct acpi_device *device)
+static int ibmacpi_device_add(struct acpi_device *device)
{
return 0;
}
@@ -1043,7 +1043,7 @@ static int register_driver(struct ibm_struct *ibm)
memset(ibm->driver, 0, sizeof(struct acpi_driver));
sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
ibm->driver->ids = ibm->hid;
- ibm->driver->ops.add = &device_add;
+ ibm->driver->ops.add = &ibmacpi_device_add;
ret = acpi_bus_register_driver(ibm->driver);
if (ret < 0) {
@@ -1185,6 +1185,10 @@ static int __init acpi_ibm_init(void)
if (acpi_disabled)
return -ENODEV;
+ if (!acpi_specific_hotkey_enabled){
+ printk(IBM_ERR "Using generic hotkey driver\n");
+ return -ENODEV;
+ }
/* these handles are required */
if (IBM_HANDLE_INIT(ec, 1) < 0 ||
IBM_HANDLE_INIT(hkey, 1) < 0 ||
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index 1c0c12336c5..ece7a9dedd5 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -67,7 +67,8 @@
******************************************************************************/
acpi_status
-acpi_ns_root_initialize (void)
+acpi_ns_root_initialize (
+ void)
{
acpi_status status;
const struct acpi_predefined_names *init_val = NULL;
@@ -265,7 +266,7 @@ unlock_and_exit:
*
* FUNCTION: acpi_ns_lookup
*
- * PARAMETERS: prefix_node - Search scope if name is not fully qualified
+ * PARAMETERS: scope_info - Current scope info block
* Pathname - Search pathname, in internal format
* (as represented in the AML stream)
* Type - Type associated with name
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index bfd922c5c7d..5653a19d717 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -49,14 +49,20 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsalloc")
+/* Local prototypes */
+
+static void
+acpi_ns_remove_reference (
+ struct acpi_namespace_node *node);
+
/*******************************************************************************
*
* FUNCTION: acpi_ns_create_node
*
- * PARAMETERS: acpi_name - Name of the new node
+ * PARAMETERS: Name - Name of the new node (4 char ACPI name)
*
- * RETURN: None
+ * RETURN: New namespace node (Null on failure)
*
* DESCRIPTION: Create a namespace node
*
@@ -145,7 +151,6 @@ acpi_ns_delete_node (
}
}
-
ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
/*
@@ -157,57 +162,6 @@ acpi_ns_delete_node (
}
-#ifdef ACPI_ALPHABETIC_NAMESPACE
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_compare_names
- *
- * PARAMETERS: Name1 - First name to compare
- * Name2 - Second name to compare
- *
- * RETURN: value from strncmp
- *
- * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an
- * underscore are forced to be alphabetically first.
- *
- ******************************************************************************/
-
-int
-acpi_ns_compare_names (
- char *name1,
- char *name2)
-{
- char reversed_name1[ACPI_NAME_SIZE];
- char reversed_name2[ACPI_NAME_SIZE];
- u32 i;
- u32 j;
-
-
- /*
- * Replace all instances of "underscore" with a value that is smaller so
- * that all names that are prefixed with underscore(s) are alphabetically
- * first.
- *
- * Reverse the name bytewise so we can just do a 32-bit compare instead
- * of a strncmp.
- */
- for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
- reversed_name1[j] = name1[i];
- if (name1[i] == '_') {
- reversed_name1[j] = '*';
- }
-
- reversed_name2[j] = name2[i];
- if (name2[i] == '_') {
- reversed_name2[j] = '*';
- }
- }
-
- return (*(int *) reversed_name1 - *(int *) reversed_name2);
-}
-#endif
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_install_node
@@ -271,7 +225,8 @@ acpi_ns_install_node (
* alphabetic placement.
*/
previous_child_node = NULL;
- while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) {
+ while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node),
+ acpi_ut_get_node_name (node)) < 0) {
if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
/* Last peer; Clear end-of-list flag */
@@ -429,7 +384,8 @@ acpi_ns_delete_children (
/* There should be only one reference remaining on this node */
if (child_node->reference_count != 1) {
- ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
+ ACPI_REPORT_WARNING ((
+ "Existing references (%d) on node being deleted (%p)\n",
child_node->reference_count, child_node));
}
@@ -548,7 +504,7 @@ acpi_ns_delete_namespace_subtree (
*
******************************************************************************/
-void
+static void
acpi_ns_remove_reference (
struct acpi_namespace_node *node)
{
@@ -683,3 +639,54 @@ acpi_ns_delete_namespace_by_owner (
}
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ns_compare_names
+ *
+ * PARAMETERS: Name1 - First name to compare
+ * Name2 - Second name to compare
+ *
+ * RETURN: value from strncmp
+ *
+ * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an
+ * underscore are forced to be alphabetically first.
+ *
+ ******************************************************************************/
+
+int
+acpi_ns_compare_names (
+ char *name1,
+ char *name2)
+{
+ char reversed_name1[ACPI_NAME_SIZE];
+ char reversed_name2[ACPI_NAME_SIZE];
+ u32 i;
+ u32 j;
+
+
+ /*
+ * Replace all instances of "underscore" with a value that is smaller so
+ * that all names that are prefixed with underscore(s) are alphabetically
+ * first.
+ *
+ * Reverse the name bytewise so we can just do a 32-bit compare instead
+ * of a strncmp.
+ */
+ for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
+ reversed_name1[j] = name1[i];
+ if (name1[i] == '_') {
+ reversed_name1[j] = '*';
+ }
+
+ reversed_name2[j] = name2[i];
+ if (name2[i] == '_') {
+ reversed_name2[j] = '*';
+ }
+ }
+
+ return (*(int *) reversed_name1 - *(int *) reversed_name2);
+}
+#endif
+
+
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 1f6af3eb6c9..6c2aef0e0dd 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -50,16 +50,32 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsdump")
+/* Local prototypes */
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+acpi_ns_dump_root_devices (
+ void);
+static acpi_status
+acpi_ns_dump_one_device (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+#endif
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/*******************************************************************************
*
* FUNCTION: acpi_ns_print_pathname
*
- * PARAMETERS: num_segment - Number of ACPI name segments
+ * PARAMETERS: num_segments - Number of ACPI name segments
* Pathname - The compressed (internal) path
*
+ * RETURN: None
+ *
* DESCRIPTION: Print an object's full namespace pathname
*
******************************************************************************/
@@ -103,6 +119,8 @@ acpi_ns_print_pathname (
* Level - Desired debug level
* Component - Caller's component ID
*
+ * RETURN: None
+ *
* DESCRIPTION: Print an object's full namespace pathname
* Manages allocation/freeing of a pathname buffer
*
@@ -137,9 +155,12 @@ acpi_ns_dump_pathname (
*
* FUNCTION: acpi_ns_dump_one_object
*
- * PARAMETERS: Handle - Node to be dumped
+ * PARAMETERS: obj_handle - Node to be dumped
* Level - Nesting level of the handle
* Context - Passed into walk_namespace
+ * return_value - Not used
+ *
+ * RETURN: Status
*
* DESCRIPTION: Dump a single Node
* This procedure is a user_function called by acpi_ns_walk_namespace.
@@ -394,8 +415,7 @@ acpi_ns_dump_one_object (
return (AE_OK);
}
- acpi_os_printf ("(R%d)",
- obj_desc->common.reference_count);
+ acpi_os_printf ("(R%d)", obj_desc->common.reference_count);
switch (type) {
case ACPI_TYPE_METHOD:
@@ -551,18 +571,20 @@ cleanup:
#ifdef ACPI_FUTURE_USAGE
-
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_objects
*
* PARAMETERS: Type - Object type to be dumped
+ * display_type - 0 or ACPI_DISPLAY_SUMMARY
* max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX
* for an effectively unlimited depth.
* owner_id - Dump only objects owned by this ID. Use
* ACPI_UINT32_MAX to match all owners.
* start_handle - Where in namespace to start/end search
*
+ * RETURN: None
+ *
* DESCRIPTION: Dump typed objects within the loaded namespace.
* Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
*
@@ -590,10 +612,44 @@ acpi_ns_dump_objects (
ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
(void *) &info, NULL);
}
+#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
+ * FUNCTION: acpi_ns_dump_entry
+ *
+ * PARAMETERS: Handle - Node to be dumped
+ * debug_level - Output level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a single Node
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_entry (
+ acpi_handle handle,
+ u32 debug_level)
+{
+ struct acpi_walk_info info;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ info.debug_level = debug_level;
+ info.owner_id = ACPI_UINT32_MAX;
+ info.display_type = ACPI_DISPLAY_SUMMARY;
+
+ (void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
+}
+
+
+#ifdef _ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
* FUNCTION: acpi_ns_dump_tables
*
* PARAMETERS: search_base - Root of subtree to be dumped, or
@@ -601,6 +657,8 @@ acpi_ns_dump_objects (
* max_depth - Maximum depth of dump. Use INT_MAX
* for an effectively unlimited depth.
*
+ * RETURN: None
+ *
* DESCRIPTION: Dump the name space, or a portion of it.
*
******************************************************************************/
@@ -626,7 +684,7 @@ acpi_ns_dump_tables (
}
if (ACPI_NS_ALL == search_base) {
- /* entire namespace */
+ /* Entire namespace */
search_handle = acpi_gbl_root_node;
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
@@ -636,38 +694,5 @@ acpi_ns_dump_tables (
ACPI_UINT32_MAX, search_handle);
return_VOID;
}
-
-#endif /* ACPI_FUTURE_USAGE */
-
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ns_dump_entry
- *
- * PARAMETERS: Handle - Node to be dumped
- * debug_level - Output level
- *
- * DESCRIPTION: Dump a single Node
- *
- ******************************************************************************/
-
-void
-acpi_ns_dump_entry (
- acpi_handle handle,
- u32 debug_level)
-{
- struct acpi_walk_info info;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- info.debug_level = debug_level;
- info.owner_id = ACPI_UINT32_MAX;
- info.display_type = ACPI_DISPLAY_SUMMARY;
-
- (void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
-}
-
-#endif
-
+#endif /* _ACPI_ASL_COMPILER */
+#endif /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index d30a59e6b07..27c4f7cd2a4 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -43,15 +43,18 @@
#include <acpi/acpi.h>
-#include <acpi/acnamesp.h>
+/* TBD: This entire module is apparently obsolete and should be removed */
+
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsdumpdv")
-
+#ifdef ACPI_OBSOLETE_FUNCTIONS
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+#include <acpi/acnamesp.h>
+
/*******************************************************************************
*
* FUNCTION: acpi_ns_dump_one_device
@@ -59,13 +62,16 @@
* PARAMETERS: Handle - Node to be dumped
* Level - Nesting level of the handle
* Context - Passed into walk_namespace
+ * return_value - Not used
+ *
+ * RETURN: Status
*
* DESCRIPTION: Dump a single Node that represents a device
* This procedure is a user_function called by acpi_ns_walk_namespace.
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_dump_one_device (
acpi_handle obj_handle,
u32 level,
@@ -108,12 +114,15 @@ acpi_ns_dump_one_device (
*
* PARAMETERS: None
*
+ * RETURN: None
+ *
* DESCRIPTION: Dump all objects of type "device"
*
******************************************************************************/
void
-acpi_ns_dump_root_devices (void)
+acpi_ns_dump_root_devices (
+ void)
{
acpi_handle sys_bus_handle;
acpi_status status;
@@ -142,5 +151,6 @@ acpi_ns_dump_root_devices (void)
}
#endif
+#endif
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 0d008d53657..1ae89a1c882 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -52,19 +52,33 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nseval")
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_execute_control_method (
+ struct acpi_parameter_info *info);
+
+static acpi_status
+acpi_ns_get_object_value (
+ struct acpi_parameter_info *info);
+
/*******************************************************************************
*
* FUNCTION: acpi_ns_evaluate_relative
*
- * PARAMETERS: Pathname - Name of method to execute, If NULL, the
- * handle is the object to execute
- * Info - Method info block
+ * PARAMETERS: Pathname - Name of method to execute, If NULL, the
+ * handle is the object to execute
+ * Info - Method info block, contains:
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * Params - List of parameters to pass to the method,
+ * terminated by NULL. Params itself may be
+ * NULL if no parameters are being passed.
*
* RETURN: Status
*
- * DESCRIPTION: Find and execute the requested method using the handle as a
- * scope
+ * DESCRIPTION: Evaluate the object or find and execute the requested method
*
* MUTEX: Locks Namespace
*
@@ -157,8 +171,8 @@ cleanup1:
*
* FUNCTION: acpi_ns_evaluate_by_name
*
- * PARAMETERS: Pathname - Fully qualified pathname to the object
- * Info - Contains:
+ * PARAMETERS: Pathname - Fully qualified pathname to the object
+ * Info - Method info block, contains:
* return_object - Where to put method's return value (if
* any). If NULL, no value is returned.
* Params - List of parameters to pass to the method,
@@ -167,8 +181,8 @@ cleanup1:
*
* RETURN: Status
*
- * DESCRIPTION: Find and execute the requested method passing the given
- * parameters
+ * DESCRIPTION: Evaluate the object or rind and execute the requested method
+ * passing the given parameters
*
* MUTEX: Locks Namespace
*
@@ -241,17 +255,21 @@ cleanup:
*
* FUNCTION: acpi_ns_evaluate_by_handle
*
- * PARAMETERS: Handle - Method Node to execute
- * Params - List of parameters to pass to the method,
- * terminated by NULL. Params itself may be
+ * PARAMETERS: Info - Method info block, contains:
+ * Node - Method/Object Node to execute
+ * Parameters - List of parameters to pass to the method,
+ * terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
- * param_type - Type of Parameter list
- * return_object - Where to put method's return value (if
- * any). If NULL, no value is returned.
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * parameter_type - Type of Parameter list
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
*
* RETURN: Status
*
- * DESCRIPTION: Execute the requested method passing the given parameters
+ * DESCRIPTION: Evaluate object or execute the requested method passing the
+ * given parameters
*
* MUTEX: Locks Namespace
*
@@ -345,7 +363,16 @@ acpi_ns_evaluate_by_handle (
*
* FUNCTION: acpi_ns_execute_control_method
*
- * PARAMETERS: Info - Method info block (w/params)
+ * PARAMETERS: Info - Method info block, contains:
+ * Node - Method Node to execute
+ * Parameters - List of parameters to pass to the method,
+ * terminated by NULL. Params itself may be
+ * NULL if no parameters are being passed.
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * parameter_type - Type of Parameter list
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
*
* RETURN: Status
*
@@ -355,7 +382,7 @@ acpi_ns_evaluate_by_handle (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_execute_control_method (
struct acpi_parameter_info *info)
{
@@ -414,7 +441,10 @@ acpi_ns_execute_control_method (
*
* FUNCTION: acpi_ns_get_object_value
*
- * PARAMETERS: Info - Method info block (w/params)
+ * PARAMETERS: Info - Method info block, contains:
+ * Node - Object's NS node
+ * return_object - Where to put object value (if
+ * any). If NULL, no value is returned.
*
* RETURN: Status
*
@@ -424,7 +454,7 @@ acpi_ns_execute_control_method (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_get_object_value (
struct acpi_parameter_info *info)
{
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 4a46b380605..362802ae29a 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -50,6 +50,22 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsinit")
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_init_one_object (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+
+static acpi_status
+acpi_ns_init_one_device (
+ acpi_handle obj_handle,
+ u32 nesting_level,
+ void *context,
+ void **return_value);
+
/*******************************************************************************
*
@@ -191,7 +207,7 @@ acpi_ns_initialize_devices (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_init_one_object (
acpi_handle obj_handle,
u32 level,
@@ -331,7 +347,7 @@ acpi_ns_init_one_object (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_init_one_device (
acpi_handle obj_handle,
u32 nesting_level,
@@ -374,7 +390,8 @@ acpi_ns_init_one_device (
/*
* Run _STA to determine if we can run _INI on the device.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA"));
+ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
+ pinfo.node, METHOD_NAME__STA));
status = acpi_ut_execute_STA (pinfo.node, &flags);
if (ACPI_FAILURE (status)) {
@@ -399,8 +416,9 @@ acpi_ns_init_one_device (
/*
* The device is present. Run _INI.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI"));
- status = acpi_ns_evaluate_relative ("_INI", &pinfo);
+ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
+ pinfo.node, METHOD_NAME__INI));
+ status = acpi_ns_evaluate_relative (METHOD_NAME__INI, &pinfo);
if (ACPI_FAILURE (status)) {
/* No _INI (AE_NOT_FOUND) means device requires no initialization */
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index 1d7aedf68a7..34e49701660 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -50,9 +50,24 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsload")
+/* Local prototypes */
-#ifndef ACPI_NO_METHOD_EXECUTION
+static acpi_status
+acpi_ns_load_table_by_type (
+ acpi_table_type table_type);
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+acpi_status
+acpi_ns_unload_namespace (
+ acpi_handle handle);
+
+static acpi_status
+acpi_ns_delete_subtree (
+ acpi_handle start_handle);
+#endif
+
+#ifndef ACPI_NO_METHOD_EXECUTION
/*******************************************************************************
*
* FUNCTION: acpi_ns_load_table
@@ -159,7 +174,7 @@ acpi_ns_load_table (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_load_table_by_type (
acpi_table_type table_type)
{
@@ -321,8 +336,7 @@ acpi_ns_load_namespace (
}
-#ifdef ACPI_FUTURE_USAGE
-
+#ifdef ACPI_FUTURE_IMPLEMENTATION
/*******************************************************************************
*
* FUNCTION: acpi_ns_delete_subtree
@@ -339,7 +353,7 @@ acpi_ns_load_namespace (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ns_delete_subtree (
acpi_handle start_handle)
{
@@ -453,8 +467,6 @@ acpi_ns_unload_namespace (
return_ACPI_STATUS (status);
}
-
-#endif /* ACPI_FUTURE_USAGE */
-
+#endif
#endif
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index b6f8f910eff..d8ce7e39795 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -50,6 +50,14 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsnames")
+/* Local prototypes */
+
+static void
+acpi_ns_build_external_path (
+ struct acpi_namespace_node *node,
+ acpi_size size,
+ char *name_buffer);
+
/*******************************************************************************
*
@@ -66,7 +74,7 @@
*
******************************************************************************/
-void
+static void
acpi_ns_build_external_path (
struct acpi_namespace_node *node,
acpi_size size,
@@ -126,7 +134,7 @@ acpi_ns_build_external_path (
*
* FUNCTION: acpi_ns_get_external_pathname
*
- * PARAMETERS: Node - NS node whose pathname is needed
+ * PARAMETERS: Node - Namespace node whose pathname is needed
*
* RETURN: Pointer to storage containing the fully qualified name of
* the node, In external format (name segments separated by path
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index 4e41e66db61..27258c1ca4f 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -60,6 +60,8 @@
* Type - Type of object, or ACPI_TYPE_ANY if not
* known
*
+ * RETURN: Status
+ *
* DESCRIPTION: Record the given object as the value associated with the
* name whose acpi_handle is passed. If Object is NULL
* and Type is ACPI_TYPE_ANY, set the name as having no value.
@@ -97,7 +99,8 @@ acpi_ns_attach_object (
if (!object && (ACPI_TYPE_ANY != type)) {
/* Null object */
- ACPI_REPORT_ERROR (("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
+ ACPI_REPORT_ERROR ((
+ "ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -112,7 +115,8 @@ acpi_ns_attach_object (
/* Check if this object is already attached */
if (node->object == object) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in name_obj %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Obj %p already installed in name_obj %p\n",
object, node));
return_ACPI_STATUS (AE_OK);
@@ -192,7 +196,7 @@ acpi_ns_attach_object (
*
* FUNCTION: acpi_ns_detach_object
*
- * PARAMETERS: Node - An node whose object will be detached
+ * PARAMETERS: Node - A Namespace node whose object will be detached
*
* RETURN: None.
*
@@ -248,7 +252,7 @@ acpi_ns_detach_object (
*
* FUNCTION: acpi_ns_get_attached_object
*
- * PARAMETERS: Node - Parent Node to be examined
+ * PARAMETERS: Node - Namespace node
*
* RETURN: Current value of the object field from the Node whose
* handle is passed
@@ -284,7 +288,7 @@ acpi_ns_get_attached_object (
*
* FUNCTION: acpi_ns_get_secondary_object
*
- * PARAMETERS: Node - Parent Node to be examined
+ * PARAMETERS: Node - Namespace node
*
* RETURN: Current value of the object field from the Node whose
* handle is passed.
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 0e6dea23603..af8aaa9cc4f 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -49,15 +49,24 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nssearch")
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_search_parent_tree (
+ u32 target_name,
+ struct acpi_namespace_node *node,
+ acpi_object_type type,
+ struct acpi_namespace_node **return_node);
+
/*******************************************************************************
*
* FUNCTION: acpi_ns_search_node
*
- * PARAMETERS: *target_name - Ascii ACPI name to search for
- * *Node - Starting node where search will begin
- * Type - Object type to match
- * **return_node - Where the matched Named obj is returned
+ * PARAMETERS: target_name - Ascii ACPI name to search for
+ * Node - Starting node where search will begin
+ * Type - Object type to match
+ * return_node - Where the matched Named obj is returned
*
* RETURN: Status
*
@@ -163,10 +172,10 @@ acpi_ns_search_node (
*
* FUNCTION: acpi_ns_search_parent_tree
*
- * PARAMETERS: *target_name - Ascii ACPI name to search for
- * *Node - Starting node where search will begin
- * Type - Object type to match
- * **return_node - Where the matched Node is returned
+ * PARAMETERS: target_name - Ascii ACPI name to search for
+ * Node - Starting node where search will begin
+ * Type - Object type to match
+ * return_node - Where the matched Node is returned
*
* RETURN: Status
*
@@ -257,12 +266,12 @@ acpi_ns_search_parent_tree (
*
* PARAMETERS: target_name - Ascii ACPI name to search for (4 chars)
* walk_state - Current state of the walk
- * *Node - Starting node where search will begin
+ * Node - Starting node where search will begin
* interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x.
* Otherwise,search only.
* Type - Object type to match
* Flags - Flags describing the search restrictions
- * **return_node - Where the Node is returned
+ * return_node - Where the Node is returned
*
* RETURN: Status
*
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index 75da76cc0b1..c53b82e94ce 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -51,6 +51,18 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsutils")
+/* Local prototypes */
+
+static u8
+acpi_ns_valid_path_separator (
+ char sep);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_name
+acpi_ns_find_parent_name (
+ struct acpi_namespace_node *node_to_search);
+#endif
+
/*******************************************************************************
*
@@ -59,7 +71,8 @@
* PARAMETERS: module_name - Caller's module name (for error output)
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
- * Message - Error message to use on failure
+ * internal_name - Name or path of the namespace node
+ * lookup_status - Exception code from NS lookup
*
* RETURN: None
*
@@ -121,6 +134,9 @@ acpi_ns_report_error (
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
* Message - Error message to use on failure
+ * prefix_node - Prefix relative to the path
+ * Path - Path to the node
+ * method_status - Execution status
*
* RETURN: None
*
@@ -161,8 +177,8 @@ acpi_ns_report_method_error (
*
* FUNCTION: acpi_ns_print_node_pathname
*
- * PARAMETERS: Node - Object
- * Msg - Prefix message
+ * PARAMETERS: Node - Object
+ * Message - Prefix message
*
* DESCRIPTION: Print an object's full namespace pathname
* Manages allocation/freeing of a pathname buffer
@@ -172,7 +188,7 @@ acpi_ns_report_method_error (
void
acpi_ns_print_node_pathname (
struct acpi_namespace_node *node,
- char *msg)
+ char *message)
{
struct acpi_buffer buffer;
acpi_status status;
@@ -189,8 +205,8 @@ acpi_ns_print_node_pathname (
status = acpi_ns_handle_to_pathname (node, &buffer);
if (ACPI_SUCCESS (status)) {
- if (msg) {
- acpi_os_printf ("%s ", msg);
+ if (message) {
+ acpi_os_printf ("%s ", message);
}
acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
@@ -224,7 +240,7 @@ acpi_ns_valid_root_prefix (
*
* FUNCTION: acpi_ns_valid_path_separator
*
- * PARAMETERS: Sep - Character to be checked
+ * PARAMETERS: Sep - Character to be checked
*
* RETURN: TRUE if a valid path separator
*
@@ -232,7 +248,7 @@ acpi_ns_valid_root_prefix (
*
******************************************************************************/
-u8
+static u8
acpi_ns_valid_path_separator (
char sep)
{
@@ -245,10 +261,12 @@ acpi_ns_valid_path_separator (
*
* FUNCTION: acpi_ns_get_type
*
- * PARAMETERS: Handle - Parent Node to be examined
+ * PARAMETERS: Node - Parent Node to be examined
*
* RETURN: Type field from Node whose handle is passed
*
+ * DESCRIPTION: Return the type of a Namespace node
+ *
******************************************************************************/
acpi_object_type
@@ -271,11 +289,13 @@ acpi_ns_get_type (
*
* FUNCTION: acpi_ns_local
*
- * PARAMETERS: Type - A namespace object type
+ * PARAMETERS: Type - A namespace object type
*
* RETURN: LOCAL if names must be found locally in objects of the
* passed type, 0 if enclosing scopes should be searched
*
+ * DESCRIPTION: Returns scope rule for the given object type.
+ *
******************************************************************************/
u32
@@ -303,7 +323,7 @@ acpi_ns_local (
* PARAMETERS: Info - Info struct initialized with the
* external name pointer.
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Calculate the length of the internal (AML) namestring
* corresponding to the external (ASL) namestring.
@@ -551,14 +571,16 @@ acpi_ns_internalize_name (
*
* FUNCTION: acpi_ns_externalize_name
*
- * PARAMETERS: *internal_name - Internal representation of name
- * **converted_name - Where to return the resulting
- * external representation of name
+ * PARAMETERS: internal_name_length - Lenth of the internal name below
+ * internal_name - Internal representation of name
+ * converted_name_length - Where the length is returned
+ * converted_name - Where the resulting external name
+ * is returned
*
* RETURN: Status
*
* DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
- * to its external form (e.g. "\_PR_.CPU0")
+ * to its external (printable) form (e.g. "\_PR_.CPU0")
*
******************************************************************************/
@@ -717,8 +739,9 @@ acpi_ns_externalize_name (
*
* DESCRIPTION: Convert a namespace handle to a real Node
*
- * Note: Real integer handles allow for more verification
- * and keep all pointers within this subsystem.
+ * Note: Real integer handles would allow for more verification
+ * and keep all pointers within this subsystem - however this introduces
+ * more (and perhaps unnecessary) overhead.
*
******************************************************************************/
@@ -775,7 +798,7 @@ acpi_ns_convert_entry_to_handle (
return ((acpi_handle) node);
-/* ---------------------------------------------------
+/* Example future implementation ---------------------
if (!Node)
{
@@ -801,12 +824,13 @@ acpi_ns_convert_entry_to_handle (
*
* RETURN: none
*
- * DESCRIPTION: free memory allocated for table storage.
+ * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
*
******************************************************************************/
void
-acpi_ns_terminate (void)
+acpi_ns_terminate (
+ void)
{
union acpi_operand_object *obj_desc;
@@ -940,7 +964,6 @@ acpi_ns_get_node_by_path (
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
cleanup:
- /* Cleanup */
if (internal_path) {
ACPI_MEM_FREE (internal_path);
}
@@ -950,55 +973,6 @@ cleanup:
/*******************************************************************************
*
- * FUNCTION: acpi_ns_find_parent_name
- *
- * PARAMETERS: *child_node - Named Obj whose name is to be found
- *
- * RETURN: The ACPI name
- *
- * DESCRIPTION: Search for the given obj in its parent scope and return the
- * name segment, or "????" if the parent name can't be found
- * (which "should not happen").
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_name
-acpi_ns_find_parent_name (
- struct acpi_namespace_node *child_node)
-{
- struct acpi_namespace_node *parent_node;
-
-
- ACPI_FUNCTION_TRACE ("ns_find_parent_name");
-
-
- if (child_node) {
- /* Valid entry. Get the parent Node */
-
- parent_node = acpi_ns_get_parent_node (child_node);
- if (parent_node) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Parent of %p [%4.4s] is %p [%4.4s]\n",
- child_node, acpi_ut_get_node_name (child_node),
- parent_node, acpi_ut_get_node_name (parent_node)));
-
- if (parent_node->name.integer) {
- return_VALUE ((acpi_name) parent_node->name.integer);
- }
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Unable to find parent of %p (%4.4s)\n",
- child_node, acpi_ut_get_node_name (child_node)));
- }
-
- return_VALUE (ACPI_UNKNOWN_NAME);
-}
-#endif
-
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ns_get_parent_node
*
* PARAMETERS: Node - Current table entry
@@ -1009,7 +983,6 @@ acpi_ns_find_parent_name (
*
******************************************************************************/
-
struct acpi_namespace_node *
acpi_ns_get_parent_node (
struct acpi_namespace_node *node)
@@ -1030,7 +1003,6 @@ acpi_ns_get_parent_node (
node = node->peer;
}
-
return (node->peer);
}
@@ -1049,7 +1021,6 @@ acpi_ns_get_parent_node (
*
******************************************************************************/
-
struct acpi_namespace_node *
acpi_ns_get_next_valid_node (
struct acpi_namespace_node *node)
@@ -1067,3 +1038,53 @@ acpi_ns_get_next_valid_node (
}
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ns_find_parent_name
+ *
+ * PARAMETERS: *child_node - Named Obj whose name is to be found
+ *
+ * RETURN: The ACPI name
+ *
+ * DESCRIPTION: Search for the given obj in its parent scope and return the
+ * name segment, or "????" if the parent name can't be found
+ * (which "should not happen").
+ *
+ ******************************************************************************/
+
+acpi_name
+acpi_ns_find_parent_name (
+ struct acpi_namespace_node *child_node)
+{
+ struct acpi_namespace_node *parent_node;
+
+
+ ACPI_FUNCTION_TRACE ("ns_find_parent_name");
+
+
+ if (child_node) {
+ /* Valid entry. Get the parent Node */
+
+ parent_node = acpi_ns_get_parent_node (child_node);
+ if (parent_node) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Parent of %p [%4.4s] is %p [%4.4s]\n",
+ child_node, acpi_ut_get_node_name (child_node),
+ parent_node, acpi_ut_get_node_name (parent_node)));
+
+ if (parent_node->name.integer) {
+ return_VALUE ((acpi_name) parent_node->name.integer);
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Unable to find parent of %p (%4.4s)\n",
+ child_node, acpi_ut_get_node_name (child_node)));
+ }
+
+ return_VALUE (ACPI_UNKNOWN_NAME);
+}
+#endif
+
+
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index 4de2444df30..f9a7277dca6 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -56,7 +56,7 @@
*
* PARAMETERS: Type - Type of node to be searched for
* parent_node - Parent node whose children we are
- * getting
+ * getting
* child_node - Previous child that was found.
* The NEXT child will be returned
*
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 1dc995586cb..12ea202257f 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -58,11 +58,11 @@
* FUNCTION: acpi_evaluate_object_typed
*
* PARAMETERS: Handle - Object handle (optional)
- * *Pathname - Object pathname (optional)
- * **external_params - List of parameters to pass to method,
+ * Pathname - Object pathname (optional)
+ * external_params - List of parameters to pass to method,
* terminated by NULL. May be NULL
* if no parameters are being passed.
- * *return_buffer - Where to put method's return value (if
+ * return_buffer - Where to put method's return value (if
* any). If NULL, no value is returned.
* return_type - Expected type of return object
*
@@ -73,6 +73,7 @@
* be valid (non-null)
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_evaluate_object_typed (
@@ -307,7 +308,8 @@ acpi_evaluate_object (
if (ACPI_SUCCESS (status)) {
/* Validate/Allocate/Clear caller buffer */
- status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
+ status = acpi_ut_initialize_buffer (return_buffer,
+ buffer_space_needed);
if (ACPI_FAILURE (status)) {
/*
* Caller's buffer is too small or a new one can't be allocated
@@ -423,7 +425,8 @@ acpi_walk_namespace (
return_ACPI_STATUS (status);
}
- status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK,
+ status = acpi_ns_walk_namespace (type, start_object, max_depth,
+ ACPI_NS_WALK_UNLOCK,
user_function, context, return_value);
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
@@ -525,7 +528,8 @@ acpi_ns_get_device_callback (
}
}
- status = info->user_function (obj_handle, nesting_level, info->context, return_value);
+ status = info->user_function (obj_handle, nesting_level, info->context,
+ return_value);
return (status);
}
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index f2405efd1b9..8d097914c49 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -57,9 +57,9 @@
* FUNCTION: acpi_get_handle
*
* PARAMETERS: Parent - Object to search under (search scope).
- * path_name - Pointer to an asciiz string containing the
- * name
- * ret_handle - Where the return handle is placed
+ * Pathname - Pointer to an asciiz string containing the
+ * name
+ * ret_handle - Where the return handle is returned
*
* RETURN: Status
*
@@ -220,7 +220,7 @@ EXPORT_SYMBOL(acpi_get_name);
* FUNCTION: acpi_get_object_info
*
* PARAMETERS: Handle - Object Handle
- * Info - Where the info is returned
+ * Buffer - Where the info is returned
*
* RETURN: Status
*
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index 19acf32674b..363e1f6cfb1 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -56,7 +56,7 @@
* FUNCTION: acpi_get_type
*
* PARAMETERS: Handle - Handle of object whose type is desired
- * *ret_type - Where the type will be placed
+ * ret_type - Where the type will be placed
*
* RETURN: Status
*
@@ -258,5 +258,5 @@ unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
return (status);
}
-EXPORT_SYMBOL(acpi_get_next_object);
+EXPORT_SYMBOL(acpi_get_next_object);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 5a9128de622..bdd9f37f810 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -71,6 +71,9 @@ EXPORT_SYMBOL(acpi_in_debugger);
extern char line_buf[80];
#endif /*ENABLE_DEBUGGER*/
+int acpi_specific_hotkey_enabled;
+EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
+
static unsigned int acpi_irq_irq;
static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
@@ -1152,6 +1155,15 @@ acpi_wake_gpes_always_on_setup(char *str)
__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
+int __init
+acpi_hotkey_setup(char *str)
+{
+ acpi_specific_hotkey_enabled = TRUE;
+ return 1;
+}
+
+__setup("acpi_specific_hotkey", acpi_hotkey_setup);
+
/*
* max_cstate is defined in the base kernel so modules can
* change it w/o depending on the state of the processor module.
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index b5d98895f6a..b7ac68cc9e1 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -50,6 +50,16 @@
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("psargs")
+/* Local prototypes */
+
+static u32
+acpi_ps_get_next_package_length (
+ struct acpi_parse_state *parser_state);
+
+static union acpi_parse_object *
+acpi_ps_get_next_field (
+ struct acpi_parse_state *parser_state);
+
/*******************************************************************************
*
@@ -64,7 +74,7 @@
*
******************************************************************************/
-u32
+static u32
acpi_ps_get_next_package_length (
struct acpi_parse_state *parser_state)
{
@@ -78,7 +88,6 @@ acpi_ps_get_next_package_length (
encoded_length = (u32) ACPI_GET8 (parser_state->aml);
parser_state->aml++;
-
switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
case 0: /* 1-byte encoding (bits 0-5) */
@@ -287,13 +296,14 @@ acpi_ps_get_next_namepath (
* parent tree, but don't open a new scope -- we just want to lookup the
* object (MUST BE mode EXECUTE to perform upsearch)
*/
- status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
+ status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ NULL, &node);
if (ACPI_SUCCESS (status) && method_call) {
if (node->type == ACPI_TYPE_METHOD) {
- /*
- * This name is actually a control method invocation
- */
+ /* This name is actually a control method invocation */
+
method_desc = acpi_ns_get_attached_object (node);
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
"Control Method - %p Desc %p Path=%p\n",
@@ -360,7 +370,7 @@ acpi_ps_get_next_namepath (
/*
* We got a NOT_FOUND during table load or we encountered
* a cond_ref_of(x) where the target does not exist.
- * -- either case is ok
+ * Either case is ok
*/
status = AE_OK;
}
@@ -486,12 +496,13 @@ acpi_ps_get_next_simple_arg (
*
******************************************************************************/
-union acpi_parse_object *
+static union acpi_parse_object *
acpi_ps_get_next_field (
struct acpi_parse_state *parser_state)
{
- u32 aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
- parser_state->aml_start);
+ u32 aml_offset = (u32)
+ ACPI_PTR_DIFF (parser_state->aml,
+ parser_state->aml_start);
union acpi_parse_object *field;
u16 opcode;
u32 name;
@@ -500,7 +511,7 @@ acpi_ps_get_next_field (
ACPI_FUNCTION_TRACE ("ps_get_next_field");
- /* determine field type */
+ /* Determine field type */
switch (ACPI_GET8 (parser_state->aml)) {
default:
@@ -521,7 +532,6 @@ acpi_ps_get_next_field (
break;
}
-
/* Allocate a new field op */
field = acpi_ps_alloc_op (opcode);
@@ -582,10 +592,10 @@ acpi_ps_get_next_field (
*
* FUNCTION: acpi_ps_get_next_arg
*
- * PARAMETERS: parser_state - Current parser state object
+ * PARAMETERS: walk_state - Current state
+ * parser_state - Current parser state object
* arg_type - The argument type (AML_*_ARG)
- * arg_count - If the argument points to a control method
- * the method's argument is returned here.
+ * return_arg - Where the next arg is returned
*
* RETURN: Status, and an op object containing the next argument.
*
@@ -619,7 +629,7 @@ acpi_ps_get_next_arg (
case ARGP_NAME:
case ARGP_NAMESTRING:
- /* constants, strings, and namestrings are all the same size */
+ /* Constants, strings, and namestrings are all the same size */
arg = acpi_ps_alloc_op (AML_BYTE_OP);
if (!arg) {
@@ -654,7 +664,6 @@ acpi_ps_get_next_arg (
else {
arg = field;
}
-
prev = field;
}
@@ -677,8 +686,8 @@ acpi_ps_get_next_arg (
/* Fill in bytelist data */
- arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end,
- parser_state->aml);
+ arg->common.value.size = (u32)
+ ACPI_PTR_DIFF (parser_state->pkg_end, parser_state->aml);
arg->named.data = parser_state->aml;
/* Skip to End of byte data */
@@ -706,7 +715,7 @@ acpi_ps_get_next_arg (
status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0);
}
else {
- /* single complex argument, nothing returned */
+ /* Single complex argument, nothing returned */
walk_state->arg_count = 1;
}
@@ -716,7 +725,7 @@ acpi_ps_get_next_arg (
case ARGP_DATAOBJ:
case ARGP_TERMARG:
- /* single complex argument, nothing returned */
+ /* Single complex argument, nothing returned */
walk_state->arg_count = 1;
break;
@@ -727,7 +736,7 @@ acpi_ps_get_next_arg (
case ARGP_OBJLIST:
if (parser_state->aml < parser_state->pkg_end) {
- /* non-empty list of variable arguments, nothing returned */
+ /* Non-empty list of variable arguments, nothing returned */
walk_state->arg_count = ACPI_VAR_ARGS;
}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 03e33fedc11..5744673568c 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -44,6 +44,7 @@
#include <acpi/acpi.h>
#include <acpi/acparser.h>
+#include <acpi/acopcode.h>
#include <acpi/amlcode.h>
@@ -51,23 +52,6 @@
ACPI_MODULE_NAME ("psopcode")
-#define _UNK 0x6B
-/*
- * Reserved ASCII characters. Do not use any of these for
- * internal opcodes, since they are used to differentiate
- * name strings from AML opcodes
- */
-#define _ASC 0x6C
-#define _NAM 0x6C
-#define _PFX 0x6D
-#define _UNKNOWN_OPCODE 0x02 /* An example unknown opcode */
-
-#define MAX_EXTENDED_OPCODE 0x88
-#define NUM_EXTENDED_OPCODE (MAX_EXTENDED_OPCODE + 1)
-#define MAX_INTERNAL_OPCODE
-#define NUM_INTERNAL_OPCODE (MAX_INTERNAL_OPCODE + 1)
-
-
/*******************************************************************************
*
* NAME: acpi_gbl_aml_op_info
@@ -79,274 +63,9 @@
*
******************************************************************************/
-
-/*
- * All AML opcodes and the parse-time arguments for each. Used by the AML parser Each list is compressed
- * into a 32-bit number and stored in the master opcode table at the end of this file.
- */
-
-
-#define ARGP_ACCESSFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_ACQUIRE_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_WORDDATA)
-#define ARGP_ADD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_ALIAS_OP ARGP_LIST2 (ARGP_NAMESTRING, ARGP_NAME)
-#define ARGP_ARG0 ARG_NONE
-#define ARGP_ARG1 ARG_NONE
-#define ARGP_ARG2 ARG_NONE
-#define ARGP_ARG3 ARG_NONE
-#define ARGP_ARG4 ARG_NONE
-#define ARGP_ARG5 ARG_NONE
-#define ARGP_ARG6 ARG_NONE
-#define ARGP_BANK_FIELD_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_TERMARG, ARGP_BYTEDATA, ARGP_FIELDLIST)
-#define ARGP_BIT_AND_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BIT_NAND_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BIT_NOR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BIT_NOT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BIT_OR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BIT_XOR_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_BREAK_OP ARG_NONE
-#define ARGP_BREAK_POINT_OP ARG_NONE
-#define ARGP_BUFFER_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_BYTELIST)
-#define ARGP_BYTE_OP ARGP_LIST1 (ARGP_BYTEDATA)
-#define ARGP_BYTELIST_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME)
-#define ARGP_CONTINUE_OP ARG_NONE
-#define ARGP_COPY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SIMPLENAME)
-#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_CREATE_BYTE_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_CREATE_DWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_CREATE_FIELD_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_CREATE_QWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_CREATE_WORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
-#define ARGP_DATA_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_DEBUG_OP ARG_NONE
-#define ARGP_DECREMENT_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_DEREF_OF_OP ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_DEVICE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST)
-#define ARGP_DIVIDE_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET, ARGP_TARGET)
-#define ARGP_DWORD_OP ARGP_LIST1 (ARGP_DWORDDATA)
-#define ARGP_ELSE_OP ARGP_LIST2 (ARGP_PKGLENGTH, ARGP_TERMLIST)
-#define ARGP_EVENT_OP ARGP_LIST1 (ARGP_NAME)
-#define ARGP_FATAL_OP ARGP_LIST3 (ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_TERMARG)
-#define ARGP_FIELD_OP ARGP_LIST4 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_BYTEDATA, ARGP_FIELDLIST)
-#define ARGP_FIND_SET_LEFT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_FIND_SET_RIGHT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_FROM_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_IF_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
-#define ARGP_INCREMENT_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_INDEX_FIELD_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_BYTEDATA, ARGP_FIELDLIST)
-#define ARGP_INDEX_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_LAND_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LGREATER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LGREATEREQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LLESS_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LLESSEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LNOT_OP ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_LNOTEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LOAD_OP ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME)
-#define ARGP_LOAD_TABLE_OP ARGP_LIST6 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_LOCAL0 ARG_NONE
-#define ARGP_LOCAL1 ARG_NONE
-#define ARGP_LOCAL2 ARG_NONE
-#define ARGP_LOCAL3 ARG_NONE
-#define ARGP_LOCAL4 ARG_NONE
-#define ARGP_LOCAL5 ARG_NONE
-#define ARGP_LOCAL6 ARG_NONE
-#define ARGP_LOCAL7 ARG_NONE
-#define ARGP_LOR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_MATCH_OP ARGP_LIST6 (ARGP_TERMARG, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_METHOD_OP ARGP_LIST4 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMLIST)
-#define ARGP_METHODCALL_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_MID_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_MOD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_MULTIPLY_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_MUTEX_OP ARGP_LIST2 (ARGP_NAME, ARGP_BYTEDATA)
-#define ARGP_NAME_OP ARGP_LIST2 (ARGP_NAME, ARGP_DATAOBJ)
-#define ARGP_NAMEDFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_NAMEPATH_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_NOOP_OP ARG_NONE
-#define ARGP_NOTIFY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
-#define ARGP_ONE_OP ARG_NONE
-#define ARGP_ONES_OP ARG_NONE
-#define ARGP_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST)
-#define ARGP_POWER_RES_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_WORDDATA, ARGP_OBJLIST)
-#define ARGP_PROCESSOR_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_BYTEDATA, ARGP_OBJLIST)
-#define ARGP_QWORD_OP ARGP_LIST1 (ARGP_QWORDDATA)
-#define ARGP_REF_OF_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_TERMARG)
-#define ARGP_RELEASE_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_RESERVEDFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_RESET_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_REVISION_OP ARG_NONE
-#define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST)
-#define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_SIZE_OF_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_SLEEP_OP ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_STALL_OP ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_STATICSTRING_OP ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_STORE_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SUPERNAME)
-#define ARGP_STRING_OP ARGP_LIST1 (ARGP_CHARLIST)
-#define ARGP_SUBTRACT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_THERMAL_ZONE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST)
-#define ARGP_TIMER_OP ARG_NONE
-#define ARGP_TO_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_BUFFER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_DEC_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_HEX_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_INTEGER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_STRING_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TYPE_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_UNLOAD_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_VAR_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_DATAOBJLIST)
-#define ARGP_WAIT_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
-#define ARGP_WHILE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
-#define ARGP_WORD_OP ARGP_LIST1 (ARGP_WORDDATA)
-#define ARGP_ZERO_OP ARG_NONE
-
-
-/*
- * All AML opcodes and the runtime arguments for each. Used by the AML interpreter Each list is compressed
- * into a 32-bit number and stored in the master opcode table at the end of this file.
- *
- * (Used by prep_operands procedure and the ASL Compiler)
- */
-
-
-#define ARGI_ACCESSFIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_ACQUIRE_OP ARGI_LIST2 (ARGI_MUTEX, ARGI_INTEGER)
-#define ARGI_ADD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_ALIAS_OP ARGI_INVALID_OPCODE
-#define ARGI_ARG0 ARG_NONE
-#define ARGI_ARG1 ARG_NONE
-#define ARGI_ARG2 ARG_NONE
-#define ARGI_ARG3 ARG_NONE
-#define ARGI_ARG4 ARG_NONE
-#define ARGI_ARG5 ARG_NONE
-#define ARGI_ARG6 ARG_NONE
-#define ARGI_BANK_FIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BIT_NOT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BIT_OR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BIT_XOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_BREAK_OP ARG_NONE
-#define ARGI_BREAK_POINT_OP ARG_NONE
-#define ARGI_BUFFER_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_BYTE_OP ARGI_INVALID_OPCODE
-#define ARGI_BYTELIST_OP ARGI_INVALID_OPCODE
-#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF)
-#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF)
-#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
-#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE
-#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET)
-#define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_CREATE_BYTE_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_CREATE_DWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_CREATE_FIELD_OP ARGI_LIST4 (ARGI_BUFFER, ARGI_INTEGER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_CREATE_QWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_CREATE_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
-#define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING)
-#define ARGI_DEBUG_OP ARG_NONE
-#define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF)
-#define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING)
-#define ARGI_DEVICE_OP ARGI_INVALID_OPCODE
-#define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF)
-#define ARGI_DWORD_OP ARGI_INVALID_OPCODE
-#define ARGI_ELSE_OP ARGI_INVALID_OPCODE
-#define ARGI_EVENT_OP ARGI_INVALID_OPCODE
-#define ARGI_FATAL_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER)
-#define ARGI_FIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_IF_OP ARGI_INVALID_OPCODE
-#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF)
-#define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
-#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LGREATEREQUAL_OP ARGI_INVALID_OPCODE
-#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE
-#define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE
-#define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF)
-#define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_ANYTYPE)
-#define ARGI_LOCAL0 ARG_NONE
-#define ARGI_LOCAL1 ARG_NONE
-#define ARGI_LOCAL2 ARG_NONE
-#define ARGI_LOCAL3 ARG_NONE
-#define ARGI_LOCAL4 ARG_NONE
-#define ARGI_LOCAL5 ARG_NONE
-#define ARGI_LOCAL6 ARG_NONE
-#define ARGI_LOCAL7 ARG_NONE
-#define ARGI_LOR_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
-#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_COMPUTEDATA, ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
-#define ARGI_METHOD_OP ARGI_INVALID_OPCODE
-#define ARGI_METHODCALL_OP ARGI_INVALID_OPCODE
-#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_MOD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_MULTIPLY_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_MUTEX_OP ARGI_INVALID_OPCODE
-#define ARGI_NAME_OP ARGI_INVALID_OPCODE
-#define ARGI_NAMEDFIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_NAMEPATH_OP ARGI_INVALID_OPCODE
-#define ARGI_NOOP_OP ARG_NONE
-#define ARGI_NOTIFY_OP ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER)
-#define ARGI_ONE_OP ARG_NONE
-#define ARGI_ONES_OP ARG_NONE
-#define ARGI_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_POWER_RES_OP ARGI_INVALID_OPCODE
-#define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE
-#define ARGI_QWORD_OP ARGI_INVALID_OPCODE
-#define ARGI_REF_OF_OP ARGI_LIST1 (ARGI_OBJECT_REF)
-#define ARGI_REGION_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
-#define ARGI_RELEASE_OP ARGI_LIST1 (ARGI_MUTEX)
-#define ARGI_RESERVEDFIELD_OP ARGI_INVALID_OPCODE
-#define ARGI_RESET_OP ARGI_LIST1 (ARGI_EVENT)
-#define ARGI_RETURN_OP ARGI_INVALID_OPCODE
-#define ARGI_REVISION_OP ARG_NONE
-#define ARGI_SCOPE_OP ARGI_INVALID_OPCODE
-#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT)
-#define ARGI_SIZE_OF_OP ARGI_LIST1 (ARGI_DATAOBJECT)
-#define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE
-#define ARGI_STORE_OP ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
-#define ARGI_STRING_OP ARGI_INVALID_OPCODE
-#define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
-#define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE
-#define ARGI_TIMER_OP ARG_NONE
-#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
-#define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET)
-#define ARGI_TYPE_OP ARGI_LIST1 (ARGI_ANYTYPE)
-#define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
-#define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER)
-#define ARGI_WHILE_OP ARGI_INVALID_OPCODE
-#define ARGI_WORD_OP ARGI_INVALID_OPCODE
-#define ARGI_ZERO_OP ARG_NONE
-
-
/*
* Summary of opcode types/flags
- */
-
-/******************************************************************************
+ *
Opcodes that have associated namespace objects (AML_NSOBJECT flag)
@@ -460,14 +179,13 @@
AML_CREATE_DWORD_FIELD_OP
AML_CREATE_QWORD_FIELD_OP
-******************************************************************************/
+ ******************************************************************************/
/*
- * Master Opcode information table. A summary of everything we know about each opcode, all in one place.
+ * Master Opcode information table. A summary of everything we know about each
+ * opcode, all in one place.
*/
-
-
const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
{
/*! [Begin] no source code translation */
@@ -693,8 +411,7 @@ static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] =
*
* PARAMETERS: Opcode - The AML opcode
*
- * RETURN: A pointer to the info about the opcode. NULL if the opcode was
- * not found in the table.
+ * RETURN: A pointer to the info about the opcode.
*
* DESCRIPTION: Find AML opcode description based on the opcode.
* NOTE: This procedure must ALWAYS return a valid pointer!
@@ -731,7 +448,8 @@ acpi_ps_get_opcode_info (
default:
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode [%4.4X]\n", opcode));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unknown AML opcode [%4.4X]\n", opcode));
break;
}
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index e79edb53cb3..bbfdc1a58c2 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -64,6 +64,23 @@
static u32 acpi_gbl_depth = 0;
+/* Local prototypes */
+
+static void
+acpi_ps_complete_this_op (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op);
+
+static acpi_status
+acpi_ps_next_parse_state (
+ struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op,
+ acpi_status callback_status);
+
+static acpi_status
+acpi_ps_parse_loop (
+ struct acpi_walk_state *walk_state);
+
/*******************************************************************************
*
@@ -100,7 +117,7 @@ acpi_ps_get_opcode_size (
*
* PARAMETERS: parser_state - A parser state object
*
- * RETURN: Status
+ * RETURN: Next AML opcode
*
* DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
*
@@ -117,7 +134,6 @@ acpi_ps_peek_opcode (
aml = parser_state->aml;
opcode = (u16) ACPI_GET8 (aml);
-
if (opcode == AML_EXTOP) {
/* Extended opcode */
@@ -142,7 +158,7 @@ acpi_ps_peek_opcode (
*
******************************************************************************/
-void
+static void
acpi_ps_complete_this_op (
struct acpi_walk_state *walk_state,
union acpi_parse_object *op)
@@ -272,7 +288,6 @@ acpi_ps_complete_this_op (
next = NULL;
}
}
-
prev = next;
}
}
@@ -280,7 +295,7 @@ acpi_ps_complete_this_op (
cleanup:
- /* Now we can actually delete the subtree rooted at op */
+ /* Now we can actually delete the subtree rooted at Op */
acpi_ps_delete_parse_tree (op);
return_VOID;
@@ -291,7 +306,9 @@ cleanup:
*
* FUNCTION: acpi_ps_next_parse_state
*
- * PARAMETERS: parser_state - Current parser state object
+ * PARAMETERS: walk_state - Current state
+ * Op - Current parse op
+ * callback_status - Status from previous operation
*
* RETURN: Status
*
@@ -300,7 +317,7 @@ cleanup:
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ps_next_parse_state (
struct acpi_walk_state *walk_state,
union acpi_parse_object *op,
@@ -382,9 +399,8 @@ acpi_ps_next_parse_state (
case AE_CTRL_TRANSFER:
- /*
- * A method call (invocation) -- transfer control
- */
+ /* A method call (invocation) -- transfer control */
+
status = AE_CTRL_TRANSFER;
walk_state->prev_op = op;
walk_state->method_call_op = op;
@@ -397,6 +413,7 @@ acpi_ps_next_parse_state (
default:
+
status = callback_status;
if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
status = AE_OK;
@@ -412,7 +429,7 @@ acpi_ps_next_parse_state (
*
* FUNCTION: acpi_ps_parse_loop
*
- * PARAMETERS: parser_state - Current parser state object
+ * PARAMETERS: walk_state - Current state
*
* RETURN: Status
*
@@ -421,7 +438,7 @@ acpi_ps_next_parse_state (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ps_parse_loop (
struct acpi_walk_state *walk_state)
{
@@ -443,6 +460,7 @@ acpi_ps_parse_loop (
walk_state->arg_types = 0;
#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
/* We are restarting a preempted control method */
@@ -471,7 +489,8 @@ acpi_ps_parse_loop (
acpi_format_exception (status)));
}
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "get_predicate Failed, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "get_predicate Failed, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
@@ -492,16 +511,15 @@ acpi_ps_parse_loop (
}
#endif
- /*
- * Iterative parsing loop, while there is more aml to process:
- */
+ /* Iterative parsing loop, while there is more AML to process: */
+
while ((parser_state->aml < parser_state->aml_end) || (op)) {
aml_op_start = parser_state->aml;
if (!op) {
/* Get the next opcode from the AML stream */
walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
- parser_state->aml_start);
+ parser_state->aml_start);
walk_state->opcode = acpi_ps_peek_opcode (parser_state);
/*
@@ -578,8 +596,10 @@ acpi_ps_parse_loop (
INCREMENT_ARG_LIST (walk_state->arg_types);
}
- /* Make sure that we found a NAME and didn't run out of arguments */
-
+ /*
+ * Make sure that we found a NAME and didn't run out of
+ * arguments
+ */
if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
status = AE_AML_NO_OPERAND;
goto close_this_op;
@@ -597,12 +617,13 @@ acpi_ps_parse_loop (
status = walk_state->descending_callback (walk_state, &op);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",
- acpi_format_exception (status)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "During name lookup/catalog, %s\n",
+ acpi_format_exception (status)));
goto close_this_op;
}
- if (op == NULL) {
+ if (!op) {
continue;
}
@@ -659,7 +680,7 @@ acpi_ps_parse_loop (
if ((walk_state->descending_callback != NULL)) {
/*
- * Find the object. This will either insert the object into
+ * Find the object. This will either insert the object into
* the namespace or simply look it up
*/
walk_state->op = op;
@@ -688,11 +709,15 @@ acpi_ps_parse_loop (
}
- /* Start arg_count at zero because we don't know if there are any args yet */
-
+ /*
+ * Start arg_count at zero because we don't know if there are
+ * any args yet
+ */
walk_state->arg_count = 0;
- if (walk_state->arg_types) /* Are there any arguments that must be processed? */ {
+ /* Are there any arguments that must be processed? */
+
+ if (walk_state->arg_types) {
/* Get arguments */
switch (op->common.aml_opcode) {
@@ -720,14 +745,18 @@ acpi_ps_parse_loop (
default:
- /* Op is not a constant or string, append each argument to the Op */
-
+ /*
+ * Op is not a constant or string, append each argument
+ * to the Op
+ */
while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
!walk_state->arg_count) {
- walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
- parser_state->aml_start);
+ walk_state->aml_offset = (u32)
+ ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
+
status = acpi_ps_get_next_arg (walk_state, parser_state,
- GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
+ GET_CURRENT_ARG_TYPE (walk_state->arg_types),
+ &arg);
if (ACPI_FAILURE (status)) {
goto close_this_op;
}
@@ -752,7 +781,8 @@ acpi_ps_parse_loop (
* Save the length and address of the body
*/
op->named.data = parser_state->aml;
- op->named.length = (u32) (parser_state->pkg_end - parser_state->aml);
+ op->named.length = (u32) (parser_state->pkg_end -
+ parser_state->aml);
/* Skip body of method */
@@ -773,7 +803,8 @@ acpi_ps_parse_loop (
* to parse them correctly.
*/
op->named.data = aml_op_start;
- op->named.length = (u32) (parser_state->pkg_end - aml_op_start);
+ op->named.length = (u32) (parser_state->pkg_end -
+ aml_op_start);
/* Skip body */
@@ -785,7 +816,8 @@ acpi_ps_parse_loop (
case AML_WHILE_OP:
if (walk_state->control_state) {
- walk_state->control_state->control.package_end = parser_state->pkg_end;
+ walk_state->control_state->control.package_end =
+ parser_state->pkg_end;
}
break;
@@ -801,8 +833,10 @@ acpi_ps_parse_loop (
/* Check for arguments that need to be processed */
if (walk_state->arg_count) {
- /* There are arguments (complex ones), push Op and prepare for argument */
-
+ /*
+ * There are arguments (complex ones), push Op and
+ * prepare for argument
+ */
status = acpi_ps_push_scope (parser_state, op,
walk_state->arg_types, walk_state->arg_count);
if (ACPI_FAILURE (status)) {
@@ -812,8 +846,10 @@ acpi_ps_parse_loop (
continue;
}
- /* All arguments have been processed -- Op is complete, prepare for next */
-
+ /*
+ * All arguments have been processed -- Op is complete,
+ * prepare for next
+ */
walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
if (walk_state->op_info->flags & AML_NAMED) {
if (acpi_gbl_depth) {
@@ -880,9 +916,8 @@ close_this_op:
case AE_CTRL_TRANSFER:
- /*
- * We are about to transfer to a called method.
- */
+ /* We are about to transfer to a called method. */
+
walk_state->prev_op = op;
walk_state->prev_arg_types = walk_state->arg_types;
return_ACPI_STATUS (status);
@@ -1051,10 +1086,7 @@ close_this_op:
*
* FUNCTION: acpi_ps_parse_aml
*
- * PARAMETERS: start_scope - The starting point of the parse. Becomes the
- * root of the parsed op tree.
- * Aml - Pointer to the raw AML code to parse
- * aml_size - Length of the AML to parse
+ * PARAMETERS: walk_state - Current state
*
*
* RETURN: Status
@@ -1076,8 +1108,10 @@ acpi_ps_parse_aml (
ACPI_FUNCTION_TRACE ("ps_parse_aml");
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n",
- walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Entered with walk_state=%p Aml=%p size=%X\n",
+ walk_state, walk_state->parser_state.aml,
+ walk_state->parser_state.aml_size));
/* Create and initialize a new thread state */
@@ -1142,9 +1176,10 @@ acpi_ps_parse_aml (
if ((status == AE_ALREADY_EXISTS) &&
(!walk_state->method_desc->method.semaphore)) {
/*
- * This method is marked not_serialized, but it tried to create a named
- * object, causing the second thread entrance to fail. We will workaround
- * this by marking the method permanently as Serialized.
+ * This method is marked not_serialized, but it tried to create
+ * a named object, causing the second thread entrance to fail.
+ * We will workaround this by marking the method permanently
+ * as Serialized.
*/
walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
walk_state->method_desc->method.concurrency = 1;
@@ -1187,7 +1222,8 @@ acpi_ps_parse_aml (
previous_walk_state = walk_state;
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "return_value=%p, implicit_value=%p State=%p\n",
walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
/* Check if we have restarted a preempted walk */
@@ -1231,12 +1267,14 @@ acpi_ps_parse_aml (
*/
else if (previous_walk_state->caller_return_desc) {
if (previous_walk_state->implicit_return_obj) {
- *(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj;
+ *(previous_walk_state->caller_return_desc) =
+ previous_walk_state->implicit_return_obj;
}
else {
/* NULL if no return value */
- *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc;
+ *(previous_walk_state->caller_return_desc) =
+ previous_walk_state->return_desc;
}
}
else {
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index dcbed49608b..8dcd1b1e713 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -65,6 +65,7 @@ union acpi_parse_object *
acpi_ps_get_parent_scope (
struct acpi_parse_state *parser_state)
{
+
return (parser_state->scope->parse_scope.op);
}
@@ -87,8 +88,10 @@ u8
acpi_ps_has_completed_scope (
struct acpi_parse_state *parser_state)
{
- return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
- !parser_state->scope->parse_scope.arg_count)));
+
+ return ((u8)
+ ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
+ !parser_state->scope->parse_scope.arg_count)));
}
@@ -167,23 +170,23 @@ acpi_ps_push_scope (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
- scope->parse_scope.op = op;
- scope->parse_scope.arg_list = remaining_args;
- scope->parse_scope.arg_count = arg_count;
- scope->parse_scope.pkg_end = parser_state->pkg_end;
+ scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
+ scope->parse_scope.op = op;
+ scope->parse_scope.arg_list = remaining_args;
+ scope->parse_scope.arg_count = arg_count;
+ scope->parse_scope.pkg_end = parser_state->pkg_end;
/* Push onto scope stack */
acpi_ut_push_generic_state (&parser_state->scope, scope);
if (arg_count == ACPI_VAR_ARGS) {
- /* multiple arguments */
+ /* Multiple arguments */
scope->parse_scope.arg_end = parser_state->pkg_end;
}
else {
- /* single argument */
+ /* Single argument */
scope->parse_scope.arg_end = ACPI_TO_POINTER (ACPI_MAX_PTR);
}
@@ -221,18 +224,17 @@ acpi_ps_pop_scope (
ACPI_FUNCTION_TRACE ("ps_pop_scope");
- /*
- * Only pop the scope if there is in fact a next scope
- */
+ /* Only pop the scope if there is in fact a next scope */
+
if (scope->common.next) {
scope = acpi_ut_pop_generic_state (&parser_state->scope);
/* return to parsing previous op */
- *op = scope->parse_scope.op;
- *arg_list = scope->parse_scope.arg_list;
- *arg_count = scope->parse_scope.arg_count;
- parser_state->pkg_end = scope->parse_scope.pkg_end;
+ *op = scope->parse_scope.op;
+ *arg_list = scope->parse_scope.arg_list;
+ *arg_count = scope->parse_scope.arg_count;
+ parser_state->pkg_end = scope->parse_scope.pkg_end;
/* All done with this scope state structure */
@@ -241,12 +243,13 @@ acpi_ps_pop_scope (
else {
/* empty parse stack, prepare to fetch next opcode */
- *op = NULL;
- *arg_list = 0;
- *arg_count = 0;
+ *op = NULL;
+ *arg_list = 0;
+ *arg_count = 0;
}
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Popped Op %p Args %X\n", *op, *arg_count));
return_VOID;
}
@@ -257,7 +260,7 @@ acpi_ps_pop_scope (
*
* PARAMETERS: parser_state - Current parser state object
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Destroy available list, remaining stack levels, and return
* root scope
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index 2140bd1ac10..d5aafe73fca 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -49,6 +49,14 @@
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("pstree")
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+union acpi_parse_object *
+acpi_ps_get_child (
+ union acpi_parse_object *op);
+#endif
+
/*******************************************************************************
*
@@ -57,7 +65,7 @@
* PARAMETERS: Op - Get an argument for this op
* Argn - Nth argument to get
*
- * RETURN: The argument (as an Op object). NULL if argument does not exist
+ * RETURN: The argument (as an Op object). NULL if argument does not exist
*
* DESCRIPTION: Get the specified op's argument.
*
@@ -152,7 +160,6 @@ acpi_ps_append_arg (
return;
}
-
/* Append the argument to the linked argument list */
if (op->common.value.arg) {
@@ -164,14 +171,12 @@ acpi_ps_append_arg (
}
prev_arg->common.next = arg;
}
-
else {
/* No argument list, this will be the first argument */
op->common.value.arg = arg;
}
-
/* Set the parent in this arg and any args linked after it */
while (arg) {
@@ -182,73 +187,6 @@ acpi_ps_append_arg (
#ifdef ACPI_FUTURE_USAGE
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_ps_get_child
- *
- * PARAMETERS: Op - Get the child of this Op
- *
- * RETURN: Child Op, Null if none is found.
- *
- * DESCRIPTION: Get op's children or NULL if none
- *
- ******************************************************************************/
-union acpi_parse_object *
-acpi_ps_get_child (
- union acpi_parse_object *op)
-{
- union acpi_parse_object *child = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- switch (op->common.aml_opcode) {
- case AML_SCOPE_OP:
- case AML_ELSE_OP:
- case AML_DEVICE_OP:
- case AML_THERMAL_ZONE_OP:
- case AML_INT_METHODCALL_OP:
-
- child = acpi_ps_get_arg (op, 0);
- break;
-
-
- case AML_BUFFER_OP:
- case AML_PACKAGE_OP:
- case AML_METHOD_OP:
- case AML_IF_OP:
- case AML_WHILE_OP:
- case AML_FIELD_OP:
-
- child = acpi_ps_get_arg (op, 1);
- break;
-
-
- case AML_POWER_RES_OP:
- case AML_INDEX_FIELD_OP:
-
- child = acpi_ps_get_arg (op, 2);
- break;
-
-
- case AML_PROCESSOR_OP:
- case AML_BANK_FIELD_OP:
-
- child = acpi_ps_get_arg (op, 3);
- break;
-
-
- default:
- /* All others have no children */
- break;
- }
-
- return (child);
-}
-
-
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_depth_next
@@ -280,21 +218,21 @@ acpi_ps_get_depth_next (
return (NULL);
}
- /* look for an argument or child */
+ /* Look for an argument or child */
next = acpi_ps_get_arg (op, 0);
if (next) {
return (next);
}
- /* look for a sibling */
+ /* Look for a sibling */
next = op->common.next;
if (next) {
return (next);
}
- /* look for a sibling of parent */
+ /* Look for a sibling of parent */
parent = op->common.parent;
@@ -305,13 +243,13 @@ acpi_ps_get_depth_next (
}
if (arg == origin) {
- /* reached parent of origin, end search */
+ /* Reached parent of origin, end search */
return (NULL);
}
if (parent->common.next) {
- /* found sibling of parent */
+ /* Found sibling of parent */
return (parent->common.next);
}
@@ -323,5 +261,74 @@ acpi_ps_get_depth_next (
return (next);
}
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ps_get_child
+ *
+ * PARAMETERS: Op - Get the child of this Op
+ *
+ * RETURN: Child Op, Null if none is found.
+ *
+ * DESCRIPTION: Get op's children or NULL if none
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_child (
+ union acpi_parse_object *op)
+{
+ union acpi_parse_object *child = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ switch (op->common.aml_opcode) {
+ case AML_SCOPE_OP:
+ case AML_ELSE_OP:
+ case AML_DEVICE_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_INT_METHODCALL_OP:
+
+ child = acpi_ps_get_arg (op, 0);
+ break;
+
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_METHOD_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+
+ child = acpi_ps_get_arg (op, 1);
+ break;
+
+
+ case AML_POWER_RES_OP:
+ case AML_INDEX_FIELD_OP:
+
+ child = acpi_ps_get_arg (op, 2);
+ break;
+
+
+ case AML_PROCESSOR_OP:
+ case AML_BANK_FIELD_OP:
+
+ child = acpi_ps_get_arg (op, 3);
+ break;
+
+
+ default:
+ /* All others have no children */
+ break;
+ }
+
+ return (child);
+}
+#endif
+
#endif /* ACPI_FUTURE_USAGE */
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index b3597cb19f8..a10f88715d4 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -45,7 +45,6 @@
#include <acpi/acpi.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
-#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("psutils")
@@ -57,7 +56,7 @@
*
* PARAMETERS: None
*
- * RETURN: scope_op
+ * RETURN: A new Scope object, null on failure
*
* DESCRIPTION: Create a Scope and associated namepath op with the root name
*
@@ -75,7 +74,6 @@ acpi_ps_create_scope_op (
return (NULL);
}
-
scope_op->named.name = ACPI_ROOT_NAME;
return (scope_op);
}
@@ -88,10 +86,9 @@ acpi_ps_create_scope_op (
* PARAMETERS: Op - A newly allocated Op object
* Opcode - Opcode to store in the Op
*
- * RETURN: Status
+ * RETURN: None
*
- * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
- * opcode
+ * DESCRIPTION: Initialize a parse (Op) object
*
******************************************************************************/
@@ -107,7 +104,8 @@ acpi_ps_init_op (
op->common.aml_opcode = opcode;
ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name,
- (acpi_ps_get_opcode_info (opcode))->name, sizeof (op->common.aml_op_name)));
+ (acpi_ps_get_opcode_info (opcode))->name,
+ sizeof (op->common.aml_op_name)));
}
@@ -117,7 +115,7 @@ acpi_ps_init_op (
*
* PARAMETERS: Opcode - Opcode that will be stored in the new Op
*
- * RETURN: Pointer to the new Op.
+ * RETURN: Pointer to the new Op, null on failure
*
* DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
* opcode. A cache of opcodes is available for the pure
@@ -275,7 +273,6 @@ acpi_ps_get_name (
union acpi_parse_object *op)
{
-
/* The "generic" object has no name associated with it */
if (op->common.flags & ACPI_PARSEOP_GENERIC) {
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index 110d2ce917b..9d20cb2ceb5 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -90,17 +90,15 @@ acpi_ps_delete_parse_tree (
}
}
- /*
- * No more children, this Op is complete.
- */
+ /* No more children, this Op is complete. */
+
next = op->common.next;
parent = op->common.parent;
acpi_ps_free_op (op);
- /*
- * If we are back to the starting point, the walk is complete.
- */
+ /* If we are back to the starting point, the walk is complete. */
+
if (op == subtree_root) {
return_VOID;
}
@@ -111,5 +109,6 @@ acpi_ps_delete_parse_tree (
op = parent;
}
}
+
return_VOID;
}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index b318ad24726..dba893648e8 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -57,13 +57,16 @@
*
* FUNCTION: acpi_psx_execute
*
- * PARAMETERS: Info->Node - A method object containing both the AML
- * address and length.
- * **Params - List of parameters to pass to method,
+ * PARAMETERS: Info - Method info block, contains:
+ * Node - Method Node to execute
+ * Parameters - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
- * **return_obj_desc - Return object from execution of the
- * method.
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
+ * parameter_type - Type of Parameter list
+ * return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.
*
* RETURN: Status
*
@@ -196,9 +199,8 @@ acpi_psx_execute (
goto cleanup3;
}
- /*
- * The walk of the parse tree is where we actually execute the method
- */
+ /* The walk of the parse tree is where we actually execute the method */
+
status = acpi_ps_parse_aml (walk_state);
goto cleanup2; /* Walk state already deleted */
@@ -217,7 +219,8 @@ cleanup1:
for (i = 0; info->parameters[i]; i++) {
/* Ignore errors, just do them all */
- (void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT);
+ (void) acpi_ut_update_object_reference (
+ info->parameters[i], REF_DECREMENT);
}
}
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 8dbf802ee7f..d1f42b97282 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -433,7 +433,7 @@ acpi_pci_irq_enable (
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
pci_name(dev), ('A' + pin));
/* Interrupt Line values above 0xF are forbidden */
- if (dev->irq >= 0 && (dev->irq <= 0xF)) {
+ if (dev->irq > 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
return_VALUE(0);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 520b28ad074..6ad0e77df9b 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -72,10 +72,12 @@ struct acpi_pci_link_irq {
u8 active; /* Current IRQ */
u8 edge_level; /* All IRQs */
u8 active_high_low; /* All IRQs */
- u8 initialized;
u8 resource_type;
u8 possible_count;
u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+ u8 initialized:1;
+ u8 suspend_resume:1;
+ u8 reserved:6;
};
struct acpi_pci_link {
@@ -530,6 +532,10 @@ static int acpi_pci_link_allocate(
ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
+ if (link->irq.suspend_resume) {
+ acpi_pci_link_set(link, link->irq.active);
+ link->irq.suspend_resume = 0;
+ }
if (link->irq.initialized)
return_VALUE(0);
@@ -713,38 +719,24 @@ end:
return_VALUE(result);
}
-
-static int
-acpi_pci_link_resume (
- struct acpi_pci_link *link)
-{
- ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
-
- if (link->irq.active && link->irq.initialized)
- return_VALUE(acpi_pci_link_set(link, link->irq.active));
- else
- return_VALUE(0);
-}
-
-
static int
-irqrouter_resume(
- struct sys_device *dev)
+irqrouter_suspend(
+ struct sys_device *dev,
+ u32 state)
{
struct list_head *node = NULL;
struct acpi_pci_link *link = NULL;
- ACPI_FUNCTION_TRACE("irqrouter_resume");
+ ACPI_FUNCTION_TRACE("irqrouter_suspend");
list_for_each(node, &acpi_link.entries) {
-
link = list_entry(node, struct acpi_pci_link, node);
if (!link) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
continue;
}
-
- acpi_pci_link_resume(link);
+ if (link->irq.active && link->irq.initialized)
+ link->irq.suspend_resume = 1;
}
return_VALUE(0);
}
@@ -812,9 +804,12 @@ static int __init acpi_irq_penalty_update(char *str, int used)
* There is no ISA_POSSIBLE weight, so we simply use
* the (small) PCI_USING penalty.
*/
-void acpi_penalize_isa_irq(int irq)
+void acpi_penalize_isa_irq(int irq, int active)
{
- acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+ if (active)
+ acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
+ else
+ acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
}
/*
@@ -856,7 +851,7 @@ __setup("acpi_irq_balance", acpi_irq_balance_set);
static struct sysdev_class irqrouter_sysdev_class = {
set_kset_name("irqrouter"),
- .resume = irqrouter_resume,
+ .suspend = irqrouter_suspend,
};
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 76156ac91bd..d56a439ac61 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -256,6 +256,43 @@ acpi_processor_errata (
/* --------------------------------------------------------------------------
+ Common ACPI processor fucntions
+ -------------------------------------------------------------------------- */
+
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+
+int acpi_processor_set_pdc(struct acpi_processor *pr,
+ struct acpi_object_list *pdc_in)
+{
+ acpi_status status = AE_OK;
+ u32 arg0_buf[3];
+ union acpi_object arg0 = {ACPI_TYPE_BUFFER};
+ struct acpi_object_list no_object = {1, &arg0};
+ struct acpi_object_list *pdc;
+
+ ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
+
+ arg0.buffer.length = 12;
+ arg0.buffer.pointer = (u8 *) arg0_buf;
+ arg0_buf[0] = ACPI_PDC_REVISION_ID;
+ arg0_buf[1] = 0;
+ arg0_buf[2] = 0;
+
+ pdc = (pdc_in) ? pdc_in : &no_object;
+
+ status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
+
+ if ((ACPI_FAILURE(status)) && (pdc_in))
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
+
+ return_VALUE(status);
+}
+
+
+/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index c9d671cf785..893b074e3d1 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -6,6 +6,8 @@
* Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
* Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
* - Added processor hotplug support
+ * Copyright (C) 2005 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * - Added support for C3 on SMP
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -142,7 +144,7 @@ acpi_processor_power_activate (
switch (old->type) {
case ACPI_STATE_C3:
/* Disable bus master reload */
- if (new->type != ACPI_STATE_C3)
+ if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
break;
}
@@ -152,7 +154,7 @@ acpi_processor_power_activate (
switch (new->type) {
case ACPI_STATE_C3:
/* Enable bus master reload */
- if (old->type != ACPI_STATE_C3)
+ if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
break;
}
@@ -163,6 +165,9 @@ acpi_processor_power_activate (
}
+static atomic_t c3_cpu_count;
+
+
static void acpi_processor_idle (void)
{
struct acpi_processor *pr = NULL;
@@ -297,8 +302,22 @@ static void acpi_processor_idle (void)
break;
case ACPI_STATE_C3:
- /* Disable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+
+ if (pr->flags.bm_check) {
+ if (atomic_inc_return(&c3_cpu_count) ==
+ num_online_cpus()) {
+ /*
+ * All CPUs are trying to go to C3
+ * Disable bus master arbitration
+ */
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
+ ACPI_MTX_DO_NOT_LOCK);
+ }
+ } else {
+ /* SMP with no shared cache... Invalidate cache */
+ ACPI_FLUSH_CPU_CACHE();
+ }
+
/* Get start time (ticks) */
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Invoke C3 */
@@ -307,8 +326,12 @@ static void acpi_processor_idle (void)
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Get end time (ticks) */
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
- /* Enable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+ if (pr->flags.bm_check) {
+ /* Enable bus master arbitration */
+ atomic_dec(&c3_cpu_count);
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+ }
+
/* Re-enable interrupts */
local_irq_enable();
/* Compute time (ticks) that we were actually asleep */
@@ -519,6 +542,29 @@ static int acpi_processor_get_power_info_fadt (struct acpi_processor *pr)
}
+static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
+{
+ int i;
+
+ ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
+
+ for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+ memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+
+ /* if info is obtained from pblk/fadt, type equals state */
+ pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+ pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
+ pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
+
+ /* the C0 state only exists as a filler in our array,
+ * and all processors need to support C1 */
+ pr->power.states[ACPI_STATE_C0].valid = 1;
+ pr->power.states[ACPI_STATE_C1].valid = 1;
+
+ return_VALUE(0);
+}
+
+
static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
{
acpi_status status = 0;
@@ -529,9 +575,6 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_cst");
- if (errata.smp)
- return_VALUE(-ENODEV);
-
if (nocst)
return_VALUE(-ENODEV);
@@ -664,13 +707,6 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
return_VOID;
}
- /* We're (currently) only supporting C2 on UP */
- else if (errata.smp) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C2 not supported in SMP mode\n"));
- return_VOID;
- }
-
/*
* Otherwise we've met all of our C2 requirements.
* Normalize the C2 latency to expidite policy
@@ -686,6 +722,8 @@ static void acpi_processor_power_verify_c3(
struct acpi_processor *pr,
struct acpi_processor_cx *cx)
{
+ static int bm_check_flag;
+
ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c3");
if (!cx->address)
@@ -702,20 +740,6 @@ static void acpi_processor_power_verify_c3(
return_VOID;
}
- /* bus mastering control is necessary */
- else if (!pr->flags.bm_control) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C3 support requires bus mastering control\n"));
- return_VOID;
- }
-
- /* We're (currently) only supporting C2 on UP */
- else if (errata.smp) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C3 not supported in SMP mode\n"));
- return_VOID;
- }
-
/*
* PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
* DMA transfers are used by any ISA device to avoid livelock.
@@ -729,6 +753,39 @@ static void acpi_processor_power_verify_c3(
return_VOID;
}
+ /* All the logic here assumes flags.bm_check is same across all CPUs */
+ if (!bm_check_flag) {
+ /* Determine whether bm_check is needed based on CPU */
+ acpi_processor_power_init_bm_check(&(pr->flags), pr->id);
+ bm_check_flag = pr->flags.bm_check;
+ } else {
+ pr->flags.bm_check = bm_check_flag;
+ }
+
+ if (pr->flags.bm_check) {
+ printk("Disabling BM access before entering C3\n");
+ /* bus mastering control is necessary */
+ if (!pr->flags.bm_control) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "C3 support requires bus mastering control\n"));
+ return_VOID;
+ }
+ } else {
+ printk("Invalidating cache before entering C3\n");
+ /*
+ * WBINVD should be set in fadt, for C3 state to be
+ * supported on when bm_check is not required.
+ */
+ if (acpi_fadt.wb_invd != 1) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Cache invalidation should work properly"
+ " for C3 to be enabled on SMP systems\n"));
+ return_VOID;
+ }
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD,
+ 0, ACPI_MTX_DO_NOT_LOCK);
+ }
+
/*
* Otherwise we've met all of our C3 requirements.
* Normalize the C3 latency to expidite policy. Enable
@@ -737,7 +794,6 @@ static void acpi_processor_power_verify_c3(
*/
cx->valid = 1;
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
- pr->flags.bm_check = 1;
return_VOID;
}
@@ -787,10 +843,7 @@ static int acpi_processor_get_power_info (
if ((result) || (acpi_processor_power_verify(pr) < 2)) {
result = acpi_processor_get_power_info_fadt(pr);
if (result)
- return_VALUE(result);
-
- if (acpi_processor_power_verify(pr) < 2)
- return_VALUE(-ENODEV);
+ result = acpi_processor_get_power_info_default_c1(pr);
}
/*
@@ -810,11 +863,10 @@ static int acpi_processor_get_power_info (
* CPU as being "idle manageable"
*/
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- if (pr->power.states[i].valid)
+ if (pr->power.states[i].valid) {
pr->power.count = i;
- if ((pr->power.states[i].valid) &&
- (pr->power.states[i].type >= ACPI_STATE_C2))
pr->flags.power = 1;
+ }
}
return_VALUE(0);
@@ -829,7 +881,7 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr)
if (!pr)
return_VALUE(-EINVAL);
- if (errata.smp || nocst) {
+ if ( nocst) {
return_VALUE(-ENODEV);
}
@@ -929,7 +981,6 @@ static struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
-
int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device)
{
acpi_status status = 0;
@@ -946,7 +997,10 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
first_run++;
}
- if (!errata.smp && (pr->id == 0) && acpi_fadt.cst_cnt && !nocst) {
+ if (!pr)
+ return_VALUE(-EINVAL);
+
+ if (acpi_fadt.cst_cnt && !nocst) {
status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -954,6 +1008,8 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *dev
}
}
+ acpi_processor_power_init_pdc(&(pr->power), pr->id);
+ acpi_processor_set_pdc(pr, pr->power.pdc);
acpi_processor_get_power_info(pr);
/*
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index a9a1a8fe319..1f0d6256302 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -165,37 +165,6 @@ void acpi_processor_ppc_exit(void) {
acpi_processor_ppc_status &= ~PPC_REGISTERED;
}
-/*
- * when registering a cpufreq driver with this ACPI processor driver, the
- * _PCT and _PSS structures are read out and written into struct
- * acpi_processor_performance.
- */
-static int acpi_processor_set_pdc (struct acpi_processor *pr)
-{
- acpi_status status = AE_OK;
- u32 arg0_buf[3];
- union acpi_object arg0 = {ACPI_TYPE_BUFFER};
- struct acpi_object_list no_object = {1, &arg0};
- struct acpi_object_list *pdc;
-
- ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
-
- arg0.buffer.length = 12;
- arg0.buffer.pointer = (u8 *) arg0_buf;
- arg0_buf[0] = ACPI_PDC_REVISION_ID;
- arg0_buf[1] = 0;
- arg0_buf[2] = 0;
-
- pdc = (pr->performance->pdc) ? pr->performance->pdc : &no_object;
-
- status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
-
- if ((ACPI_FAILURE(status)) && (pr->performance->pdc))
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
-
- return_VALUE(status);
-}
-
static int
acpi_processor_get_performance_control (
@@ -357,7 +326,7 @@ acpi_processor_get_performance_info (
if (!pr || !pr->performance || !pr->handle)
return_VALUE(-EINVAL);
- acpi_processor_set_pdc(pr);
+ acpi_processor_set_pdc(pr, pr->performance->pdc);
status = acpi_get_handle(pr->handle, "_PCT", &handle);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 4788c079735..55d264771c4 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -77,21 +77,21 @@ acpi_rs_address16_resource (
u8 **output_buffer,
acpi_size *structure_size)
{
- u8 *buffer = byte_stream_buffer;
- struct acpi_resource *output_struct = (void *) *output_buffer;
- u8 *temp_ptr;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16);
u32 index;
u16 temp16;
u8 temp8;
+ u8 *temp_ptr;
+ u8 *buffer = byte_stream_buffer;
+ struct acpi_resource *output_struct = (void *) *output_buffer;
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_address16);
ACPI_FUNCTION_TRACE ("rs_address16_resource");
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -104,9 +104,8 @@ acpi_rs_address16_resource (
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS16;
- /*
- * Get the Resource Type (Byte3)
- */
+ /* Get the Resource Type (Byte3) */
+
buffer += 2;
temp8 = *buffer;
@@ -118,9 +117,8 @@ acpi_rs_address16_resource (
output_struct->data.address16.resource_type = temp8;
- /*
- * Get the General Flags (Byte4)
- */
+ /* Get the General Flags (Byte4) */
+
buffer += 1;
temp8 = *buffer;
@@ -140,9 +138,8 @@ acpi_rs_address16_resource (
output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
- /*
- * Get the Type Specific Flags (Byte5)
- */
+ /* Get the Type Specific Flags (Byte5) */
+
buffer += 1;
temp8 = *buffer;
@@ -165,39 +162,34 @@ acpi_rs_address16_resource (
}
}
- /*
- * Get Granularity (Bytes 6-7)
- */
+ /* Get Granularity (Bytes 6-7) */
+
buffer += 1;
ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer);
- /*
- * Get min_address_range (Bytes 8-9)
- */
+ /* Get min_address_range (Bytes 8-9) */
+
buffer += 2;
ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer);
- /*
- * Get max_address_range (Bytes 10-11)
- */
+ /* Get max_address_range (Bytes 10-11) */
+
buffer += 2;
ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer);
- /*
- * Get address_translation_offset (Bytes 12-13)
- */
+ /* Get address_translation_offset (Bytes 12-13) */
+
buffer += 2;
- ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset, buffer);
+ ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset,
+ buffer);
+
+ /* Get address_length (Bytes 14-15) */
- /*
- * Get address_length (Bytes 14-15)
- */
buffer += 2;
ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer);
- /*
- * Resource Source Index (if present)
- */
+ /* Resource Source Index (if present) */
+
buffer += 2;
/*
@@ -225,7 +217,8 @@ acpi_rs_address16_resource (
output_struct->data.address16.resource_source.string_ptr =
(char *)((u8 * )output_struct + struct_size);
- temp_ptr = (u8 *) output_struct->data.address16.resource_source.string_ptr;
+ temp_ptr = (u8 *)
+ output_struct->data.address16.resource_source.string_ptr;
/* Copy the string into the buffer */
@@ -239,9 +232,8 @@ acpi_rs_address16_resource (
index += 1;
}
- /*
- * Add the terminating null
- */
+ /* Add the terminating null */
+
*temp_ptr = 0x00;
output_struct->data.address16.resource_source.string_length = index + 1;
@@ -260,14 +252,12 @@ acpi_rs_address16_resource (
output_struct->data.address16.resource_source.string_ptr = NULL;
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -305,28 +295,24 @@ acpi_rs_address16_stream (
ACPI_FUNCTION_TRACE ("rs_address16_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x88;
buffer += 1;
- /*
- * Save a pointer to the Length field - to be filled in later
- */
+ /* Save a pointer to the Length field - to be filled in later */
+
length_field = buffer;
buffer += 2;
- /*
- * Set the Resource Type (Memory, Io, bus_number)
- */
+ /* Set the Resource Type (Memory, Io, bus_number) */
+
temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
*buffer = temp8;
buffer += 1;
- /*
- * Set the general flags
- */
+ /* Set the general flags */
+
temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
@@ -336,9 +322,8 @@ acpi_rs_address16_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the type specific flags
- */
+ /* Set the type specific flags */
+
temp8 = 0;
if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
@@ -362,39 +347,34 @@ acpi_rs_address16_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the address space granularity
- */
+ /* Set the address space granularity */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity);
buffer += 2;
- /*
- * Set the address range minimum
- */
+ /* Set the address range minimum */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range);
buffer += 2;
- /*
- * Set the address range maximum
- */
+ /* Set the address range maximum */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range);
buffer += 2;
- /*
- * Set the address translation offset
- */
- ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_translation_offset);
+ /* Set the address translation offset */
+
+ ACPI_MOVE_32_TO_16 (buffer,
+ &linked_list->data.address16.address_translation_offset);
buffer += 2;
- /*
- * Set the address length
- */
+ /* Set the address length */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length);
buffer += 2;
- /*
- * Resource Source Index and Resource Source are optional
- */
+ /* Resource Source Index and Resource Source are optional */
+
if (0 != linked_list->data.address16.resource_source.string_length) {
temp8 = (u8) linked_list->data.address16.resource_source.index;
@@ -403,9 +383,8 @@ acpi_rs_address16_stream (
temp_pointer = (char *) buffer;
- /*
- * Copy the string
- */
+ /* Copy the string */
+
ACPI_STRCPY (temp_pointer,
linked_list->data.address16.resource_source.string_ptr);
@@ -413,12 +392,12 @@ acpi_rs_address16_stream (
* Buffer needs to be set to the length of the sting + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1);
+ buffer += (acpi_size)(ACPI_STRLEN (
+ linked_list->data.address16.resource_source.string_ptr) + 1);
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer);
*bytes_consumed = actual_bytes;
@@ -475,9 +454,8 @@ acpi_rs_address32_resource (
buffer = byte_stream_buffer;
struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32);
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -490,9 +468,8 @@ acpi_rs_address32_resource (
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS32;
- /*
- * Get the Resource Type (Byte3)
- */
+ /* Get the Resource Type (Byte3) */
+
buffer += 2;
temp8 = *buffer;
@@ -504,35 +481,29 @@ acpi_rs_address32_resource (
output_struct->data.address32.resource_type = temp8;
- /*
- * Get the General Flags (Byte4)
- */
+ /* Get the General Flags (Byte4) */
+
buffer += 1;
temp8 = *buffer;
- /*
- * Producer / Consumer
- */
+ /* Producer / Consumer */
+
output_struct->data.address32.producer_consumer = temp8 & 0x01;
- /*
- * Decode
- */
+ /* Decode */
+
output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
- /*
- * Min Address Fixed
- */
+ /* Min Address Fixed */
+
output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
- /*
- * Max Address Fixed
- */
+ /* Max Address Fixed */
+
output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
- /*
- * Get the Type Specific Flags (Byte5)
- */
+ /* Get the Type Specific Flags (Byte5) */
+
buffer += 1;
temp8 = *buffer;
@@ -556,39 +527,34 @@ acpi_rs_address32_resource (
}
}
- /*
- * Get Granularity (Bytes 6-9)
- */
+ /* Get Granularity (Bytes 6-9) */
+
buffer += 1;
ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
- /*
- * Get min_address_range (Bytes 10-13)
- */
+ /* Get min_address_range (Bytes 10-13) */
+
buffer += 4;
ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
- /*
- * Get max_address_range (Bytes 14-17)
- */
+ /* Get max_address_range (Bytes 14-17) */
+
buffer += 4;
ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
- /*
- * Get address_translation_offset (Bytes 18-21)
- */
+ /* Get address_translation_offset (Bytes 18-21) */
+
buffer += 4;
- ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer);
+ ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset,
+ buffer);
+
+ /* Get address_length (Bytes 22-25) */
- /*
- * Get address_length (Bytes 22-25)
- */
buffer += 4;
ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
- /*
- * Resource Source Index (if present)
- */
+ /* Resource Source Index (if present) */
+
buffer += 4;
/*
@@ -615,7 +581,8 @@ acpi_rs_address32_resource (
output_struct->data.address32.resource_source.string_ptr =
(char *)((u8 *)output_struct + struct_size);
- temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr;
+ temp_ptr = (u8 *)
+ output_struct->data.address32.resource_source.string_ptr;
/* Copy the string into the buffer */
@@ -628,9 +595,8 @@ acpi_rs_address32_resource (
index += 1;
}
- /*
- * Add the terminating null
- */
+ /* Add the terminating null */
+
*temp_ptr = 0x00;
output_struct->data.address32.resource_source.string_length = index + 1;
@@ -648,14 +614,12 @@ acpi_rs_address32_resource (
output_struct->data.address32.resource_source.string_ptr = NULL;
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -694,29 +658,25 @@ acpi_rs_address32_stream (
buffer = *output_buffer;
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x87;
buffer += 1;
- /*
- * Set a pointer to the Length field - to be filled in later
- */
+ /* Set a pointer to the Length field - to be filled in later */
+
length_field = ACPI_CAST_PTR (u16, buffer);
buffer += 2;
- /*
- * Set the Resource Type (Memory, Io, bus_number)
- */
+ /* Set the Resource Type (Memory, Io, bus_number) */
+
temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
*buffer = temp8;
buffer += 1;
- /*
- * Set the general flags
- */
+ /* Set the general flags */
+
temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
@@ -725,9 +685,8 @@ acpi_rs_address32_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the type specific flags
- */
+ /* Set the type specific flags */
+
temp8 = 0;
if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
@@ -751,39 +710,34 @@ acpi_rs_address32_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the address space granularity
- */
+ /* Set the address space granularity */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
buffer += 4;
- /*
- * Set the address range minimum
- */
+ /* Set the address range minimum */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
buffer += 4;
- /*
- * Set the address range maximum
- */
+ /* Set the address range maximum */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
buffer += 4;
- /*
- * Set the address translation offset
- */
- ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset);
+ /* Set the address translation offset */
+
+ ACPI_MOVE_32_TO_32 (buffer,
+ &linked_list->data.address32.address_translation_offset);
buffer += 4;
- /*
- * Set the address length
- */
+ /* Set the address length */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
buffer += 4;
- /*
- * Resource Source Index and Resource Source are optional
- */
+ /* Resource Source Index and Resource Source are optional */
+
if (0 != linked_list->data.address32.resource_source.string_length) {
temp8 = (u8) linked_list->data.address32.resource_source.index;
@@ -792,9 +746,8 @@ acpi_rs_address32_stream (
temp_pointer = (char *) buffer;
- /*
- * Copy the string
- */
+ /* Copy the string */
+
ACPI_STRCPY (temp_pointer,
linked_list->data.address32.resource_source.string_ptr);
@@ -802,12 +755,12 @@ acpi_rs_address32_stream (
* Buffer needs to be set to the length of the sting + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
+ buffer += (acpi_size)(ACPI_STRLEN (
+ linked_list->data.address32.resource_source.string_ptr) + 1);
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
/*
@@ -864,9 +817,8 @@ acpi_rs_address64_resource (
struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
resource_type = *buffer;
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -879,9 +831,8 @@ acpi_rs_address64_resource (
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS64;
- /*
- * Get the Resource Type (Byte3)
- */
+ /* Get the Resource Type (Byte3) */
+
buffer += 2;
temp8 = *buffer;
@@ -893,35 +844,29 @@ acpi_rs_address64_resource (
output_struct->data.address64.resource_type = temp8;
- /*
- * Get the General Flags (Byte4)
- */
+ /* Get the General Flags (Byte4) */
+
buffer += 1;
temp8 = *buffer;
- /*
- * Producer / Consumer
- */
+ /* Producer / Consumer */
+
output_struct->data.address64.producer_consumer = temp8 & 0x01;
- /*
- * Decode
- */
+ /* Decode */
+
output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
- /*
- * Min Address Fixed
- */
+ /* Min Address Fixed */
+
output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
- /*
- * Max Address Fixed
- */
+ /* Max Address Fixed */
+
output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
- /*
- * Get the Type Specific Flags (Byte5)
- */
+ /* Get the Type Specific Flags (Byte5) */
+
buffer += 1;
temp8 = *buffer;
@@ -951,33 +896,29 @@ acpi_rs_address64_resource (
buffer += 2;
}
- /*
- * Get Granularity (Bytes 6-13) or (Bytes 8-15)
- */
+ /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
+
buffer += 1;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
- /*
- * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
- */
+ /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
+
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
- /*
- * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
- */
+ /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
+
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
- /*
- * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
- */
+ /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
+
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
+ ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset,
+ buffer);
+
+ /* Get address_length (Bytes 38-45) or (Bytes 40-47) */
- /*
- * Get address_length (Bytes 38-45) or (Bytes 40-47)
- */
buffer += 8;
ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
@@ -989,14 +930,15 @@ acpi_rs_address64_resource (
/* Get type_specific_attribute (Bytes 48-55) */
buffer += 8;
- ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer);
+ ACPI_MOVE_64_TO_64 (
+ &output_struct->data.address64.type_specific_attributes,
+ buffer);
}
else {
output_struct->data.address64.type_specific_attributes = 0;
- /*
- * Resource Source Index (if present)
- */
+ /* Resource Source Index (if present) */
+
buffer += 8;
/*
@@ -1025,7 +967,8 @@ acpi_rs_address64_resource (
output_struct->data.address64.resource_source.string_ptr =
(char *)((u8 *)output_struct + struct_size);
- temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
+ temp_ptr = (u8 *)
+ output_struct->data.address64.resource_source.string_ptr;
/* Copy the string into the buffer */
@@ -1042,7 +985,8 @@ acpi_rs_address64_resource (
* Add the terminating null
*/
*temp_ptr = 0x00;
- output_struct->data.address64.resource_source.string_length = index + 1;
+ output_struct->data.address64.resource_source.string_length =
+ index + 1;
/*
* In order for the struct_size to fall on a 32-bit boundary,
@@ -1054,14 +998,12 @@ acpi_rs_address64_resource (
}
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -1100,29 +1042,25 @@ acpi_rs_address64_stream (
buffer = *output_buffer;
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x8A;
buffer += 1;
- /*
- * Set a pointer to the Length field - to be filled in later
- */
+ /* Set a pointer to the Length field - to be filled in later */
+
length_field = ACPI_CAST_PTR (u16, buffer);
buffer += 2;
- /*
- * Set the Resource Type (Memory, Io, bus_number)
- */
+ /* Set the Resource Type (Memory, Io, bus_number) */
+
temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
*buffer = temp8;
buffer += 1;
- /*
- * Set the general flags
- */
+ /* Set the general flags */
+
temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
@@ -1131,9 +1069,8 @@ acpi_rs_address64_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the type specific flags
- */
+ /* Set the type specific flags */
+
temp8 = 0;
if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
@@ -1157,39 +1094,34 @@ acpi_rs_address64_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the address space granularity
- */
+ /* Set the address space granularity */
+
ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
buffer += 8;
- /*
- * Set the address range minimum
- */
+ /* Set the address range minimum */
+
ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
buffer += 8;
- /*
- * Set the address range maximum
- */
+ /* Set the address range maximum */
+
ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
buffer += 8;
- /*
- * Set the address translation offset
- */
- ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset);
+ /* Set the address translation offset */
+
+ ACPI_MOVE_64_TO_64 (buffer,
+ &linked_list->data.address64.address_translation_offset);
buffer += 8;
- /*
- * Set the address length
- */
+ /* Set the address length */
+
ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
buffer += 8;
- /*
- * Resource Source Index and Resource Source are optional
- */
+ /* Resource Source Index and Resource Source are optional */
+
if (0 != linked_list->data.address64.resource_source.string_length) {
temp8 = (u8) linked_list->data.address64.resource_source.index;
@@ -1198,21 +1130,21 @@ acpi_rs_address64_stream (
temp_pointer = (char *) buffer;
- /*
- * Copy the string
- */
- ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
+ /* Copy the string */
+
+ ACPI_STRCPY (temp_pointer,
+ linked_list->data.address64.resource_source.string_ptr);
/*
* Buffer needs to be set to the length of the sting + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
+ buffer += (acpi_size)(ACPI_STRLEN (
+ linked_list->data.address64.resource_source.string_ptr) + 1);
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
/*
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 8a5f0a52371..98176f2fcb5 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -81,9 +81,8 @@ acpi_rs_get_byte_stream_length (
while (!done) {
- /*
- * Init the variable that will hold the size to add to the total.
- */
+ /* Init the variable that will hold the size to add to the total. */
+
segment_size = 0;
switch (linked_list->id) {
@@ -196,7 +195,8 @@ acpi_rs_get_byte_stream_length (
segment_size = 16;
if (linked_list->data.address16.resource_source.string_ptr) {
- segment_size += linked_list->data.address16.resource_source.string_length;
+ segment_size +=
+ linked_list->data.address16.resource_source.string_length;
segment_size++;
}
break;
@@ -212,7 +212,8 @@ acpi_rs_get_byte_stream_length (
segment_size = 26;
if (linked_list->data.address32.resource_source.string_ptr) {
- segment_size += linked_list->data.address32.resource_source.string_length;
+ segment_size +=
+ linked_list->data.address32.resource_source.string_length;
segment_size++;
}
break;
@@ -227,7 +228,8 @@ acpi_rs_get_byte_stream_length (
segment_size = 46;
if (linked_list->data.address64.resource_source.string_ptr) {
- segment_size += linked_list->data.address64.resource_source.string_length;
+ segment_size +=
+ linked_list->data.address64.resource_source.string_length;
segment_size++;
}
break;
@@ -241,38 +243,36 @@ acpi_rs_get_byte_stream_length (
* Index + the length of the null terminated string
* Resource Source + 1 for the null.
*/
- segment_size = 9 +
- (((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
+ segment_size = 9 + (((acpi_size)
+ linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
if (linked_list->data.extended_irq.resource_source.string_ptr) {
- segment_size += linked_list->data.extended_irq.resource_source.string_length;
+ segment_size +=
+ linked_list->data.extended_irq.resource_source.string_length;
segment_size++;
}
break;
default:
- /*
- * If we get here, everything is out of sync, exit with error
- */
+
+ /* If we get here, everything is out of sync, exit with error */
+
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
} /* switch (linked_list->Id) */
- /*
- * Update the total
- */
+ /* Update the total */
+
byte_stream_size_needed += segment_size;
- /*
- * Point to the next object
- */
+ /* Point to the next object */
+
linked_list = ACPI_PTR_ADD (struct acpi_resource,
linked_list, linked_list->length);
}
- /*
- * This is the data the caller needs
- */
+ /* This is the data the caller needs */
+
*size_needed = byte_stream_size_needed;
return_ACPI_STATUS (AE_OK);
}
@@ -320,9 +320,8 @@ acpi_rs_get_list_length (
while (bytes_parsed < byte_stream_buffer_length) {
- /*
- * The next byte in the stream is the resource type
- */
+ /* The next byte in the stream is the resource type */
+
resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
switch (resource_type) {
@@ -346,9 +345,8 @@ acpi_rs_get_list_length (
ACPI_MOVE_16_TO_16 (&temp16, buffer);
bytes_consumed = temp16 + 3;
- /*
- * Ensure a 32-bit boundary for the structure
- */
+ /* Ensure a 32-bit boundary for the structure */
+
temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
@@ -416,9 +414,8 @@ acpi_rs_get_list_length (
temp8 = 0;
}
- /*
- * Ensure a 64-bit boundary for the structure
- */
+ /* Ensure a 64-bit boundary for the structure */
+
temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) +
@@ -452,9 +449,8 @@ acpi_rs_get_list_length (
temp8 = 0;
}
- /*
- * Ensure a 32-bit boundary for the structure
- */
+ /* Ensure a 32-bit boundary for the structure */
+
temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) +
@@ -488,9 +484,8 @@ acpi_rs_get_list_length (
temp8 = 0;
}
- /*
- * Ensure a 32-bit boundary for the structure
- */
+ /* Ensure a 32-bit boundary for the structure */
+
temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) +
@@ -537,9 +532,8 @@ acpi_rs_get_list_length (
temp8 = 0;
}
- /*
- * Ensure a 32-bit boundary for the structure
- */
+ /* Ensure a 32-bit boundary for the structure */
+
temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) +
@@ -567,9 +561,8 @@ acpi_rs_get_list_length (
++buffer;
- /*
- * Look at the number of bits set
- */
+ /* Look at the number of bits set */
+
ACPI_MOVE_16_TO_16 (&temp16, buffer);
for (index = 0; index < 16; index++) {
@@ -596,9 +589,8 @@ acpi_rs_get_list_length (
++buffer;
- /*
- * Look at the number of bits set
- */
+ /* Look at the number of bits set */
+
temp8 = *buffer;
for(index = 0; index < 8; index++) {
@@ -670,9 +662,8 @@ acpi_rs_get_list_length (
temp8 = (u8) (temp8 & 0x7);
bytes_consumed = temp8 + 1;
- /*
- * Ensure a 32-bit boundary for the structure
- */
+ /* Ensure a 32-bit boundary for the structure */
+
temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
(temp8 * sizeof (u8));
@@ -697,21 +688,18 @@ acpi_rs_get_list_length (
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
}
- /*
- * Update the return value and counter
- */
+ /* Update the return value and counter */
+
buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
bytes_parsed += bytes_consumed;
- /*
- * Set the byte stream to point to the next resource
- */
+ /* Set the byte stream to point to the next resource */
+
byte_stream_buffer += bytes_consumed;
}
- /*
- * This is the data the caller needs
- */
+ /* This is the data the caller needs */
+
*size_needed = buffer_size;
return_ACPI_STATUS (AE_OK);
}
@@ -767,9 +755,8 @@ acpi_rs_get_pci_routing_table_length (
top_object_list = package_object->package.elements;
for (index = 0; index < number_of_elements; index++) {
- /*
- * Dereference the sub-package
- */
+ /* Dereference the sub-package */
+
package_element = *top_object_list;
/*
@@ -778,37 +765,40 @@ acpi_rs_get_pci_routing_table_length (
*/
sub_object_list = package_element->package.elements;
- /*
- * Scan the irq_table_elements for the Source Name String
- */
+ /* Scan the irq_table_elements for the Source Name String */
+
name_found = FALSE;
for (table_index = 0; table_index < 4 && !name_found; table_index++) {
- if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
- ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
- ((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) {
+ if ((ACPI_TYPE_STRING ==
+ ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
+
+ ((ACPI_TYPE_LOCAL_REFERENCE ==
+ ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
+
+ ((*sub_object_list)->reference.opcode ==
+ AML_INT_NAMEPATH_OP))) {
name_found = TRUE;
}
else {
- /*
- * Look at the next element
- */
+ /* Look at the next element */
+
sub_object_list++;
}
}
temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4);
- /*
- * Was a String type found?
- */
+ /* Was a String type found? */
+
if (name_found) {
if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
/*
* The length String.Length field does not include the
* terminating NULL, add 1
*/
- temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1);
+ temp_size_needed += ((acpi_size)
+ (*sub_object_list)->string.length + 1);
}
else {
temp_size_needed += acpi_ns_get_pathname_length (
@@ -827,14 +817,14 @@ acpi_rs_get_pci_routing_table_length (
temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed);
- /*
- * Point to the next union acpi_operand_object
- */
+ /* Point to the next union acpi_operand_object */
+
top_object_list++;
}
/*
- * Adding an extra element to the end of the list, essentially a NULL terminator
+ * Adding an extra element to the end of the list, essentially a
+ * NULL terminator
*/
*buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table);
return_ACPI_STATUS (AE_OK);
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index a3a0cbfda68..8e0eae0d50b 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -87,9 +87,8 @@ acpi_rs_create_resource_list (
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
byte_stream_buffer));
- /*
- * Params already validated, so we don't re-validate here
- */
+ /* Params already validated, so we don't re-validate here */
+
byte_stream_buffer_length = byte_stream_buffer->buffer.length;
byte_stream_start = byte_stream_buffer->buffer.pointer;
@@ -171,9 +170,8 @@ acpi_rs_create_pci_routing_table (
/* Params already validated, so we don't re-validate here */
- /*
- * Get the required buffer length
- */
+ /* Get the required buffer length */
+
status = acpi_rs_get_pci_routing_table_length (package_object,
&buffer_size_needed);
if (ACPI_FAILURE (status)) {
@@ -217,9 +215,8 @@ acpi_rs_create_pci_routing_table (
*/
user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4);
- /*
- * Each element of the top-level package must also be a package
- */
+ /* Each element of the top-level package must also be a package */
+
if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"(PRT[%X]) Need sub-package, found %s\n",
@@ -243,9 +240,8 @@ acpi_rs_create_pci_routing_table (
*/
sub_object_list = (*top_object_list)->package.elements;
- /*
- * 1) First subobject: Dereference the PRT.Address
- */
+ /* 1) First subobject: Dereference the PRT.Address */
+
obj_desc = sub_object_list[0];
if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->address = obj_desc->integer.value;
@@ -257,9 +253,8 @@ acpi_rs_create_pci_routing_table (
return_ACPI_STATUS (AE_BAD_DATA);
}
- /*
- * 2) Second subobject: Dereference the PRT.Pin
- */
+ /* 2) Second subobject: Dereference the PRT.Pin */
+
obj_desc = sub_object_list[1];
if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->pin = (u32) obj_desc->integer.value;
@@ -271,9 +266,8 @@ acpi_rs_create_pci_routing_table (
return_ACPI_STATUS (AE_BAD_DATA);
}
- /*
- * 3) Third subobject: Dereference the PRT.source_name
- */
+ /* 3) Third subobject: Dereference the PRT.source_name */
+
obj_desc = sub_object_list[2];
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE:
@@ -296,7 +290,9 @@ acpi_rs_create_pci_routing_table (
status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer);
- user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */
+ /* +1 to include null terminator */
+
+ user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1;
break;
@@ -304,8 +300,10 @@ acpi_rs_create_pci_routing_table (
ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
- /* Add to the Length field the length of the string (add 1 for terminator) */
-
+ /*
+ * Add to the Length field the length of the string
+ * (add 1 for terminator)
+ */
user_prt->length += obj_desc->string.length + 1;
break;
@@ -333,9 +331,8 @@ acpi_rs_create_pci_routing_table (
user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
- /*
- * 4) Fourth subobject: Dereference the PRT.source_index
- */
+ /* 4) Fourth subobject: Dereference the PRT.source_index */
+
obj_desc = sub_object_list[3];
if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->source_index = (u32) obj_desc->integer.value;
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index eef1b1f2c68..1935dab2ab5 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -48,9 +48,62 @@
#define _COMPONENT ACPI_RESOURCES
ACPI_MODULE_NAME ("rsdump")
+/* Local prototypes */
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+static void
+acpi_rs_dump_irq (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_address16 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_address32 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_address64 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_dma (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_io (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_extended_irq (
+ union acpi_resource_data *data);
+static void
+acpi_rs_dump_fixed_io (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_fixed_memory32 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_memory24 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_memory32 (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_start_depend_fns (
+ union acpi_resource_data *data);
+
+static void
+acpi_rs_dump_vendor_specific (
+ union acpi_resource_data *data);
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/*******************************************************************************
*
* FUNCTION: acpi_rs_dump_irq
@@ -63,7 +116,7 @@
*
******************************************************************************/
-void
+static void
acpi_rs_dump_irq (
union acpi_resource_data *data)
{
@@ -77,13 +130,13 @@ acpi_rs_dump_irq (
acpi_os_printf ("IRQ Resource\n");
acpi_os_printf (" %s Triggered\n",
- ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
+ ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
acpi_os_printf (" Active %s\n",
- ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
+ ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
acpi_os_printf (" %s\n",
- ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
+ ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
acpi_os_printf (" %X Interrupts ( ", irq_data->number_of_interrupts);
@@ -108,7 +161,7 @@ acpi_rs_dump_irq (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_dma (
union acpi_resource_data *data)
{
@@ -144,7 +197,7 @@ acpi_rs_dump_dma (
}
acpi_os_printf (" %sBus Master\n",
- ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
+ ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
switch (dma_data->transfer) {
@@ -165,7 +218,8 @@ acpi_rs_dump_dma (
break;
}
- acpi_os_printf (" Number of Channels: %X ( ", dma_data->number_of_channels);
+ acpi_os_printf (" Number of Channels: %X ( ",
+ dma_data->number_of_channels);
for (index = 0; index < dma_data->number_of_channels; index++) {
acpi_os_printf ("%X ", dma_data->channels[index]);
@@ -188,7 +242,7 @@ acpi_rs_dump_dma (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_start_depend_fns (
union acpi_resource_data *data)
{
@@ -232,8 +286,7 @@ acpi_rs_dump_start_depend_fns (
break;
default:
- acpi_os_printf (" Invalid performance "
- "robustness preference\n");
+ acpi_os_printf (" Invalid performance robustness preference\n");
break;
}
@@ -253,7 +306,7 @@ acpi_rs_dump_start_depend_fns (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_io (
union acpi_resource_data *data)
{
@@ -266,19 +319,15 @@ acpi_rs_dump_io (
acpi_os_printf ("Io Resource\n");
acpi_os_printf (" %d bit decode\n",
- ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
+ ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
- acpi_os_printf (" Range minimum base: %08X\n",
- io_data->min_base_address);
+ acpi_os_printf (" Range minimum base: %08X\n", io_data->min_base_address);
- acpi_os_printf (" Range maximum base: %08X\n",
- io_data->max_base_address);
+ acpi_os_printf (" Range maximum base: %08X\n", io_data->max_base_address);
- acpi_os_printf (" Alignment: %08X\n",
- io_data->alignment);
+ acpi_os_printf (" Alignment: %08X\n", io_data->alignment);
- acpi_os_printf (" Range Length: %08X\n",
- io_data->range_length);
+ acpi_os_printf (" Range Length: %08X\n", io_data->range_length);
return;
}
@@ -296,7 +345,7 @@ acpi_rs_dump_io (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_fixed_io (
union acpi_resource_data *data)
{
@@ -307,11 +356,9 @@ acpi_rs_dump_fixed_io (
acpi_os_printf ("Fixed Io Resource\n");
- acpi_os_printf (" Range base address: %08X",
- fixed_io_data->base_address);
+ acpi_os_printf (" Range base address: %08X", fixed_io_data->base_address);
- acpi_os_printf (" Range length: %08X",
- fixed_io_data->range_length);
+ acpi_os_printf (" Range length: %08X", fixed_io_data->range_length);
return;
}
@@ -329,7 +376,7 @@ acpi_rs_dump_fixed_io (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_vendor_specific (
union acpi_resource_data *data)
{
@@ -346,7 +393,7 @@ acpi_rs_dump_vendor_specific (
for (index = 0; index < vendor_data->length; index++) {
acpi_os_printf (" Byte %X: %08X\n",
- index, vendor_data->reserved[index]);
+ index, vendor_data->reserved[index]);
}
return;
@@ -365,7 +412,7 @@ acpi_rs_dump_vendor_specific (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_memory24 (
union acpi_resource_data *data)
{
@@ -378,21 +425,19 @@ acpi_rs_dump_memory24 (
acpi_os_printf ("24-Bit Memory Range Resource\n");
acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- memory24_data->read_write_attribute ?
- "/Write" : " only");
+ ACPI_READ_WRITE_MEMORY ==
+ memory24_data->read_write_attribute ?
+ "/Write" : " only");
acpi_os_printf (" Range minimum base: %08X\n",
- memory24_data->min_base_address);
+ memory24_data->min_base_address);
acpi_os_printf (" Range maximum base: %08X\n",
- memory24_data->max_base_address);
+ memory24_data->max_base_address);
- acpi_os_printf (" Alignment: %08X\n",
- memory24_data->alignment);
+ acpi_os_printf (" Alignment: %08X\n", memory24_data->alignment);
- acpi_os_printf (" Range length: %08X\n",
- memory24_data->range_length);
+ acpi_os_printf (" Range length: %08X\n", memory24_data->range_length);
return;
}
@@ -410,7 +455,7 @@ acpi_rs_dump_memory24 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_memory32 (
union acpi_resource_data *data)
{
@@ -423,21 +468,19 @@ acpi_rs_dump_memory32 (
acpi_os_printf ("32-Bit Memory Range Resource\n");
acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- memory32_data->read_write_attribute ?
- "/Write" : " only");
+ ACPI_READ_WRITE_MEMORY ==
+ memory32_data->read_write_attribute ?
+ "/Write" : " only");
acpi_os_printf (" Range minimum base: %08X\n",
- memory32_data->min_base_address);
+ memory32_data->min_base_address);
acpi_os_printf (" Range maximum base: %08X\n",
- memory32_data->max_base_address);
+ memory32_data->max_base_address);
- acpi_os_printf (" Alignment: %08X\n",
- memory32_data->alignment);
+ acpi_os_printf (" Alignment: %08X\n", memory32_data->alignment);
- acpi_os_printf (" Range length: %08X\n",
- memory32_data->range_length);
+ acpi_os_printf (" Range length: %08X\n", memory32_data->range_length);
return;
}
@@ -455,11 +498,12 @@ acpi_rs_dump_memory32 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_fixed_memory32 (
union acpi_resource_data *data)
{
- struct acpi_resource_fixed_mem32 *fixed_memory32_data = (struct acpi_resource_fixed_mem32 *) data;
+ struct acpi_resource_fixed_mem32 *fixed_memory32_data =
+ (struct acpi_resource_fixed_mem32 *) data;
ACPI_FUNCTION_ENTRY ();
@@ -468,15 +512,14 @@ acpi_rs_dump_fixed_memory32 (
acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n");
acpi_os_printf (" Read%s\n",
- ACPI_READ_WRITE_MEMORY ==
- fixed_memory32_data->read_write_attribute ?
- "/Write" : " Only");
+ ACPI_READ_WRITE_MEMORY ==
+ fixed_memory32_data->read_write_attribute ? "/Write" : " Only");
acpi_os_printf (" Range base address: %08X\n",
- fixed_memory32_data->range_base_address);
+ fixed_memory32_data->range_base_address);
acpi_os_printf (" Range length: %08X\n",
- fixed_memory32_data->range_length);
+ fixed_memory32_data->range_length);
return;
}
@@ -494,7 +537,7 @@ acpi_rs_dump_fixed_memory32 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_address16 (
union acpi_resource_data *data)
{
@@ -514,35 +557,30 @@ acpi_rs_dump_address16 (
switch (address16_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Noncacheable memory\n");
+ acpi_os_printf (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Cacheable memory\n");
+ acpi_os_printf (" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Write-combining memory\n");
+ acpi_os_printf (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Prefetchable memory\n");
+ acpi_os_printf (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid cache attribute\n");
+ acpi_os_printf (" Type Specific: Invalid cache attribute\n");
break;
}
acpi_os_printf (" Type Specific: Read%s\n",
ACPI_READ_WRITE_MEMORY ==
- address16_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ address16_data->attribute.memory.read_write_attribute ?
+ "/Write" : " Only");
break;
case ACPI_IO_RANGE:
@@ -551,30 +589,26 @@ acpi_rs_dump_address16 (
switch (address16_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "Non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: "
- "ISA and non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid range attribute\n");
+ acpi_os_printf (" Type Specific: Invalid range attribute\n");
break;
}
acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
- address16_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ address16_data->attribute.io.translation_attribute ?
+ "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
@@ -589,41 +623,42 @@ acpi_rs_dump_address16 (
}
acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address16_data->producer_consumer ?
+ ACPI_CONSUMER == address16_data->producer_consumer ?
"Consumer" : "Producer");
acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address16_data->decode ?
- "Subtractive" : "Positive");
+ ACPI_SUB_DECODE == address16_data->decode ?
+ "Subtractive" : "Positive");
acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
- "" : "not");
+ ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
+ "" : "not");
acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
- "" : "not");
+ ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
+ "" : "not");
acpi_os_printf (" Granularity: %08X\n",
- address16_data->granularity);
+ address16_data->granularity);
acpi_os_printf (" Address range min: %08X\n",
- address16_data->min_address_range);
+ address16_data->min_address_range);
acpi_os_printf (" Address range max: %08X\n",
- address16_data->max_address_range);
+ address16_data->max_address_range);
acpi_os_printf (" Address translation offset: %08X\n",
- address16_data->address_translation_offset);
+ address16_data->address_translation_offset);
acpi_os_printf (" Address Length: %08X\n",
- address16_data->address_length);
+ address16_data->address_length);
if (0xFF != address16_data->resource_source.index) {
acpi_os_printf (" Resource Source Index: %X\n",
- address16_data->resource_source.index);
+ address16_data->resource_source.index);
+
acpi_os_printf (" Resource Source: %s\n",
- address16_data->resource_source.string_ptr);
+ address16_data->resource_source.string_ptr);
}
return;
@@ -642,7 +677,7 @@ acpi_rs_dump_address16 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_address32 (
union acpi_resource_data *data)
{
@@ -661,35 +696,30 @@ acpi_rs_dump_address32 (
switch (address32_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Noncacheable memory\n");
+ acpi_os_printf (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Cacheable memory\n");
+ acpi_os_printf (" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Write-combining memory\n");
+ acpi_os_printf (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Prefetchable memory\n");
+ acpi_os_printf (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid cache attribute\n");
+ acpi_os_printf (" Type Specific: Invalid cache attribute\n");
break;
}
acpi_os_printf (" Type Specific: Read%s\n",
ACPI_READ_WRITE_MEMORY ==
- address32_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ address32_data->attribute.memory.read_write_attribute ?
+ "/Write" : " Only");
break;
case ACPI_IO_RANGE:
@@ -698,30 +728,26 @@ acpi_rs_dump_address32 (
switch (address32_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "Non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: "
- "ISA and non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid Range attribute");
+ acpi_os_printf (" Type Specific: Invalid Range attribute");
break;
}
acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
- address32_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ address32_data->attribute.io.translation_attribute ?
+ "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
@@ -731,46 +757,48 @@ acpi_rs_dump_address32 (
default:
- acpi_os_printf (" Resource Type: 0x%2.2X\n", address32_data->resource_type);
+ acpi_os_printf (" Resource Type: 0x%2.2X\n",
+ address32_data->resource_type);
break;
}
acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address32_data->producer_consumer ?
- "Consumer" : "Producer");
+ ACPI_CONSUMER == address32_data->producer_consumer ?
+ "Consumer" : "Producer");
acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address32_data->decode ?
- "Subtractive" : "Positive");
+ ACPI_SUB_DECODE == address32_data->decode ?
+ "Subtractive" : "Positive");
acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
- "" : "not ");
+ ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
+ "" : "not ");
acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
- "" : "not ");
+ ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
+ "" : "not ");
acpi_os_printf (" Granularity: %08X\n",
- address32_data->granularity);
+ address32_data->granularity);
acpi_os_printf (" Address range min: %08X\n",
- address32_data->min_address_range);
+ address32_data->min_address_range);
acpi_os_printf (" Address range max: %08X\n",
- address32_data->max_address_range);
+ address32_data->max_address_range);
acpi_os_printf (" Address translation offset: %08X\n",
- address32_data->address_translation_offset);
+ address32_data->address_translation_offset);
acpi_os_printf (" Address Length: %08X\n",
- address32_data->address_length);
+ address32_data->address_length);
if(0xFF != address32_data->resource_source.index) {
acpi_os_printf (" Resource Source Index: %X\n",
- address32_data->resource_source.index);
+ address32_data->resource_source.index);
+
acpi_os_printf (" Resource Source: %s\n",
- address32_data->resource_source.string_ptr);
+ address32_data->resource_source.string_ptr);
}
return;
@@ -789,7 +817,7 @@ acpi_rs_dump_address32 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_address64 (
union acpi_resource_data *data)
{
@@ -808,35 +836,30 @@ acpi_rs_dump_address64 (
switch (address64_data->attribute.memory.cache_attribute) {
case ACPI_NON_CACHEABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Noncacheable memory\n");
+ acpi_os_printf (" Type Specific: Noncacheable memory\n");
break;
case ACPI_CACHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Cacheable memory\n");
+ acpi_os_printf (" Type Specific: Cacheable memory\n");
break;
case ACPI_WRITE_COMBINING_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Write-combining memory\n");
+ acpi_os_printf (" Type Specific: Write-combining memory\n");
break;
case ACPI_PREFETCHABLE_MEMORY:
- acpi_os_printf (" Type Specific: "
- "Prefetchable memory\n");
+ acpi_os_printf (" Type Specific: Prefetchable memory\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid cache attribute\n");
+ acpi_os_printf (" Type Specific: Invalid cache attribute\n");
break;
}
acpi_os_printf (" Type Specific: Read%s\n",
ACPI_READ_WRITE_MEMORY ==
- address64_data->attribute.memory.read_write_attribute ?
- "/Write" : " Only");
+ address64_data->attribute.memory.read_write_attribute ?
+ "/Write" : " Only");
break;
case ACPI_IO_RANGE:
@@ -845,30 +868,26 @@ acpi_rs_dump_address64 (
switch (address64_data->attribute.io.range_attribute) {
case ACPI_NON_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "Non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: Non-ISA Io Addresses\n");
break;
case ACPI_ISA_ONLY_RANGES:
- acpi_os_printf (" Type Specific: "
- "ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA Io Addresses\n");
break;
case ACPI_ENTIRE_RANGE:
- acpi_os_printf (" Type Specific: "
- "ISA and non-ISA Io Addresses\n");
+ acpi_os_printf (" Type Specific: ISA and non-ISA Io Addresses\n");
break;
default:
- acpi_os_printf (" Type Specific: "
- "Invalid Range attribute");
+ acpi_os_printf (" Type Specific: Invalid Range attribute");
break;
}
acpi_os_printf (" Type Specific: %s Translation\n",
ACPI_SPARSE_TRANSLATION ==
- address64_data->attribute.io.translation_attribute ?
- "Sparse" : "Dense");
+ address64_data->attribute.io.translation_attribute ?
+ "Sparse" : "Dense");
break;
case ACPI_BUS_NUMBER_RANGE:
@@ -878,49 +897,51 @@ acpi_rs_dump_address64 (
default:
- acpi_os_printf (" Resource Type: 0x%2.2X\n", address64_data->resource_type);
+ acpi_os_printf (" Resource Type: 0x%2.2X\n",
+ address64_data->resource_type);
break;
}
acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == address64_data->producer_consumer ?
- "Consumer" : "Producer");
+ ACPI_CONSUMER == address64_data->producer_consumer ?
+ "Consumer" : "Producer");
acpi_os_printf (" %s decode\n",
- ACPI_SUB_DECODE == address64_data->decode ?
- "Subtractive" : "Positive");
+ ACPI_SUB_DECODE == address64_data->decode ?
+ "Subtractive" : "Positive");
acpi_os_printf (" Min address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
- "" : "not ");
+ ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
+ "" : "not ");
acpi_os_printf (" Max address is %s fixed\n",
- ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
- "" : "not ");
+ ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
+ "" : "not ");
acpi_os_printf (" Granularity: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->granularity));
+ ACPI_FORMAT_UINT64 (address64_data->granularity));
acpi_os_printf (" Address range min: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->min_address_range));
+ ACPI_FORMAT_UINT64 (address64_data->min_address_range));
acpi_os_printf (" Address range max: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->max_address_range));
+ ACPI_FORMAT_UINT64 (address64_data->max_address_range));
acpi_os_printf (" Address translation offset: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
+ ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
acpi_os_printf (" Address Length: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->address_length));
+ ACPI_FORMAT_UINT64 (address64_data->address_length));
acpi_os_printf (" Type Specific Attributes: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+ ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
if (0xFF != address64_data->resource_source.index) {
acpi_os_printf (" Resource Source Index: %X\n",
- address64_data->resource_source.index);
+ address64_data->resource_source.index);
+
acpi_os_printf (" Resource Source: %s\n",
- address64_data->resource_source.string_ptr);
+ address64_data->resource_source.string_ptr);
}
return;
@@ -939,7 +960,7 @@ acpi_rs_dump_address64 (
*
******************************************************************************/
-void
+static void
acpi_rs_dump_extended_irq (
union acpi_resource_data *data)
{
@@ -953,23 +974,22 @@ acpi_rs_dump_extended_irq (
acpi_os_printf ("Extended IRQ Resource\n");
acpi_os_printf (" Resource %s\n",
- ACPI_CONSUMER == ext_irq_data->producer_consumer ?
- "Consumer" : "Producer");
+ ACPI_CONSUMER == ext_irq_data->producer_consumer ?
+ "Consumer" : "Producer");
acpi_os_printf (" %s\n",
- ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
- "Level" : "Edge");
+ ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
+ "Level" : "Edge");
acpi_os_printf (" Active %s\n",
- ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
- "low" : "high");
+ ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
+ "low" : "high");
acpi_os_printf (" %s\n",
- ACPI_SHARED == ext_irq_data->shared_exclusive ?
- "Shared" : "Exclusive");
+ ACPI_SHARED == ext_irq_data->shared_exclusive ?
+ "Shared" : "Exclusive");
- acpi_os_printf (" Interrupts : %X ( ",
- ext_irq_data->number_of_interrupts);
+ acpi_os_printf (" Interrupts : %X ( ", ext_irq_data->number_of_interrupts);
for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
acpi_os_printf ("%X ", ext_irq_data->interrupts[index]);
@@ -979,9 +999,10 @@ acpi_rs_dump_extended_irq (
if(0xFF != ext_irq_data->resource_source.index) {
acpi_os_printf (" Resource Source Index: %X",
- ext_irq_data->resource_source.index);
+ ext_irq_data->resource_source.index);
+
acpi_os_printf (" Resource Source: %s",
- ext_irq_data->resource_source.string_ptr);
+ ext_irq_data->resource_source.string_ptr);
}
return;
@@ -992,7 +1013,7 @@ acpi_rs_dump_extended_irq (
*
* FUNCTION: acpi_rs_dump_resource_list
*
- * PARAMETERS: Data - pointer to the resource structure to dump.
+ * PARAMETERS: Resource - pointer to the resource structure to dump.
*
* RETURN: None
*
@@ -1096,7 +1117,7 @@ acpi_rs_dump_resource_list (
*
* FUNCTION: acpi_rs_dump_irq_list
*
- * PARAMETERS: Data - pointer to the routing table to dump.
+ * PARAMETERS: route_table - pointer to the routing table to dump.
*
* RETURN: None
*
@@ -1124,20 +1145,17 @@ acpi_rs_dump_irq_list (
acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
acpi_os_printf (" Address: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (prt_element->address));
+ ACPI_FORMAT_UINT64 (prt_element->address));
acpi_os_printf (" Pin: %X\n", prt_element->pin);
acpi_os_printf (" Source: %s\n", prt_element->source);
- acpi_os_printf (" source_index: %X\n",
- prt_element->source_index);
+ acpi_os_printf (" source_index: %X\n", prt_element->source_index);
buffer += prt_element->length;
-
prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
-
- if(0 == prt_element->length) {
+ if (0 == prt_element->length) {
done = TRUE;
}
}
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index 972c746d37e..23a4d149fac 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -81,67 +81,60 @@ acpi_rs_io_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16 = 0;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_io);
ACPI_FUNCTION_TRACE ("rs_io_resource");
- /*
- * The number of bytes consumed are Constant
- */
+ /* The number of bytes consumed are Constant */
+
*bytes_consumed = 8;
output_struct->id = ACPI_RSTYPE_IO;
- /*
- * Check Decode
- */
+ /* Check Decode */
+
buffer += 1;
temp8 = *buffer;
output_struct->data.io.io_decode = temp8 & 0x01;
- /*
- * Check min_base Address
- */
+ /* Check min_base Address */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
output_struct->data.io.min_base_address = temp16;
- /*
- * Check max_base Address
- */
+ /* Check max_base Address */
+
buffer += 2;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
output_struct->data.io.max_base_address = temp16;
- /*
- * Check Base alignment
- */
+ /* Check Base alignment */
+
buffer += 2;
temp8 = *buffer;
output_struct->data.io.alignment = temp8;
- /*
- * Check range_length
- */
+ /* Check range_length */
+
buffer += 1;
temp8 = *buffer;
output_struct->data.io.range_length = temp8;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -179,43 +172,39 @@ acpi_rs_fixed_io_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16 = 0;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_fixed_io);
ACPI_FUNCTION_TRACE ("rs_fixed_io_resource");
- /*
- * The number of bytes consumed are Constant
- */
+ /* The number of bytes consumed are Constant */
+
*bytes_consumed = 4;
output_struct->id = ACPI_RSTYPE_FIXED_IO;
- /*
- * Check Range Base Address
- */
+ /* Check Range Base Address */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
output_struct->data.fixed_io.base_address = temp16;
- /*
- * Check range_length
- */
+ /* Check range_length */
+
buffer += 2;
temp8 = *buffer;
output_struct->data.fixed_io.range_length = temp8;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -251,55 +240,48 @@ acpi_rs_io_stream (
ACPI_FUNCTION_TRACE ("rs_io_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x47;
buffer += 1;
- /*
- * Io Information Byte
- */
+ /* Io Information Byte */
+
temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
*buffer = temp8;
buffer += 1;
- /*
- * Set the Range minimum base address
- */
+ /* Set the Range minimum base address */
+
temp16 = (u16) linked_list->data.io.min_base_address;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the Range maximum base address
- */
+ /* Set the Range maximum base address */
+
temp16 = (u16) linked_list->data.io.max_base_address;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the base alignment
- */
+ /* Set the base alignment */
+
temp8 = (u8) linked_list->data.io.alignment;
*buffer = temp8;
buffer += 1;
- /*
- * Set the range length
- */
+ /* Set the range length */
+
temp8 = (u8) linked_list->data.io.range_length;
*buffer = temp8;
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -335,32 +317,28 @@ acpi_rs_fixed_io_stream (
ACPI_FUNCTION_TRACE ("rs_fixed_io_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x4B;
buffer += 1;
- /*
- * Set the Range base address
- */
+ /* Set the Range base address */
+
temp16 = (u16) linked_list->data.fixed_io.base_address;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the range length
- */
+ /* Set the range length */
+
temp8 = (u8) linked_list->data.fixed_io.range_length;
*buffer = temp8;
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -399,21 +377,20 @@ acpi_rs_dma_resource (
u8 temp8 = 0;
u8 index;
u8 i;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_dma);
ACPI_FUNCTION_TRACE ("rs_dma_resource");
- /*
- * The number of bytes consumed are Constant
- */
+ /* The number of bytes consumed are Constant */
+
*bytes_consumed = 3;
output_struct->id = ACPI_RSTYPE_DMA;
- /*
- * Point to the 8-bits of Byte 1
- */
+ /* Point to the 8-bits of Byte 1 */
+
buffer += 1;
temp8 = *buffer;
@@ -430,46 +407,40 @@ acpi_rs_dma_resource (
output_struct->data.dma.number_of_channels = i;
if (i > 0) {
- /*
- * Calculate the structure size based upon the number of interrupts
- */
+ /* Calculate the structure size based upon the number of interrupts */
+
struct_size += ((acpi_size) i - 1) * 4;
}
- /*
- * Point to Byte 2
- */
+ /* Point to Byte 2 */
+
buffer += 1;
temp8 = *buffer;
- /*
- * Check for transfer preference (Bits[1:0])
- */
+ /* Check for transfer preference (Bits[1:0]) */
+
output_struct->data.dma.transfer = temp8 & 0x03;
if (0x03 == output_struct->data.dma.transfer) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Invalid DMA.Transfer preference (3)\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
- /*
- * Get bus master preference (Bit[2])
- */
+ /* Get bus master preference (Bit[2]) */
+
output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
- /*
- * Get channel speed support (Bits[6:5])
- */
+ /* Get channel speed support (Bits[6:5]) */
+
output_struct->data.dma.type = (temp8 >> 5) & 0x03;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -506,16 +477,14 @@ acpi_rs_dma_stream (
ACPI_FUNCTION_TRACE ("rs_dma_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x2A;
buffer += 1;
temp8 = 0;
- /*
- * Loop through all of the Channels and set the mask bits
- */
+ /* Loop through all of the Channels and set the mask bits */
+
for (index = 0;
index < linked_list->data.dma.number_of_channels;
index++) {
@@ -526,9 +495,8 @@ acpi_rs_dma_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Set the DMA Info
- */
+ /* Set the DMA Info */
+
temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
temp8 |= (linked_list->data.dma.transfer & 0x03);
@@ -536,9 +504,8 @@ acpi_rs_dma_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index fd07a8702fb..8a2b630be45 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -83,7 +83,8 @@ acpi_rs_irq_resource (
u8 temp8 = 0;
u8 index;
u8 i;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_irq);
ACPI_FUNCTION_TRACE ("rs_irq_resource");
@@ -91,15 +92,14 @@ acpi_rs_irq_resource (
/*
* The number of bytes consumed are contained in the descriptor
- * (Bits:0-1)
+ * (Bits:0-1)
*/
temp8 = *buffer;
*bytes_consumed = (temp8 & 0x03) + 1;
output_struct->id = ACPI_RSTYPE_IRQ;
- /*
- * Point to the 16-bits of Bytes 1 and 2
- */
+ /* Point to the 16-bits of Bytes 1 and 2 */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -118,22 +118,19 @@ acpi_rs_irq_resource (
output_struct->data.irq.number_of_interrupts = i;
if (i > 0) {
- /*
- * Calculate the structure size based upon the number of interrupts
- */
+ /* Calculate the structure size based upon the number of interrupts */
+
struct_size += ((acpi_size) i - 1) * 4;
}
- /*
- * Point to Byte 3 if it is used
- */
+ /* Point to Byte 3 if it is used */
+
if (4 == *bytes_consumed) {
buffer += 2;
temp8 = *buffer;
- /*
- * Check for HE, LL interrupts
- */
+ /* Check for HE, LL interrupts */
+
switch (temp8 & 0x09) {
case 0x01: /* HE */
output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
@@ -152,13 +149,13 @@ acpi_rs_irq_resource (
* so 0x00 and 0x09 are illegal.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
+ "Invalid interrupt polarity/trigger in resource list, %X\n",
+ temp8));
return_ACPI_STATUS (AE_BAD_DATA);
}
- /*
- * Check for sharable
- */
+ /* Check for sharable */
+
output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
}
else {
@@ -171,14 +168,12 @@ acpi_rs_irq_resource (
output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -234,9 +229,8 @@ acpi_rs_irq_stream (
buffer += 1;
temp16 = 0;
- /*
- * Loop through all of the interrupts and set the mask bits
- */
+ /* Loop through all of the interrupts and set the mask bits */
+
for(index = 0;
index < linked_list->data.irq.number_of_interrupts;
index++) {
@@ -247,9 +241,8 @@ acpi_rs_irq_stream (
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the IRQ Info byte if needed.
- */
+ /* Set the IRQ Info byte if needed. */
+
if (IRqinfo_byte_needed) {
temp8 = 0;
temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
@@ -267,9 +260,8 @@ acpi_rs_irq_stream (
buffer += 1;
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -309,15 +301,15 @@ acpi_rs_extended_irq_resource (
u8 temp8 = 0;
u8 *temp_ptr;
u8 index;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_ext_irq);
ACPI_FUNCTION_TRACE ("rs_extended_irq_resource");
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -330,9 +322,8 @@ acpi_rs_extended_irq_resource (
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_EXT_IRQ;
- /*
- * Point to the Byte3
- */
+ /* Point to the Byte3 */
+
buffer += 2;
temp8 = *buffer;
@@ -347,21 +338,18 @@ acpi_rs_extended_irq_resource (
* - Edge/Level are defined opposite in the table vs the headers
*/
output_struct->data.extended_irq.edge_level =
- (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+ (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+
+ /* Check Interrupt Polarity */
- /*
- * Check Interrupt Polarity
- */
output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1;
- /*
- * Check for sharable
- */
+ /* Check for sharable */
+
output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
- /*
- * Point to Byte4 (IRQ Table length)
- */
+ /* Point to Byte4 (IRQ Table length) */
+
buffer += 1;
temp8 = *buffer;
@@ -379,14 +367,12 @@ acpi_rs_extended_irq_resource (
*/
struct_size += (temp8 - 1) * 4;
- /*
- * Point to Byte5 (First IRQ Number)
- */
+ /* Point to Byte5 (First IRQ Number) */
+
buffer += 1;
- /*
- * Cycle through every IRQ in the table
- */
+ /* Cycle through every IRQ in the table */
+
for (index = 0; index < temp8; index++) {
ACPI_MOVE_32_TO_32 (
&output_struct->data.extended_irq.interrupts[index], buffer);
@@ -407,7 +393,8 @@ acpi_rs_extended_irq_resource (
* we add 1 to the length.
*/
if (*bytes_consumed >
- ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) {
+ ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) +
+ (5 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
@@ -417,13 +404,13 @@ acpi_rs_extended_irq_resource (
buffer += 1;
- /*
- * Point the String pointer to the end of this structure.
- */
+ /* Point the String pointer to the end of this structure. */
+
output_struct->data.extended_irq.resource_source.string_ptr =
(char *)((char *) output_struct + struct_size);
- temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
+ temp_ptr = (u8 *)
+ output_struct->data.extended_irq.resource_source.string_ptr;
/* Copy the string into the buffer */
@@ -436,9 +423,8 @@ acpi_rs_extended_irq_resource (
index += 1;
}
- /*
- * Add the terminating null
- */
+ /* Add the terminating null */
+
*temp_ptr = 0x00;
output_struct->data.extended_irq.resource_source.string_length = index + 1;
@@ -456,14 +442,12 @@ acpi_rs_extended_irq_resource (
output_struct->data.extended_irq.resource_source.string_ptr = NULL;
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -501,21 +485,18 @@ acpi_rs_extended_irq_stream (
ACPI_FUNCTION_TRACE ("rs_extended_irq_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x89;
buffer += 1;
- /*
- * Set a pointer to the Length field - to be filled in later
- */
+ /* Set a pointer to the Length field - to be filled in later */
+
length_field = ACPI_CAST_PTR (u16, buffer);
buffer += 2;
- /*
- * Set the Interrupt vector flags
- */
+ /* Set the Interrupt vector flags */
+
temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
@@ -532,17 +513,15 @@ acpi_rs_extended_irq_stream (
temp8 |= 0x2;
}
- /*
- * Set the Interrupt Polarity
- */
+ /* Set the Interrupt Polarity */
+
temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2);
*buffer = temp8;
buffer += 1;
- /*
- * Set the Interrupt table length
- */
+ /* Set the Interrupt table length */
+
temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts;
*buffer = temp8;
@@ -555,18 +534,16 @@ acpi_rs_extended_irq_stream (
buffer += 4;
}
- /*
- * Resource Source Index and Resource Source are optional
- */
+ /* Resource Source Index and Resource Source are optional */
+
if (0 != linked_list->data.extended_irq.resource_source.string_length) {
*buffer = (u8) linked_list->data.extended_irq.resource_source.index;
buffer += 1;
temp_pointer = (char *) buffer;
- /*
- * Copy the string
- */
+ /* Copy the string */
+
ACPI_STRCPY (temp_pointer,
linked_list->data.extended_irq.resource_source.string_ptr);
@@ -574,12 +551,12 @@ acpi_rs_extended_irq_stream (
* Buffer needs to be set to the length of the sting + one for the
* terminating null
*/
- buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1);
+ buffer += (acpi_size) (ACPI_STRLEN (
+ linked_list->data.extended_irq.resource_source.string_ptr) + 1);
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
/*
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index e49c1e030f9..db7bcb4e60e 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -55,7 +55,7 @@
*
* PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor
*
- * RETURN: The Resource Type (Name) with no extraneous bits
+ * RETURN: The Resource Type with no extraneous bits
*
* DESCRIPTION: Extract the Resource Type/Name from the first byte of
* a resource descriptor.
@@ -70,28 +70,25 @@ acpi_rs_get_resource_type (
ACPI_FUNCTION_ENTRY ();
- /*
- * Determine if this is a small or large resource
- */
+ /* Determine if this is a small or large resource */
+
switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
case ACPI_RDESC_TYPE_SMALL:
- /*
- * Small Resource Type -- Only bits 6:3 are valid
- */
+ /* Small Resource Type -- Only bits 6:3 are valid */
+
return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
case ACPI_RDESC_TYPE_LARGE:
- /*
- * Large Resource Type -- All bits are valid
- */
+ /* Large Resource Type -- All bits are valid */
+
return (resource_start_byte);
default:
- /* No other types of resource descriptor */
+ /* Invalid type */
break;
}
@@ -135,9 +132,8 @@ acpi_rs_byte_stream_to_list (
while (bytes_parsed < byte_stream_buffer_length &&
!end_tag_processed) {
- /*
- * The next byte in the stream is the resource type
- */
+ /* The next byte in the stream is the resource type */
+
resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
switch (resource_type) {
@@ -299,28 +295,23 @@ acpi_rs_byte_stream_to_list (
return_ACPI_STATUS (status);
}
- /*
- * Update the return value and counter
- */
+ /* Update the return value and counter */
+
bytes_parsed += bytes_consumed;
- /*
- * Set the byte stream to point to the next resource
- */
+ /* Set the byte stream to point to the next resource */
+
byte_stream_buffer += bytes_consumed;
- /*
- * Set the Buffer to the next structure
- */
+ /* Set the Buffer to the next structure */
+
resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+ }
- } /* end while */
+ /* Check the reason for exiting the while loop */
- /*
- * Check the reason for exiting the while loop
- */
if (!end_tag_processed) {
return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
}
@@ -424,9 +415,8 @@ acpi_rs_list_to_byte_stream (
*/
status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
- /*
- * An End Tag indicates the end of the Resource Template
- */
+ /* An End Tag indicates the end of the Resource Template */
+
done = TRUE;
break;
@@ -488,27 +478,25 @@ acpi_rs_list_to_byte_stream (
default:
/*
* If we get here, everything is out of sync,
- * so exit with an error
+ * so exit with an error
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Invalid descriptor type (%X) in resource list\n",
linked_list->id));
status = AE_BAD_DATA;
break;
-
- } /* switch (linked_list->Id) */
+ }
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- /*
- * Set the Buffer to point to the open byte
- */
+ /* Set the Buffer to point to the open byte */
+
buffer += bytes_consumed;
- /*
- * Point to the next object
- */
+ /* Point to the next object */
+
linked_list = ACPI_PTR_ADD (struct acpi_resource,
linked_list, linked_list->length);
}
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index 7c935aecf07..91d0207f01a 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -81,15 +81,15 @@ acpi_rs_memory24_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16 = 0;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_mem24);
ACPI_FUNCTION_TRACE ("rs_memory24_resource");
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -97,48 +97,41 @@ acpi_rs_memory24_resource (
*bytes_consumed = (acpi_size) temp16 + 3;
output_struct->id = ACPI_RSTYPE_MEM24;
- /*
- * Check Byte 3 the Read/Write bit
- */
+ /* Check Byte 3 the Read/Write bit */
+
temp8 = *buffer;
buffer += 1;
output_struct->data.memory24.read_write_attribute = temp8 & 0x01;
- /*
- * Get min_base_address (Bytes 4-5)
- */
+ /* Get min_base_address (Bytes 4-5) */
+
ACPI_MOVE_16_TO_16 (&temp16, buffer);
buffer += 2;
output_struct->data.memory24.min_base_address = temp16;
- /*
- * Get max_base_address (Bytes 6-7)
- */
+ /* Get max_base_address (Bytes 6-7) */
+
ACPI_MOVE_16_TO_16 (&temp16, buffer);
buffer += 2;
output_struct->data.memory24.max_base_address = temp16;
- /*
- * Get Alignment (Bytes 8-9)
- */
+ /* Get Alignment (Bytes 8-9) */
+
ACPI_MOVE_16_TO_16 (&temp16, buffer);
buffer += 2;
output_struct->data.memory24.alignment = temp16;
- /*
- * Get range_length (Bytes 10-11)
- */
+ /* Get range_length (Bytes 10-11) */
+
ACPI_MOVE_16_TO_16 (&temp16, buffer);
output_struct->data.memory24.range_length = temp16;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -174,53 +167,45 @@ acpi_rs_memory24_stream (
ACPI_FUNCTION_TRACE ("rs_memory24_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x81;
buffer += 1;
- /*
- * The length field is static
- */
+ /* The length field is static */
+
temp16 = 0x09;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the Information Byte
- */
+ /* Set the Information Byte */
+
temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01);
*buffer = temp8;
buffer += 1;
- /*
- * Set the Range minimum base address
- */
+ /* Set the Range minimum base address */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address);
buffer += 2;
- /*
- * Set the Range maximum base address
- */
+ /* Set the Range maximum base address */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address);
buffer += 2;
- /*
- * Set the base alignment
- */
+ /* Set the base alignment */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment);
buffer += 2;
- /*
- * Set the range length
- */
+ /* Set the range length */
+
ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length);
buffer += 2;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -258,15 +243,15 @@ acpi_rs_memory32_range_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16 = 0;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_mem32);
ACPI_FUNCTION_TRACE ("rs_memory32_range_resource");
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -285,45 +270,38 @@ acpi_rs_memory32_range_resource (
* 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8)
*/
- /*
- * Check Byte 3 the Read/Write bit
- */
+ /* Check Byte 3 the Read/Write bit */
+
temp8 = *buffer;
buffer += 1;
output_struct->data.memory32.read_write_attribute = temp8 & 0x01;
- /*
- * Get min_base_address (Bytes 4-7)
- */
+ /* Get min_base_address (Bytes 4-7) */
+
ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer);
buffer += 4;
- /*
- * Get max_base_address (Bytes 8-11)
- */
+ /* Get max_base_address (Bytes 8-11) */
+
ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer);
buffer += 4;
- /*
- * Get Alignment (Bytes 12-15)
- */
+ /* Get Alignment (Bytes 12-15) */
+
ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer);
buffer += 4;
- /*
- * Get range_length (Bytes 16-19)
- */
+ /* Get range_length (Bytes 16-19) */
+
ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer);
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -361,15 +339,15 @@ acpi_rs_fixed_memory32_resource (
struct acpi_resource *output_struct = (void *) *output_buffer;
u16 temp16 = 0;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_fixed_mem32);
ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource");
- /*
- * Point past the Descriptor to get the number of bytes consumed
- */
+ /* Point past the Descriptor to get the number of bytes consumed */
+
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -378,32 +356,28 @@ acpi_rs_fixed_memory32_resource (
output_struct->id = ACPI_RSTYPE_FIXED_MEM32;
- /*
- * Check Byte 3 the Read/Write bit
- */
+ /* Check Byte 3 the Read/Write bit */
+
temp8 = *buffer;
buffer += 1;
output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01;
- /*
- * Get range_base_address (Bytes 4-7)
- */
- ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, buffer);
+ /* Get range_base_address (Bytes 4-7) */
+
+ ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address,
+ buffer);
buffer += 4;
- /*
- * Get range_length (Bytes 8-11)
- */
+ /* Get range_length (Bytes 8-11) */
+
ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer);
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -439,54 +413,46 @@ acpi_rs_memory32_range_stream (
ACPI_FUNCTION_TRACE ("rs_memory32_range_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x85;
buffer += 1;
- /*
- * The length field is static
- */
+ /* The length field is static */
+
temp16 = 0x11;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the Information Byte
- */
+ /* Set the Information Byte */
+
temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01);
*buffer = temp8;
buffer += 1;
- /*
- * Set the Range minimum base address
- */
+ /* Set the Range minimum base address */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address);
buffer += 4;
- /*
- * Set the Range maximum base address
- */
+ /* Set the Range maximum base address */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address);
buffer += 4;
- /*
- * Set the base alignment
- */
+ /* Set the base alignment */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment);
buffer += 4;
- /*
- * Set the range length
- */
+ /* Set the range length */
+
ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length);
buffer += 4;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -522,44 +488,38 @@ acpi_rs_fixed_memory32_stream (
ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x86;
buffer += 1;
- /*
- * The length field is static
- */
+ /* The length field is static */
+
temp16 = 0x09;
ACPI_MOVE_16_TO_16 (buffer, &temp16);
buffer += 2;
- /*
- * Set the Information Byte
- */
+ /* Set the Information Byte */
+
temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
*buffer = temp8;
buffer += 1;
- /*
- * Set the Range base address
- */
+ /* Set the Range base address */
+
ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.fixed_memory32.range_base_address);
+ &linked_list->data.fixed_memory32.range_base_address);
buffer += 4;
- /*
- * Set the range length
- */
+ /* Set the range length */
+
ACPI_MOVE_32_TO_32 (buffer,
- &linked_list->data.fixed_memory32.range_length);
+ &linked_list->data.fixed_memory32.range_length);
buffer += 4;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index d16be44b5df..a1f1741f0d8 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -84,24 +84,20 @@ acpi_rs_end_tag_resource (
ACPI_FUNCTION_TRACE ("rs_end_tag_resource");
- /*
- * The number of bytes consumed is static
- */
+ /* The number of bytes consumed is static */
+
*bytes_consumed = 2;
- /*
- * Fill out the structure
- */
+ /* Fill out the structure */
+
output_struct->id = ACPI_RSTYPE_END_TAG;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = 0;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -136,9 +132,8 @@ acpi_rs_end_tag_stream (
ACPI_FUNCTION_TRACE ("rs_end_tag_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x79;
buffer += 1;
@@ -151,9 +146,8 @@ acpi_rs_end_tag_stream (
*buffer = temp8;
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -192,21 +186,20 @@ acpi_rs_vendor_resource (
u16 temp16 = 0;
u8 temp8 = 0;
u8 index;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_vendor);
ACPI_FUNCTION_TRACE ("rs_vendor_resource");
- /*
- * Dereference the Descriptor to find if this is a large or small item.
- */
+ /* Dereference the Descriptor to find if this is a large or small item. */
+
temp8 = *buffer;
if (temp8 & 0x80) {
- /*
- * Large Item, point to the length field
- */
+ /* Large Item, point to the length field */
+
buffer += 1;
/* Dereference */
@@ -222,9 +215,8 @@ acpi_rs_vendor_resource (
buffer += 2;
}
else {
- /*
- * Small Item, dereference the size
- */
+ /* Small Item, dereference the size */
+
temp16 = (u8)(*buffer & 0x07);
/* Calculate bytes consumed */
@@ -251,14 +243,12 @@ acpi_rs_vendor_resource (
*/
struct_size += ACPI_ROUND_UP_to_32_bITS (temp16);
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -295,13 +285,11 @@ acpi_rs_vendor_stream (
ACPI_FUNCTION_TRACE ("rs_vendor_stream");
- /*
- * Dereference the length to find if this is a large or small item.
- */
+ /* Dereference the length to find if this is a large or small item. */
+
if(linked_list->data.vendor_specific.length > 7) {
- /*
- * Large Item, Set the descriptor field and length bytes
- */
+ /* Large Item, Set the descriptor field and length bytes */
+
*buffer = 0x84;
buffer += 1;
@@ -311,9 +299,8 @@ acpi_rs_vendor_stream (
buffer += 2;
}
else {
- /*
- * Small Item, Set the descriptor field
- */
+ /* Small Item, Set the descriptor field */
+
temp8 = 0x70;
temp8 |= (u8) linked_list->data.vendor_specific.length;
@@ -321,9 +308,8 @@ acpi_rs_vendor_stream (
buffer += 1;
}
- /*
- * Loop through all of the Vendor Specific fields
- */
+ /* Loop through all of the Vendor Specific fields */
+
for (index = 0; index < linked_list->data.vendor_specific.length; index++) {
temp8 = linked_list->data.vendor_specific.reserved[index];
@@ -331,9 +317,8 @@ acpi_rs_vendor_stream (
buffer += 1;
}
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -370,40 +355,37 @@ acpi_rs_start_depend_fns_resource (
u8 *buffer = byte_stream_buffer;
struct acpi_resource *output_struct = (void *) *output_buffer;
u8 temp8 = 0;
- acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
+ acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
+ struct acpi_resource_start_dpf);
ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource");
- /*
- * The number of bytes consumed are contained in the descriptor (Bits:0-1)
- */
+ /* The number of bytes consumed are found in the descriptor (Bits:0-1) */
+
temp8 = *buffer;
*bytes_consumed = (temp8 & 0x01) + 1;
output_struct->id = ACPI_RSTYPE_START_DPF;
- /*
- * Point to Byte 1 if it is used
- */
+ /* Point to Byte 1 if it is used */
+
if (2 == *bytes_consumed) {
buffer += 1;
temp8 = *buffer;
- /*
- * Check Compatibility priority
- */
+ /* Check Compatibility priority */
+
output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
if (3 == output_struct->data.start_dpf.compatibility_priority) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
}
- /*
- * Check Performance/Robustness preference
- */
+ /* Check Performance/Robustness preference */
+
output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
if (3 == output_struct->data.start_dpf.performance_robustness) {
@@ -412,20 +394,18 @@ acpi_rs_start_depend_fns_resource (
}
else {
output_struct->data.start_dpf.compatibility_priority =
- ACPI_ACCEPTABLE_CONFIGURATION;
+ ACPI_ACCEPTABLE_CONFIGURATION;
output_struct->data.start_dpf.performance_robustness =
- ACPI_ACCEPTABLE_CONFIGURATION;
+ ACPI_ACCEPTABLE_CONFIGURATION;
}
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -466,24 +446,20 @@ acpi_rs_end_depend_fns_resource (
ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource");
- /*
- * The number of bytes consumed is static
- */
+ /* The number of bytes consumed is static */
+
*bytes_consumed = 1;
- /*
- * Fill out the structure
- */
+ /* Fill out the structure */
+
output_struct->id = ACPI_RSTYPE_END_DPF;
- /*
- * Set the Length parameter
- */
+ /* Set the Length parameter */
+
output_struct->length = (u32) struct_size;
- /*
- * Return the final size of the structure
- */
+ /* Return the final size of the structure */
+
*structure_size = struct_size;
return_ACPI_STATUS (AE_OK);
}
@@ -533,9 +509,8 @@ acpi_rs_start_depend_fns_stream (
*buffer = 0x31;
buffer += 1;
- /*
- * Set the Priority Byte Definition
- */
+ /* Set the Priority Byte Definition */
+
temp8 = 0;
temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
0x03) << 2);
@@ -546,9 +521,8 @@ acpi_rs_start_depend_fns_stream (
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
@@ -582,15 +556,13 @@ acpi_rs_end_depend_fns_stream (
ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream");
- /*
- * The descriptor field is static
- */
+ /* The descriptor field is static */
+
*buffer = 0x38;
buffer += 1;
- /*
- * Return the number of bytes consumed in this operation
- */
+ /* Return the number of bytes consumed in this operation */
+
*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
return_ACPI_STATUS (AE_OK);
}
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index ee9ce13c053..700cf7d65d7 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -83,10 +83,10 @@ acpi_rs_get_prt_method_data (
/* Parameters guaranteed valid by caller */
- /*
- * Execute the method, no parameters
- */
- status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc);
+ /* Execute the method, no parameters */
+
+ status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRT,
+ ACPI_BTYPE_PACKAGE, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -136,10 +136,10 @@ acpi_rs_get_crs_method_data (
/* Parameters guaranteed valid by caller */
- /*
- * Execute the method, no parameters
- */
- status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc);
+ /* Execute the method, no parameters */
+
+ status = acpi_ut_evaluate_object (handle, METHOD_NAME__CRS,
+ ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -175,6 +175,7 @@ acpi_rs_get_crs_method_data (
* and the contents of the callers buffer is undefined.
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_rs_get_prs_method_data (
@@ -190,10 +191,10 @@ acpi_rs_get_prs_method_data (
/* Parameters guaranteed valid by caller */
- /*
- * Execute the method, no parameters
- */
- status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc);
+ /* Execute the method, no parameters */
+
+ status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRS,
+ ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -218,6 +219,7 @@ acpi_rs_get_prs_method_data (
* FUNCTION: acpi_rs_get_method_data
*
* PARAMETERS: Handle - a handle to the containing object
+ * Path - Path to method, relative to Handle
* ret_buffer - a pointer to a buffer structure for the
* results
*
@@ -246,9 +248,8 @@ acpi_rs_get_method_data (
/* Parameters guaranteed valid by caller */
- /*
- * Execute the method, no parameters
- */
+ /* Execute the method, no parameters */
+
status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
@@ -314,18 +315,16 @@ acpi_rs_set_srs_method_data (
return_ACPI_STATUS (status);
}
- /*
- * Init the param object
- */
+ /* Init the param object */
+
params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
if (!params[0]) {
acpi_os_free (buffer.pointer);
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /*
- * Set up the parameter object
- */
+ /* Set up the parameter object */
+
params[0]->buffer.length = (u32) buffer.length;
params[0]->buffer.pointer = buffer.pointer;
params[0]->common.flags = AOPOBJ_DATA_VALID;
@@ -335,10 +334,9 @@ acpi_rs_set_srs_method_data (
info.parameters = params;
info.parameter_type = ACPI_PARAM_ARGS;
- /*
- * Execute the method, no return value
- */
- status = acpi_ns_evaluate_relative ("_SRS", &info);
+ /* Execute the method, no return value */
+
+ status = acpi_ns_evaluate_relative (METHOD_NAME__SRS, &info);
if (ACPI_SUCCESS (status)) {
/* Delete any return object (especially if implicit_return is enabled) */
@@ -347,9 +345,8 @@ acpi_rs_set_srs_method_data (
}
}
- /*
- * Clean up and return the status from acpi_ns_evaluate_relative
- */
+ /* Clean up and return the status from acpi_ns_evaluate_relative */
+
acpi_ut_remove_reference (params[0]);
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index a9cdcbeb343..83c944b8b09 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -49,6 +49,23 @@
#define _COMPONENT ACPI_RESOURCES
ACPI_MODULE_NAME ("rsxface")
+/* Local macros for 16,32-bit to 64-bit conversion */
+
+#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
+#define ACPI_COPY_ADDRESS(out, in) \
+ ACPI_COPY_FIELD(out, in, resource_type); \
+ ACPI_COPY_FIELD(out, in, producer_consumer); \
+ ACPI_COPY_FIELD(out, in, decode); \
+ ACPI_COPY_FIELD(out, in, min_address_fixed); \
+ ACPI_COPY_FIELD(out, in, max_address_fixed); \
+ ACPI_COPY_FIELD(out, in, attribute); \
+ ACPI_COPY_FIELD(out, in, granularity); \
+ ACPI_COPY_FIELD(out, in, min_address_range); \
+ ACPI_COPY_FIELD(out, in, max_address_range); \
+ ACPI_COPY_FIELD(out, in, address_translation_offset); \
+ ACPI_COPY_FIELD(out, in, address_length); \
+ ACPI_COPY_FIELD(out, in, resource_source);
+
/*******************************************************************************
*
@@ -180,6 +197,7 @@ EXPORT_SYMBOL(acpi_get_current_resources);
* and the value of ret_buffer is undefined.
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_get_possible_resources (
@@ -346,9 +364,8 @@ acpi_set_current_resources (
ACPI_FUNCTION_TRACE ("acpi_set_current_resources");
- /*
- * Must have a valid handle and buffer
- */
+ /* Must have a valid handle and buffer */
+
if ((!device_handle) ||
(!in_buffer) ||
(!in_buffer->pointer) ||
@@ -362,21 +379,6 @@ acpi_set_current_resources (
EXPORT_SYMBOL(acpi_set_current_resources);
-#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
-#define ACPI_COPY_ADDRESS(out, in) \
- ACPI_COPY_FIELD(out, in, resource_type); \
- ACPI_COPY_FIELD(out, in, producer_consumer); \
- ACPI_COPY_FIELD(out, in, decode); \
- ACPI_COPY_FIELD(out, in, min_address_fixed); \
- ACPI_COPY_FIELD(out, in, max_address_fixed); \
- ACPI_COPY_FIELD(out, in, attribute); \
- ACPI_COPY_FIELD(out, in, granularity); \
- ACPI_COPY_FIELD(out, in, min_address_range); \
- ACPI_COPY_FIELD(out, in, max_address_range); \
- ACPI_COPY_FIELD(out, in, address_translation_offset); \
- ACPI_COPY_FIELD(out, in, address_length); \
- ACPI_COPY_FIELD(out, in, resource_source);
-
/******************************************************************************
*
* FUNCTION: acpi_resource_to_address64
@@ -408,14 +410,14 @@ acpi_resource_to_address64 (
case ACPI_RSTYPE_ADDRESS16:
address16 = (struct acpi_resource_address16 *) &resource->data;
- ACPI_COPY_ADDRESS(out, address16);
+ ACPI_COPY_ADDRESS (out, address16);
break;
case ACPI_RSTYPE_ADDRESS32:
address32 = (struct acpi_resource_address32 *) &resource->data;
- ACPI_COPY_ADDRESS(out, address32);
+ ACPI_COPY_ADDRESS (out, address32);
break;
@@ -434,4 +436,3 @@ acpi_resource_to_address64 (
return (AE_OK);
}
EXPORT_SYMBOL(acpi_resource_to_address64);
-
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 337d49b5564..cbcda30c172 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1061,13 +1061,15 @@ acpi_add_single_object (
/*
* Status
* ------
- * See if the device is present. We always assume that non-Device()
- * objects (e.g. thermal zones, power resources, processors, etc.) are
- * present, functioning, etc. (at least when parent object is present).
- * Note that _STA has a different meaning for some objects (e.g.
- * power resources) so we need to be careful how we use it.
+ * See if the device is present. We always assume that non-Device
+ * and non-Processor objects (e.g. thermal zones, power resources,
+ * etc.) are present, functioning, etc. (at least when parent object
+ * is present). Note that _STA has a different meaning for some
+ * objects (e.g. power resources) so we need to be careful how we use
+ * it.
*/
switch (type) {
+ case ACPI_BUS_TYPE_PROCESSOR:
case ACPI_BUS_TYPE_DEVICE:
result = acpi_bus_get_status(device);
if (ACPI_FAILURE(result) || !device->status.present) {
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 0a5d2a94131..7249ba2b7a2 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -1,6 +1,7 @@
/*
* sleep.c - ACPI sleep support.
*
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
* Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
* Copyright (c) 2000-2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
@@ -14,7 +15,6 @@
#include <linux/dmi.h>
#include <linux/device.h>
#include <linux/suspend.h>
-#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include "sleep.h"
@@ -27,10 +27,11 @@ extern void do_suspend_lowlevel_s4bios(void);
extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = {
- [PM_SUSPEND_ON] = ACPI_STATE_S0,
- [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
- [PM_SUSPEND_MEM] = ACPI_STATE_S3,
- [PM_SUSPEND_DISK] = ACPI_STATE_S4,
+ [PM_SUSPEND_ON] = ACPI_STATE_S0,
+ [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
+ [PM_SUSPEND_MEM] = ACPI_STATE_S3,
+ [PM_SUSPEND_DISK] = ACPI_STATE_S4,
+ [PM_SUSPEND_MAX] = ACPI_STATE_S5
};
static int init_8259A_after_S1;
@@ -44,30 +45,20 @@ static int init_8259A_after_S1;
* wakeup code to the waking vector.
*/
+extern int acpi_sleep_prepare(u32 acpi_state);
+extern void acpi_power_off(void);
+
static int acpi_pm_prepare(suspend_state_t pm_state)
{
u32 acpi_state = acpi_suspend_states[pm_state];
- if (!sleep_states[acpi_state])
+ if (!sleep_states[acpi_state]) {
+ printk("acpi_pm_prepare does not support %d \n", pm_state);
return -EPERM;
-
- /* do we have a wakeup address for S2 and S3? */
- /* Here, we support only S4BIOS, those we set the wakeup address */
- /* S4OS is only supported for now via swsusp.. */
- if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
- if (!acpi_wakeup_address)
- return -EFAULT;
- acpi_set_firmware_waking_vector(
- (acpi_physical_address) virt_to_phys(
- (void *)acpi_wakeup_address));
}
- ACPI_FLUSH_CPU_CACHE();
- acpi_enable_wakeup_device_prep(acpi_state);
- acpi_enter_sleep_state_prep(acpi_state);
- return 0;
+ return acpi_sleep_prepare(acpi_state);
}
-
/**
* acpi_pm_enter - Actually enter a sleep state.
* @pm_state: State we're entering.
@@ -92,11 +83,9 @@ static int acpi_pm_enter(suspend_state_t pm_state)
return error;
}
-
local_irq_save(flags);
acpi_enable_wakeup_device(acpi_state);
- switch (pm_state)
- {
+ switch (pm_state) {
case PM_SUSPEND_STANDBY:
barrier();
status = acpi_enter_sleep_state(acpi_state);
@@ -112,6 +101,10 @@ static int acpi_pm_enter(suspend_state_t pm_state)
else
do_suspend_lowlevel_s4bios();
break;
+ case PM_SUSPEND_MAX:
+ acpi_power_off();
+ break;
+
default:
return -EINVAL;
}
@@ -126,11 +119,9 @@ static int acpi_pm_enter(suspend_state_t pm_state)
if (pm_state > PM_SUSPEND_STANDBY)
acpi_restore_state_mem();
-
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
-
/**
* acpi_pm_finish - Finish up suspend sequence.
* @pm_state: State we're coming out of.
@@ -156,27 +147,26 @@ static int acpi_pm_finish(suspend_state_t pm_state)
return 0;
}
-
int acpi_suspend(u32 acpi_state)
{
suspend_state_t states[] = {
- [1] = PM_SUSPEND_STANDBY,
- [3] = PM_SUSPEND_MEM,
- [4] = PM_SUSPEND_DISK,
+ [1] = PM_SUSPEND_STANDBY,
+ [3] = PM_SUSPEND_MEM,
+ [4] = PM_SUSPEND_DISK,
+ [5] = PM_SUSPEND_MAX
};
- if (acpi_state <= 4 && states[acpi_state])
+ if (acpi_state < 6 && states[acpi_state])
return pm_suspend(states[acpi_state]);
return -EINVAL;
}
static struct pm_ops acpi_pm_ops = {
- .prepare = acpi_pm_prepare,
- .enter = acpi_pm_enter,
- .finish = acpi_pm_finish,
+ .prepare = acpi_pm_prepare,
+ .enter = acpi_pm_enter,
+ .finish = acpi_pm_finish,
};
-
/*
* Toshiba fails to preserve interrupts over S1, reinitialization
* of 8259 is needed after S1 resume.
@@ -190,16 +180,16 @@ static int __init init_ints_after_s1(struct dmi_system_id *d)
static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
{
- .callback = init_ints_after_s1,
- .ident = "Toshiba Satellite 4030cdt",
- .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), },
- },
- { },
+ .callback = init_ints_after_s1,
+ .ident = "Toshiba Satellite 4030cdt",
+ .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
+ },
+ {},
};
static int __init acpi_sleep_init(void)
{
- int i = 0;
+ int i = 0;
dmi_check_system(acpisleep_dmi_table);
@@ -207,7 +197,7 @@ static int __init acpi_sleep_init(void)
return 0;
printk(KERN_INFO PREFIX "(supports");
- for (i=0; i < ACPI_S_STATE_COUNT; i++) {
+ for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
acpi_status status;
u8 type_a, type_b;
status = acpi_get_sleep_type_data(i, &type_a, &type_b);
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index da237754ded..1fc86e6b5ab 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -3,35 +3,100 @@
*
* AKA S5, but it is independent of whether or not the kernel supports
* any other sleep support in the system.
+ *
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *
+ * This file is released under the GPLv2.
*/
#include <linux/pm.h>
#include <linux/init.h>
#include <acpi/acpi_bus.h>
#include <linux/sched.h>
+#include <linux/sysdev.h>
+#include <asm/io.h>
#include "sleep.h"
-static void
-acpi_power_off (void)
+int acpi_sleep_prepare(u32 acpi_state)
+{
+ /* Flag to do not allow second time invocation for S5 state */
+ static int shutdown_prepared = 0;
+#ifdef CONFIG_ACPI_SLEEP
+ /* do we have a wakeup address for S2 and S3? */
+ /* Here, we support only S4BIOS, those we set the wakeup address */
+ /* S4OS is only supported for now via swsusp.. */
+ if (acpi_state == ACPI_STATE_S3 || acpi_state == ACPI_STATE_S4) {
+ if (!acpi_wakeup_address) {
+ return -EFAULT;
+ }
+ acpi_set_firmware_waking_vector((acpi_physical_address)
+ virt_to_phys((void *)
+ acpi_wakeup_address));
+
+ }
+ ACPI_FLUSH_CPU_CACHE();
+ acpi_enable_wakeup_device_prep(acpi_state);
+#endif
+ if (acpi_state == ACPI_STATE_S5) {
+ /* Check if we were already called */
+ if (shutdown_prepared)
+ return 0;
+ acpi_wakeup_gpe_poweroff_prepare();
+ shutdown_prepared = 1;
+ }
+ acpi_enter_sleep_state_prep(acpi_state);
+ return 0;
+}
+
+void acpi_power_off(void)
{
- printk("%s called\n",__FUNCTION__);
+ printk("%s called\n", __FUNCTION__);
+ acpi_sleep_prepare(ACPI_STATE_S5);
+ local_irq_disable();
/* Some SMP machines only can poweroff in boot CPU */
set_cpus_allowed(current, cpumask_of_cpu(0));
- acpi_wakeup_gpe_poweroff_prepare();
- acpi_enter_sleep_state_prep(ACPI_STATE_S5);
- ACPI_DISABLE_IRQS();
acpi_enter_sleep_state(ACPI_STATE_S5);
}
+#ifdef CONFIG_PM
+
+static int acpi_shutdown(struct sys_device *x)
+{
+ return acpi_sleep_prepare(ACPI_STATE_S5);
+}
+
+static struct sysdev_class acpi_sysclass = {
+ set_kset_name("acpi"),
+ .shutdown = acpi_shutdown
+};
+
+static struct sys_device device_acpi = {
+ .id = 0,
+ .cls = &acpi_sysclass,
+};
+
+#endif
+
static int acpi_poweroff_init(void)
{
if (!acpi_disabled) {
u8 type_a, type_b;
acpi_status status;
- status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
- if (ACPI_SUCCESS(status))
+ status =
+ acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
+ if (ACPI_SUCCESS(status)) {
pm_power_off = acpi_power_off;
+#ifdef CONFIG_PM
+ {
+ int error;
+ error = sysdev_class_register(&acpi_sysclass);
+ if (!error)
+ error = sysdev_register(&device_acpi);
+ return error;
+ }
+#endif
+ }
}
return 0;
}
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index fd7c5a0649a..1be99f0996d 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -13,13 +13,17 @@
#include "sleep.h"
+#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
#define ACPI_SYSTEM_FILE_SLEEP "sleep"
+#endif
+
#define ACPI_SYSTEM_FILE_ALARM "alarm"
#define ACPI_SYSTEM_FILE_WAKEUP_DEVICE "wakeup"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("sleep")
+#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
{
@@ -78,6 +82,7 @@ acpi_system_write_sleep (
Done:
return error ? error : count;
}
+#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{
@@ -452,6 +457,7 @@ static struct file_operations acpi_system_wakeup_device_fops = {
.release = single_release,
};
+#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
static struct file_operations acpi_system_sleep_fops = {
.open = acpi_system_sleep_open_fs,
.read = seq_read,
@@ -459,6 +465,7 @@ static struct file_operations acpi_system_sleep_fops = {
.llseek = seq_lseek,
.release = single_release,
};
+#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
static struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs,
@@ -484,11 +491,13 @@ static int acpi_sleep_proc_init(void)
if (acpi_disabled)
return 0;
+#ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP
/* 'sleep' [R/W]*/
entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_sleep_fops;
+#endif
/* 'alarm' [R/W] */
entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index 334327c1f66..92e0c31539b 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -50,6 +50,24 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbconvrt")
+/* Local prototypes */
+
+static void
+acpi_tb_init_generic_address (
+ struct acpi_generic_address *new_gas_struct,
+ u8 register_bit_width,
+ acpi_physical_address address);
+
+static void
+acpi_tb_convert_fadt1 (
+ struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev1 *original_fadt);
+
+static void
+acpi_tb_convert_fadt2 (
+ struct fadt_descriptor_rev2 *local_fadt,
+ struct fadt_descriptor_rev2 *original_fadt);
+
u8 acpi_fadt_is_v1;
EXPORT_SYMBOL(acpi_fadt_is_v1);
@@ -142,11 +160,13 @@ acpi_tb_convert_to_xsdt (
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
if (acpi_gbl_RSDP->revision < 2) {
ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
- (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]);
+ (ACPI_CAST_PTR (struct rsdt_descriptor_rev1,
+ table_info->pointer))->table_offset_entry[i]);
}
else {
new_table->table_offset_entry[i] =
- (ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i];
+ (ACPI_CAST_PTR (XSDT_DESCRIPTOR,
+ table_info->pointer))->table_offset_entry[i];
}
}
@@ -164,7 +184,7 @@ acpi_tb_convert_to_xsdt (
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_tb_init_generic_address
*
@@ -201,7 +221,7 @@ acpi_tb_init_generic_address (
* PARAMETERS: local_fadt - Pointer to new FADT
* original_fadt - Pointer to old FADT
*
- * RETURN: Populates local_fadt
+ * RETURN: None, populates local_fadt
*
* DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
*
@@ -213,7 +233,6 @@ acpi_tb_convert_fadt1 (
struct fadt_descriptor_rev1 *original_fadt)
{
-
/* ACPI 1.0 FACS */
/* The BIOS stored FADT should agree with Revision 1.0 */
acpi_fadt_is_v1 = 1;
@@ -232,7 +251,8 @@ acpi_tb_convert_fadt1 (
ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
/*
- * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;)
+ * System Interrupt Model isn't used in ACPI 2.0
+ * (local_fadt->Reserved1 = 0;)
*/
/*
@@ -269,7 +289,8 @@ acpi_tb_convert_fadt1 (
* that immediately follows.
*/
ACPI_MEMCPY (&local_fadt->reset_register,
- &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+ &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus,
+ original_fadt))->reset_register,
sizeof (struct acpi_generic_address) + 1);
}
else {
@@ -304,7 +325,8 @@ acpi_tb_convert_fadt1 (
acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+ (acpi_physical_address)
+ (local_fadt->xpm1a_evt_blk.address +
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
/* PM1B is optional; leave null if not present */
@@ -312,7 +334,8 @@ acpi_tb_convert_fadt1 (
if (local_fadt->xpm1b_evt_blk.address) {
acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+ (acpi_physical_address)
+ (local_fadt->xpm1b_evt_blk.address +
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
}
}
@@ -325,7 +348,7 @@ acpi_tb_convert_fadt1 (
* PARAMETERS: local_fadt - Pointer to new FADT
* original_fadt - Pointer to old FADT
*
- * RETURN: Populates local_fadt
+ * RETURN: None, populates local_fadt
*
* DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
* Handles optional "X" fields.
@@ -348,7 +371,8 @@ acpi_tb_convert_fadt2 (
* is zero.
*/
if (!(local_fadt->xfirmware_ctrl)) {
- ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
+ ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl,
+ local_fadt->V1_firmware_ctrl);
}
if (!(local_fadt->Xdsdt)) {
@@ -357,32 +381,38 @@ acpi_tb_convert_fadt2 (
if (!(local_fadt->xpm1a_evt_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
- local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
}
if (!(local_fadt->xpm1b_evt_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
- local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
+ local_fadt->pm1_evt_len,
+ (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
}
if (!(local_fadt->xpm1a_cnt_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
- local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
}
if (!(local_fadt->xpm1b_cnt_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
- local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
+ local_fadt->pm1_cnt_len,
+ (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
}
if (!(local_fadt->xpm2_cnt_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
- local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
+ local_fadt->pm2_cnt_len,
+ (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
}
if (!(local_fadt->xpm_tmr_blk.address)) {
acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
- local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
+ local_fadt->pm_tm_len,
+ (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
}
if (!(local_fadt->xgpe0_blk.address)) {
@@ -399,18 +429,24 @@ acpi_tb_convert_fadt2 (
acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+ (acpi_physical_address)
+ (local_fadt->xpm1a_evt_blk.address +
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
- acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
+
+ acpi_gbl_xpm1a_enable.address_space_id =
+ local_fadt->xpm1a_evt_blk.address_space_id;
/* PM1B is optional; leave null if not present */
if (local_fadt->xpm1b_evt_blk.address) {
acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
- (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+ (acpi_physical_address)
+ (local_fadt->xpm1b_evt_blk.address +
ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
- acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
+
+ acpi_gbl_xpm1b_enable.address_space_id =
+ local_fadt->xpm1b_evt_blk.address_space_id;
}
}
@@ -432,7 +468,8 @@ acpi_tb_convert_fadt2 (
******************************************************************************/
acpi_status
-acpi_tb_convert_table_fadt (void)
+acpi_tb_convert_table_fadt (
+ void)
{
struct fadt_descriptor_rev2 *local_fadt;
struct acpi_table_desc *table_desc;
@@ -446,7 +483,8 @@ acpi_tb_convert_table_fadt (void)
* at least as long as the version 1.0 FADT
*/
if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
- ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length));
+ ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n",
+ acpi_gbl_FADT->length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
}
@@ -461,8 +499,9 @@ acpi_tb_convert_table_fadt (void)
if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
/* Length is too short to be a V2.0 table */
- ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
- acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
+ ACPI_REPORT_WARNING ((
+ "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
+ acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
}
@@ -478,9 +517,8 @@ acpi_tb_convert_table_fadt (void)
acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
}
- /*
- * Global FADT pointer will point to the new common V2.0 FADT
- */
+ /* Global FADT pointer will point to the new common V2.0 FADT */
+
acpi_gbl_FADT = local_fadt;
acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
@@ -508,7 +546,7 @@ acpi_tb_convert_table_fadt (void)
/*******************************************************************************
*
- * FUNCTION: acpi_tb_convert_table_facs
+ * FUNCTION: acpi_tb_build_common_facs
*
* PARAMETERS: table_info - Info for currently installed FACS
*
@@ -530,12 +568,14 @@ acpi_tb_build_common_facs (
/* Absolute minimum length is 24, but the ACPI spec says 64 */
if (acpi_gbl_FACS->length < 24) {
- ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length));
+ ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n",
+ acpi_gbl_FACS->length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
}
if (acpi_gbl_FACS->length < 64) {
- ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
+ ACPI_REPORT_WARNING ((
+ "FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
acpi_gbl_FACS->length));
}
@@ -548,7 +588,8 @@ acpi_tb_build_common_facs (
(!(acpi_gbl_FACS->xfirmware_waking_vector))) {
/* ACPI 1.0 FACS or short table or optional X_ field is zero */
- acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector));
+ acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64,
+ &(acpi_gbl_FACS->firmware_waking_vector));
acpi_gbl_common_fACS.vector_width = 32;
}
else {
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 896f3ddda62..4ab2aadc613 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -49,6 +49,19 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbget")
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_get_this_table (
+ struct acpi_pointer *address,
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info);
+
+static acpi_status
+acpi_tb_table_override (
+ struct acpi_table_header *header,
+ struct acpi_table_desc *table_info);
+
/*******************************************************************************
*
@@ -76,9 +89,8 @@ acpi_tb_get_table (
ACPI_FUNCTION_TRACE ("tb_get_table");
- /*
- * Get the header in order to get signature and table size
- */
+ /* Get the header in order to get signature and table size */
+
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
@@ -127,8 +139,8 @@ acpi_tb_get_table_header (
/*
- * Flags contains the current processor mode (Virtual or Physical addressing)
- * The pointer_type is either Logical or Physical
+ * Flags contains the current processor mode (Virtual or Physical
+ * addressing) The pointer_type is either Logical or Physical
*/
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
@@ -136,7 +148,8 @@ acpi_tb_get_table_header (
/* Pointer matches processor mode, copy the header */
- ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header));
+ ACPI_MEMCPY (return_header, address->pointer.logical,
+ sizeof (struct acpi_table_header));
break;
@@ -144,10 +157,11 @@ acpi_tb_get_table_header (
/* Create a logical address for the physical pointer*/
- status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
- (void *) &header);
+ status = acpi_os_map_memory (address->pointer.physical,
+ sizeof (struct acpi_table_header), (void *) &header);
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
+ ACPI_REPORT_ERROR ((
+ "Could not map memory at %8.8X%8.8X for length %X\n",
ACPI_FORMAT_UINT64 (address->pointer.physical),
sizeof (struct acpi_table_header)));
return_ACPI_STATUS (status);
@@ -210,9 +224,8 @@ acpi_tb_get_table_body (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /*
- * Attempt table override.
- */
+ /* Attempt table override. */
+
status = acpi_tb_table_override (header, table_info);
if (ACPI_SUCCESS (status)) {
/* Table was overridden by the host OS */
@@ -241,7 +254,7 @@ acpi_tb_get_table_body (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_table_override (
struct acpi_table_header *header,
struct acpi_table_desc *table_info)
@@ -315,7 +328,7 @@ acpi_tb_table_override (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_get_this_table (
struct acpi_pointer *address,
struct acpi_table_header *header,
@@ -330,8 +343,8 @@ acpi_tb_get_this_table (
/*
- * Flags contains the current processor mode (Virtual or Physical addressing)
- * The pointer_type is either Logical or Physical
+ * Flags contains the current processor mode (Virtual or Physical
+ * addressing) The pointer_type is either Logical or Physical
*/
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
@@ -341,7 +354,8 @@ acpi_tb_get_this_table (
full_table = ACPI_MEM_ALLOCATE (header->length);
if (!full_table) {
- ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
+ ACPI_REPORT_ERROR ((
+ "Could not allocate table memory for [%4.4s] length %X\n",
header->signature, header->length));
return_ACPI_STATUS (AE_NO_MEMORY);
}
@@ -362,12 +376,14 @@ acpi_tb_get_this_table (
* Just map the table's physical memory
* into our address space.
*/
- status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
- (void *) &full_table);
+ status = acpi_os_map_memory (address->pointer.physical,
+ (acpi_size) header->length, (void *) &full_table);
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
+ ACPI_REPORT_ERROR ((
+ "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
header->signature,
- ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
+ ACPI_FORMAT_UINT64 (address->pointer.physical),
+ header->length));
return (status);
}
@@ -465,9 +481,8 @@ acpi_tb_get_table_ptr (
return_ACPI_STATUS (AE_OK);
}
- /*
- * Check for instance out of range
- */
+ /* Check for instance out of range */
+
if (instance > acpi_gbl_table_lists[table_type].count) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
index adc4270988b..eea5b8cb5eb 100644
--- a/drivers/acpi/tables/tbgetall.c
+++ b/drivers/acpi/tables/tbgetall.c
@@ -49,6 +49,19 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbgetall")
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_get_primary_table (
+ struct acpi_pointer *address,
+ struct acpi_table_desc *table_info);
+
+static acpi_status
+acpi_tb_get_secondary_table (
+ struct acpi_pointer *address,
+ acpi_string signature,
+ struct acpi_table_desc *table_info);
+
/*******************************************************************************
*
@@ -63,7 +76,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_get_primary_table (
struct acpi_pointer *address,
struct acpi_table_desc *table_info)
@@ -81,9 +94,8 @@ acpi_tb_get_primary_table (
return_ACPI_STATUS (AE_OK);
}
- /*
- * Get the header in order to get signature and table size
- */
+ /* Get the header in order to get signature and table size */
+
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
@@ -130,7 +142,7 @@ acpi_tb_get_primary_table (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_get_secondary_table (
struct acpi_pointer *address,
acpi_string signature,
@@ -153,7 +165,8 @@ acpi_tb_get_secondary_table (
/* Signature must match request */
if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
- ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
+ ACPI_REPORT_ERROR ((
+ "Incorrect table signature - wanted [%s] found [%4.4s]\n",
signature, header.signature));
return_ACPI_STATUS (AE_BAD_SIGNATURE);
}
@@ -230,7 +243,8 @@ acpi_tb_get_required_tables (
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
/* Get the table address from the common internal XSDT */
- address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
+ address.pointer.value =
+ acpi_gbl_XSDT->table_offset_entry[i];
/*
* Get the tables needed by this subsystem (FADT and any SSDTs).
@@ -252,18 +266,18 @@ acpi_tb_get_required_tables (
}
/*
- * Convert the FADT to a common format. This allows earlier revisions of the
- * table to coexist with newer versions, using common access code.
+ * Convert the FADT to a common format. This allows earlier revisions of
+ * the table to coexist with newer versions, using common access code.
*/
status = acpi_tb_convert_table_fadt ();
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
+ ACPI_REPORT_ERROR ((
+ "Could not convert FADT to internal common format\n"));
return_ACPI_STATUS (status);
}
- /*
- * Get the FACS (Pointed to by the FADT)
- */
+ /* Get the FACS (Pointed to by the FADT) */
+
address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
@@ -282,9 +296,8 @@ acpi_tb_get_required_tables (
return_ACPI_STATUS (status);
}
- /*
- * Get/install the DSDT (Pointed to by the FADT)
- */
+ /* Get/install the DSDT (Pointed to by the FADT) */
+
address.pointer.value = acpi_gbl_FADT->Xdsdt;
status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 85d5bb01022..629b64c8193 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -49,6 +49,14 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbinstal")
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_match_signature (
+ char *signature,
+ struct acpi_table_desc *table_info,
+ u8 search_type);
+
/*******************************************************************************
*
@@ -56,6 +64,7 @@
*
* PARAMETERS: Signature - Table signature to match
* table_info - Return data
+ * search_type - Table type to match (primary/secondary)
*
* RETURN: Status
*
@@ -64,7 +73,7 @@
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_match_signature (
char *signature,
struct acpi_table_desc *table_info,
@@ -76,9 +85,8 @@ acpi_tb_match_signature (
ACPI_FUNCTION_TRACE ("tb_match_signature");
- /*
- * Search for a signature match among the known table types
- */
+ /* Search for a signature match among the known table types */
+
for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
if (!(acpi_gbl_table_data[i].flags & search_type)) {
continue;
@@ -161,6 +169,7 @@ acpi_tb_install_table (
* FUNCTION: acpi_tb_recognize_table
*
* PARAMETERS: table_info - Return value from acpi_tb_get_table_body
+ * search_type - Table type to match (primary/secondary)
*
* RETURN: Status
*
@@ -203,7 +212,8 @@ acpi_tb_recognize_table (
* This can be any one of many valid ACPI tables, it just isn't one of
* the tables that is consumed by the core subsystem
*/
- status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
+ status = acpi_tb_match_signature (table_header->signature,
+ table_info, search_type);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -253,9 +263,8 @@ acpi_tb_init_table_descriptor (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /*
- * Install the table into the global data structure
- */
+ /* Install the table into the global data structure */
+
list_head = &acpi_gbl_table_lists[table_type];
/*
@@ -316,7 +325,8 @@ acpi_tb_init_table_descriptor (
table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
table_desc->aml_length = (u32) (table_desc->length -
(u32) sizeof (struct acpi_table_header));
- table_desc->table_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE);
+ table_desc->table_id = acpi_ut_allocate_owner_id (
+ ACPI_OWNER_TYPE_TABLE);
table_desc->loaded_into_namespace = FALSE;
/*
@@ -349,7 +359,8 @@ acpi_tb_init_table_descriptor (
******************************************************************************/
void
-acpi_tb_delete_all_tables (void)
+acpi_tb_delete_all_tables (
+ void)
{
acpi_table_type type;
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index 9c6913238d5..b7ffe39c362 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -84,8 +84,9 @@ acpi_tb_verify_rsdp (
/*
* Obtain access to the RSDP structure
*/
- status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
- (void *) &rsdp);
+ status = acpi_os_map_memory (address->pointer.physical,
+ sizeof (struct rsdp_descriptor),
+ (void *) &rsdp);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -154,9 +155,9 @@ cleanup:
*
* FUNCTION: acpi_tb_get_rsdt_address
*
- * PARAMETERS: None
+ * PARAMETERS: out_address - Where the address is returned
*
- * RETURN: RSDT physical address
+ * RETURN: None, Address
*
* DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
* version of the RSDP
@@ -181,7 +182,8 @@ acpi_tb_get_rsdt_address (
out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
}
else {
- out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address;
+ out_address->pointer.value =
+ acpi_gbl_RSDP->xsdt_physical_address;
}
}
@@ -224,7 +226,8 @@ acpi_tb_validate_rsdt (
if (no_match) {
/* Invalid RSDT or XSDT signature */
- ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+ ACPI_REPORT_ERROR ((
+ "Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
@@ -282,6 +285,7 @@ acpi_tb_get_table_rsdt (
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
acpi_format_exception (status)));
+
return_ACPI_STATUS (status);
}
@@ -299,7 +303,8 @@ acpi_tb_get_table_rsdt (
/* Get the number of tables defined in the RSDT or XSDT */
- acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
+ acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP,
+ table_info.pointer);
/* Convert and/or copy to an XSDT structure */
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index fede5804c78..e69d01d443d 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -49,48 +49,14 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbutils")
+/* Local prototypes */
-/*******************************************************************************
- *
- * FUNCTION: acpi_tb_handle_to_object
- *
- * PARAMETERS: table_id - Id for which the function is searching
- * table_desc - Pointer to return the matching table
- * descriptor.
- *
- * RETURN: Search the tables to find one with a matching table_id and
- * return a pointer to that table descriptor.
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
+#ifdef ACPI_OBSOLETE_FUNCTIONS
acpi_status
acpi_tb_handle_to_object (
u16 table_id,
- struct acpi_table_desc **return_table_desc)
-{
- u32 i;
- struct acpi_table_desc *table_desc;
-
-
- ACPI_FUNCTION_NAME ("tb_handle_to_object");
-
-
- for (i = 0; i < ACPI_TABLE_MAX; i++) {
- table_desc = acpi_gbl_table_lists[i].next;
- while (table_desc) {
- if (table_desc->table_id == table_id) {
- *return_table_desc = table_desc;
- return (AE_OK);
- }
-
- table_desc = table_desc->next;
- }
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
- return (AE_BAD_PARAMETER);
-}
-#endif /* ACPI_FUTURE_USAGE */
+ struct acpi_table_desc **table_desc);
+#endif
/*******************************************************************************
@@ -128,6 +94,7 @@ acpi_tb_validate_table_header (
if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Cannot read table header at %p\n", table_header));
+
return (AE_BAD_ADDRESS);
}
@@ -141,6 +108,7 @@ acpi_tb_validate_table_header (
ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
(char *) &signature));
+
ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
return (AE_BAD_SIGNATURE);
}
@@ -154,6 +122,7 @@ acpi_tb_validate_table_header (
ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
(u32) table_header->length));
+
ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
return (AE_BAD_HEADER);
}
@@ -193,8 +162,10 @@ acpi_tb_verify_table_checksum (
/* Return the appropriate exception */
if (checksum) {
- ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
- table_header->signature, (u32) table_header->checksum, (u32) checksum));
+ ACPI_REPORT_WARNING ((
+ "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
+ table_header->signature, (u32) table_header->checksum,
+ (u32) checksum));
status = AE_BAD_CHECKSUM;
}
@@ -209,7 +180,7 @@ acpi_tb_verify_table_checksum (
* PARAMETERS: Buffer - Buffer to checksum
* Length - Size of the buffer
*
- * RETURNS 8 bit checksum of buffer
+ * RETURN: 8 bit checksum of buffer
*
* DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
*
@@ -238,3 +209,47 @@ acpi_tb_checksum (
}
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_handle_to_object
+ *
+ * PARAMETERS: table_id - Id for which the function is searching
+ * table_desc - Pointer to return the matching table
+ * descriptor.
+ *
+ * RETURN: Search the tables to find one with a matching table_id and
+ * return a pointer to that table descriptor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_handle_to_object (
+ u16 table_id,
+ struct acpi_table_desc **return_table_desc)
+{
+ u32 i;
+ struct acpi_table_desc *table_desc;
+
+
+ ACPI_FUNCTION_NAME ("tb_handle_to_object");
+
+
+ for (i = 0; i < ACPI_TABLE_MAX; i++) {
+ table_desc = acpi_gbl_table_lists[i].next;
+ while (table_desc) {
+ if (table_desc->table_id == table_id) {
+ *return_table_desc = table_desc;
+ return (AE_OK);
+ }
+
+ table_desc = table_desc->next;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
+ return (AE_BAD_PARAMETER);
+}
+#endif
+
+
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 7715043461c..0c0b9085dbe 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -67,7 +67,8 @@
******************************************************************************/
acpi_status
-acpi_load_tables (void)
+acpi_load_tables (
+ void)
{
struct acpi_pointer rsdp_address;
acpi_status status;
@@ -82,7 +83,7 @@ acpi_load_tables (void)
&rsdp_address);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n",
- acpi_format_exception (status)));
+ acpi_format_exception (status)));
goto error_exit;
}
@@ -93,7 +94,7 @@ acpi_load_tables (void)
status = acpi_tb_verify_rsdp (&rsdp_address);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n",
- acpi_format_exception (status)));
+ acpi_format_exception (status)));
goto error_exit;
}
@@ -102,7 +103,7 @@ acpi_load_tables (void)
status = acpi_tb_get_table_rsdt ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n",
- acpi_format_exception (status)));
+ acpi_format_exception (status)));
goto error_exit;
}
@@ -110,20 +111,20 @@ acpi_load_tables (void)
status = acpi_tb_get_required_tables ();
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
- acpi_format_exception (status)));
+ ACPI_REPORT_ERROR ((
+ "acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
+ acpi_format_exception (status)));
goto error_exit;
}
ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
-
/* Load the namespace from the tables */
status = acpi_ns_load_namespace ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n",
- acpi_format_exception (status)));
+ acpi_format_exception (status)));
goto error_exit;
}
@@ -139,7 +140,6 @@ error_exit:
#ifdef ACPI_FUTURE_USAGE
-
/*******************************************************************************
*
* FUNCTION: acpi_load_table
@@ -250,7 +250,6 @@ acpi_unload_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
-
/* Find all tables of the requested type */
table_desc = acpi_gbl_table_lists[table_type].next;
@@ -321,7 +320,6 @@ acpi_get_table_header (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
-
/* Get a pointer to the entire table */
status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
@@ -329,23 +327,20 @@ acpi_get_table_header (
return_ACPI_STATUS (status);
}
- /*
- * The function will return a NULL pointer if the table is not loaded
- */
+ /* The function will return a NULL pointer if the table is not loaded */
+
if (tbl_ptr == NULL) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
- /*
- * Copy the header to the caller's buffer
- */
+ /* Copy the header to the caller's buffer */
+
ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
- sizeof (struct acpi_table_header));
+ sizeof (struct acpi_table_header));
return_ACPI_STATUS (status);
}
-
#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
@@ -404,7 +399,6 @@ acpi_get_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
-
/* Get a pointer to the entire table */
status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
@@ -423,9 +417,8 @@ acpi_get_table (
/* Get the table length */
if (table_type == ACPI_TABLE_RSDP) {
- /*
- * RSD PTR is the only "table" without a header
- */
+ /* RSD PTR is the only "table" without a header */
+
table_length = sizeof (struct rsdp_descriptor);
}
else {
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index 6e8072ebbac..dc3c3f6a9f6 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -50,6 +50,18 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbxfroot")
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_find_rsdp (
+ struct acpi_table_desc *table_info,
+ u32 flags);
+
+static u8 *
+acpi_tb_scan_memory_for_rsdp (
+ u8 *start_address,
+ u32 length);
+
/*******************************************************************************
*
@@ -57,7 +69,8 @@
*
* PARAMETERS: Signature - String with ACPI table signature
* oem_id - String with the table OEM ID
- * oem_table_id - String with the OEM Table ID.
+ * oem_table_id - String with the OEM Table ID
+ * table_ptr - Where the table pointer is returned
*
* RETURN: Status
*
@@ -99,14 +112,13 @@ acpi_tb_find_table (
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
-
table = acpi_gbl_DSDT;
}
else {
/* Find the table */
status = acpi_get_firmware_table (signature, 1,
- ACPI_LOGICAL_ADDRESSING, &table);
+ ACPI_LOGICAL_ADDRESSING, &table);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -114,14 +126,19 @@ acpi_tb_find_table (
/* Check oem_id and oem_table_id */
- if ((oem_id[0] && ACPI_STRNCMP (
- oem_id, table->oem_id, sizeof (table->oem_id))) ||
+ if ((oem_id[0] && ACPI_STRNCMP (
+ oem_id, table->oem_id,
+ sizeof (table->oem_id))) ||
+
(oem_table_id[0] && ACPI_STRNCMP (
- oem_table_id, table->oem_table_id, sizeof (table->oem_table_id)))) {
+ oem_table_id, table->oem_table_id,
+ sizeof (table->oem_table_id)))) {
return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature));
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+ table->signature));
+
*table_ptr = table;
return_ACPI_STATUS (AE_OK);
}
@@ -191,8 +208,8 @@ acpi_get_firmware_table (
/* Map and validate the RSDP */
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
- (void *) &acpi_gbl_RSDP);
+ status = acpi_os_map_memory (address.pointer.physical,
+ sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -203,7 +220,8 @@ acpi_get_firmware_table (
/* The signature and checksum must both be correct */
- if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+ if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG,
+ sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
return_ACPI_STATUS (AE_BAD_SIGNATURE);
@@ -313,7 +331,8 @@ acpi_get_firmware_table (
cleanup:
- acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
+ acpi_os_unmap_memory (rsdt_info->pointer,
+ (acpi_size) rsdt_info->pointer->length);
ACPI_MEM_FREE (rsdt_info);
if (header) {
@@ -335,8 +354,8 @@ EXPORT_SYMBOL(acpi_get_firmware_table);
*
* FUNCTION: acpi_find_root_pointer
*
- * PARAMETERS: **rsdp_address - Where to place the RSDP address
- * Flags - Logical/Physical addressing
+ * PARAMETERS: Flags - Logical/Physical addressing
+ * rsdp_address - Where to place the RSDP address
*
* RETURN: Status, Physical address of the RSDP
*
@@ -363,6 +382,7 @@ acpi_find_root_pointer (
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"RSDP structure not found, %s Flags=%X\n",
acpi_format_exception (status), flags));
+
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
@@ -385,7 +405,7 @@ acpi_find_root_pointer (
*
******************************************************************************/
-u8 *
+static u8 *
acpi_tb_scan_memory_for_rsdp (
u8 *start_address,
u32 length)
@@ -406,7 +426,8 @@ acpi_tb_scan_memory_for_rsdp (
mem_rover += ACPI_RSDP_SCAN_STEP) {
/* The signature and checksum must both be correct */
- if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+ if (ACPI_STRNCMP ((char *) mem_rover,
+ RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) {
/* No signature match, keep looking */
continue;
@@ -450,7 +471,7 @@ acpi_tb_scan_memory_for_rsdp (
*
* FUNCTION: acpi_tb_find_rsdp
*
- * PARAMETERS: *table_info - Where the table info is returned
+ * PARAMETERS: table_info - Where the table info is returned
* Flags - Current memory mode (logical vs.
* physical addressing)
*
@@ -468,7 +489,7 @@ acpi_tb_scan_memory_for_rsdp (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_tb_find_rsdp (
struct acpi_table_desc *table_info,
u32 flags)
@@ -483,43 +504,49 @@ acpi_tb_find_rsdp (
/*
- * Scan supports either 1) Logical addressing or 2) Physical addressing
+ * Scan supports either logical addressing or physical addressing
*/
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- /*
- * 1a) Get the location of the EBDA
- */
- status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
- ACPI_EBDA_PTR_LENGTH,
- (void *) &table_ptr);
+ /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
+
+ status = acpi_os_map_memory (
+ (acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
+ ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
+
return_ACPI_STATUS (status);
}
ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
- physical_address <<= 4; /* Convert segment to physical address */
+
+ /* Convert segment part to physical address */
+
+ physical_address <<= 4;
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
/* EBDA present? */
if (physical_address > 0x400) {
/*
- * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+ * 1b) Search EBDA paragraphs (EBDa is required to be a
+ * minimum of 1_k length)
*/
- status = acpi_os_map_memory ((acpi_physical_address) physical_address,
- ACPI_EBDA_WINDOW_SIZE,
- (void *) &table_ptr);
+ status = acpi_os_map_memory (
+ (acpi_physical_address) physical_address,
+ ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
physical_address, ACPI_EBDA_WINDOW_SIZE));
+
return_ACPI_STATUS (status);
}
- mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+ mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr,
+ ACPI_EBDA_WINDOW_SIZE);
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
@@ -527,7 +554,8 @@ acpi_tb_find_rsdp (
physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
- table_info->physical_address = (acpi_physical_address) physical_address;
+ table_info->physical_address =
+ (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
@@ -535,13 +563,15 @@ acpi_tb_find_rsdp (
/*
* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
*/
- status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
- ACPI_HI_RSDP_WINDOW_SIZE,
- (void *) &table_ptr);
+ status = acpi_os_map_memory (
+ (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
+ ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr);
+
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not map memory at %8.8X for length %X\n",
ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
+
return_ACPI_STATUS (status);
}
@@ -551,9 +581,11 @@ acpi_tb_find_rsdp (
if (mem_rover) {
/* Found it, return the physical address */
- physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
+ physical_address =
+ ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
- table_info->physical_address = (acpi_physical_address) physical_address;
+ table_info->physical_address =
+ (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
@@ -562,9 +594,8 @@ acpi_tb_find_rsdp (
* Physical addressing
*/
else {
- /*
- * 1a) Get the location of the EBDA
- */
+ /* 1a) Get the location of the EBDA */
+
ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
physical_address <<= 4; /* Convert segment to physical address */
@@ -572,9 +603,11 @@ acpi_tb_find_rsdp (
if (physical_address > 0x400) {
/*
- * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+ * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of
+ * 1_k length)
*/
- mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
+ mem_rover = acpi_tb_scan_memory_for_rsdp (
+ ACPI_PHYSADDR_TO_PTR (physical_address),
ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
@@ -584,10 +617,10 @@ acpi_tb_find_rsdp (
}
}
- /*
- * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
- */
- mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
+ /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
+
+ mem_rover = acpi_tb_scan_memory_for_rsdp (
+ ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
ACPI_HI_RSDP_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index c84997c9f96..73b1d8aeae9 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -263,6 +263,9 @@ dispatch_write(struct file* file, const char __user * buffer,
* destination so that sscanf can be used on it safely.
*/
tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
+ if(!tmp_buffer)
+ return -ENOMEM;
+
if (copy_from_user(tmp_buffer, buffer, count)) {
result = -EFAULT;
}
@@ -529,6 +532,11 @@ toshiba_acpi_init(void)
if (acpi_disabled)
return -ENODEV;
+
+ if (!acpi_specific_hotkey_enabled){
+ printk(MY_INFO "Using generic hotkey driver\n");
+ return -ENODEV;
+ }
/* simple device detection: look for HCI method */
if (is_valid_acpi_path(METHOD_HCI_1))
method_hci = METHOD_HCI_1;
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 3313439c4bc..c4e7f989a2b 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -47,8 +47,35 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utalloc")
+/* Local prototypes */
-/******************************************************************************
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+static struct acpi_debug_mem_block *
+acpi_ut_find_allocation (
+ u32 list_id,
+ void *allocation);
+
+static acpi_status
+acpi_ut_track_allocation (
+ u32 list_id,
+ struct acpi_debug_mem_block *address,
+ acpi_size size,
+ u8 alloc_type,
+ u32 component,
+ char *module,
+ u32 line);
+
+static acpi_status
+acpi_ut_remove_allocation (
+ u32 list_id,
+ struct acpi_debug_mem_block *address,
+ u32 component,
+ char *module,
+ u32 line);
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+
+
+/*******************************************************************************
*
* FUNCTION: acpi_ut_release_to_cache
*
@@ -98,7 +125,8 @@ acpi_ut_release_to_cache (
/* Put the object at the head of the cache list */
- * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
+ * (ACPI_CAST_INDIRECT_PTR (char,
+ &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
cache_info->list_head = object;
cache_info->cache_depth++;
@@ -115,7 +143,7 @@ acpi_ut_release_to_cache (
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_acquire_from_cache
*
@@ -156,7 +184,8 @@ acpi_ut_acquire_from_cache (
/* There is an object available, use it */
object = cache_info->list_head;
- cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
+ cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char,
+ &(((char *) object)[cache_info->link_offset])));
ACPI_MEM_TRACKING (cache_info->cache_hits++);
cache_info->cache_depth--;
@@ -201,7 +230,7 @@ acpi_ut_acquire_from_cache (
#ifdef ACPI_ENABLE_OBJECT_CACHE
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_delete_generic_cache
*
@@ -228,7 +257,8 @@ acpi_ut_delete_generic_cache (
while (cache_info->list_head) {
/* Delete one cached state object */
- next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
+ next = *(ACPI_CAST_INDIRECT_PTR (char,
+ &(((char *) cache_info->list_head)[cache_info->link_offset])));
ACPI_MEM_FREE (cache_info->list_head);
cache_info->list_head = next;
@@ -497,8 +527,8 @@ acpi_ut_allocate_and_track (
acpi_status status;
- allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
- module, line);
+ allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header),
+ component, module, line);
if (!allocation) {
return (NULL);
}
@@ -543,8 +573,8 @@ acpi_ut_callocate_and_track (
acpi_status status;
- allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
- module, line);
+ allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header),
+ component, module, line);
if (!allocation) {
/* Report allocation error */
@@ -637,7 +667,7 @@ acpi_ut_free_and_track (
*
******************************************************************************/
-struct acpi_debug_mem_block *
+static struct acpi_debug_mem_block *
acpi_ut_find_allocation (
u32 list_id,
void *allocation)
@@ -686,7 +716,7 @@ acpi_ut_find_allocation (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_track_allocation (
u32 list_id,
struct acpi_debug_mem_block *allocation,
@@ -721,10 +751,12 @@ acpi_ut_track_allocation (
element = acpi_ut_find_allocation (list_id, allocation);
if (element) {
- ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
+ ACPI_REPORT_ERROR ((
+ "ut_track_allocation: Allocation already present in list! (%p)\n",
allocation));
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n",
+ element, allocation));
goto unlock_and_exit;
}
@@ -773,7 +805,7 @@ unlock_and_exit:
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_remove_allocation (
u32 list_id,
struct acpi_debug_mem_block *allocation,
@@ -797,7 +829,7 @@ acpi_ut_remove_allocation (
/* No allocations! */
_ACPI_REPORT_ERROR (module, line, component,
- ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+ ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
return_ACPI_STATUS (AE_OK);
}
@@ -824,7 +856,8 @@ acpi_ut_remove_allocation (
ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
+ allocation->size));
status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
return_ACPI_STATUS (status);
@@ -842,6 +875,7 @@ acpi_ut_remove_allocation (
* DESCRIPTION: Print some info about the outstanding allocations.
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
void
acpi_ut_dump_allocation_info (
@@ -884,7 +918,8 @@ acpi_ut_dump_allocation_info (
ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
("%30s: %4d (%3d Kb)\n", "Max Nodes",
acpi_gbl_max_concurrent_node_count,
- ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
+ ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
+ sizeof (struct acpi_namespace_node)))));
*/
return_VOID;
}
@@ -933,26 +968,26 @@ acpi_ut_dump_allocations (
descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
- descriptor, element->size, element->module,
- element->line, acpi_ut_get_descriptor_name (descriptor));
+ descriptor, element->size, element->module,
+ element->line, acpi_ut_get_descriptor_name (descriptor));
/* Most of the elements will be Operand objects. */
switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
case ACPI_DESC_TYPE_OPERAND:
acpi_os_printf ("%12.12s R%hd",
- acpi_ut_get_type_name (descriptor->object.common.type),
- descriptor->object.common.reference_count);
+ acpi_ut_get_type_name (descriptor->object.common.type),
+ descriptor->object.common.reference_count);
break;
case ACPI_DESC_TYPE_PARSER:
acpi_os_printf ("aml_opcode %04hX",
- descriptor->op.asl.aml_opcode);
+ descriptor->op.asl.aml_opcode);
break;
case ACPI_DESC_TYPE_NAMED:
acpi_os_printf ("%4.4s",
- acpi_ut_get_node_name (&descriptor->node));
+ acpi_ut_get_node_name (&descriptor->node));
break;
default:
@@ -983,6 +1018,5 @@ acpi_ut_dump_allocations (
return_VOID;
}
-
#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 0fcd98bde0d..11e88495716 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -49,21 +49,69 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utcopy")
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_copy_isimple_to_esimple (
+ union acpi_operand_object *internal_object,
+ union acpi_object *external_object,
+ u8 *data_space,
+ acpi_size *buffer_space_used);
+
+static acpi_status
+acpi_ut_copy_ielement_to_ielement (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context);
+
+static acpi_status
+acpi_ut_copy_ipackage_to_epackage (
+ union acpi_operand_object *internal_object,
+ u8 *buffer,
+ acpi_size *space_used);
+
+static acpi_status
+acpi_ut_copy_esimple_to_isimple(
+ union acpi_object *user_obj,
+ union acpi_operand_object **return_obj);
+
+static acpi_status
+acpi_ut_copy_simple_object (
+ union acpi_operand_object *source_desc,
+ union acpi_operand_object *dest_desc);
+
+static acpi_status
+acpi_ut_copy_ielement_to_eelement (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context);
+
+static acpi_status
+acpi_ut_copy_ipackage_to_ipackage (
+ union acpi_operand_object *source_obj,
+ union acpi_operand_object *dest_obj,
+ struct acpi_walk_state *walk_state);
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_isimple_to_esimple
*
- * PARAMETERS: *internal_object - Pointer to the object we are examining
- * *Buffer - Where the object is returned
- * *space_used - Where the data length is returned
+ * PARAMETERS: internal_object - Source object to be copied
+ * external_object - Where to return the copied object
+ * data_space - Where object data is returned (such as
+ * buffer and string data)
+ * buffer_space_used - Length of data_space that was used
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to place a simple object in a user
- * buffer.
+ * DESCRIPTION: This function is called to copy a simple internal object to
+ * an external object.
*
- * The buffer is assumed to have sufficient space for the object.
+ * The data_space buffer is assumed to have sufficient space for
+ * the object.
*
******************************************************************************/
@@ -107,10 +155,12 @@ acpi_ut_copy_isimple_to_esimple (
external_object->string.pointer = (char *) data_space;
external_object->string.length = internal_object->string.length;
- *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1);
+ *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ (acpi_size) internal_object->string.length + 1);
- ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer,
- (acpi_size) internal_object->string.length + 1);
+ ACPI_MEMCPY ((void *) data_space,
+ (void *) internal_object->string.pointer,
+ (acpi_size) internal_object->string.length + 1);
break;
@@ -118,10 +168,12 @@ acpi_ut_copy_isimple_to_esimple (
external_object->buffer.pointer = data_space;
external_object->buffer.length = internal_object->buffer.length;
- *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length);
+ *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
+ internal_object->string.length);
- ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer,
- internal_object->buffer.length);
+ ACPI_MEMCPY ((void *) data_space,
+ (void *) internal_object->buffer.pointer,
+ internal_object->buffer.length);
break;
@@ -194,7 +246,7 @@ acpi_ut_copy_isimple_to_esimple (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_copy_ielement_to_eelement (
u8 object_type,
union acpi_operand_object *source_object,
@@ -213,7 +265,7 @@ acpi_ut_copy_ielement_to_eelement (
this_index = state->pkg.index;
target_object = (union acpi_object *)
- &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
+ &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
switch (object_type) {
case ACPI_COPY_TYPE_SIMPLE:
@@ -236,7 +288,8 @@ acpi_ut_copy_ielement_to_eelement (
*/
target_object->type = ACPI_TYPE_PACKAGE;
target_object->package.count = source_object->package.count;
- target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space);
+ target_object->package.elements =
+ ACPI_CAST_PTR (union acpi_object, info->free_space);
/*
* Pass the new package object back to the package walk routine
@@ -248,7 +301,8 @@ acpi_ut_copy_ielement_to_eelement (
* update the buffer length counter
*/
object_space = ACPI_ROUND_UP_TO_NATIVE_WORD (
- (acpi_size) target_object->package.count * sizeof (union acpi_object));
+ (acpi_size) target_object->package.count *
+ sizeof (union acpi_object));
break;
@@ -266,9 +320,9 @@ acpi_ut_copy_ielement_to_eelement (
*
* FUNCTION: acpi_ut_copy_ipackage_to_epackage
*
- * PARAMETERS: *internal_object - Pointer to the object we are returning
- * *Buffer - Where the object is returned
- * *space_used - Where the object length is returned
+ * PARAMETERS: internal_object - Pointer to the object we are returning
+ * Buffer - Where the object is returned
+ * space_used - Where the object length is returned
*
* RETURN: Status
*
@@ -304,13 +358,15 @@ acpi_ut_copy_ipackage_to_epackage (
* Free space begins right after the first package
*/
info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
- info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+ info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
+ sizeof (union acpi_object));
info.object_space = 0;
info.num_packages = 1;
external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
external_object->package.count = internal_object->package.count;
- external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space);
+ external_object->package.elements = ACPI_CAST_PTR (union acpi_object,
+ info.free_space);
/*
* Leave room for an array of ACPI_OBJECTS in the buffer
@@ -333,8 +389,8 @@ acpi_ut_copy_ipackage_to_epackage (
*
* FUNCTION: acpi_ut_copy_iobject_to_eobject
*
- * PARAMETERS: *internal_object - The internal object to be converted
- * *buffer_ptr - Where the object is returned
+ * PARAMETERS: internal_object - The internal object to be converted
+ * buffer_ptr - Where the object is returned
*
* RETURN: Status
*
@@ -367,10 +423,10 @@ acpi_ut_copy_iobject_to_eobject (
* Build a simple object (no nested objects)
*/
status = acpi_ut_copy_isimple_to_esimple (internal_object,
- (union acpi_object *) ret_buffer->pointer,
- ((u8 *) ret_buffer->pointer +
- ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
- &ret_buffer->length);
+ (union acpi_object *) ret_buffer->pointer,
+ ((u8 *) ret_buffer->pointer +
+ ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
+ &ret_buffer->length);
/*
* build simple does not include the object size in the length
* so we add it in here
@@ -386,8 +442,8 @@ acpi_ut_copy_iobject_to_eobject (
*
* FUNCTION: acpi_ut_copy_esimple_to_isimple
*
- * PARAMETERS: *external_object - The external object to be converted
- * *internal_object - Where the internal object is returned
+ * PARAMETERS: external_object - The external object to be converted
+ * ret_internal_object - Where the internal object is returned
*
* RETURN: Status
*
@@ -398,7 +454,7 @@ acpi_ut_copy_iobject_to_eobject (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_copy_esimple_to_isimple (
union acpi_object *external_object,
union acpi_operand_object **ret_internal_object)
@@ -417,7 +473,8 @@ acpi_ut_copy_esimple_to_isimple (
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_INTEGER:
- internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
+ internal_object = acpi_ut_create_internal_object (
+ (u8) external_object->type);
if (!internal_object) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
@@ -486,7 +543,6 @@ error_exit:
#ifdef ACPI_FUTURE_IMPLEMENTATION
-
/* Code to convert packages that are parameters to control methods */
/*******************************************************************************
@@ -614,7 +670,7 @@ acpi_ut_copy_eobject_to_iobject (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_copy_simple_object (
union acpi_operand_object *source_desc,
union acpi_operand_object *dest_desc)
@@ -724,7 +780,7 @@ acpi_ut_copy_simple_object (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_copy_ielement_to_ielement (
u8 object_type,
union acpi_operand_object *source_object,
@@ -837,7 +893,7 @@ error_exit:
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_copy_ipackage_to_ipackage (
union acpi_operand_object *source_obj,
union acpi_operand_object *dest_obj,
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 985c5d045b7..794c7df3f2a 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -56,7 +56,7 @@ static char *acpi_gbl_fn_entry_str = "----Entry";
static char *acpi_gbl_fn_exit_str = "----Exit-";
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_init_stack_ptr_trace
*
@@ -64,9 +64,9 @@ static char *acpi_gbl_fn_exit_str = "----Exit-";
*
* RETURN: None
*
- * DESCRIPTION: Save the current stack pointer
+ * DESCRIPTION: Save the current CPU stack pointer at subsystem startup
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_init_stack_ptr_trace (
@@ -79,7 +79,7 @@ acpi_ut_init_stack_ptr_trace (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_track_stack_ptr
*
@@ -87,9 +87,9 @@ acpi_ut_init_stack_ptr_trace (
*
* RETURN: None
*
- * DESCRIPTION: Save the current stack pointer
+ * DESCRIPTION: Save the current CPU stack pointer
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_track_stack_ptr (
@@ -110,16 +110,16 @@ acpi_ut_track_stack_ptr (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_debug_print
*
- * PARAMETERS: debug_level - Requested debug print level
- * proc_name - Caller's procedure name
- * module_name - Caller's module name (for error output)
+ * PARAMETERS: requested_debug_level - Requested debug print level
* line_number - Caller's line number (for error output)
- * component_id - Caller's component ID (for error output)
- *
+ * dbg_info - Contains:
+ * proc_name - Caller's procedure name
+ * module_name - Caller's module name
+ * component_id - Caller's component ID
* Format - Printf format field
* ... - Optional printf arguments
*
@@ -128,7 +128,7 @@ acpi_ut_track_stack_ptr (
* DESCRIPTION: Print error message with prefix consisting of the module name,
* line number, and component ID.
*
- ****************************************************************************/
+ ******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print (
@@ -157,7 +157,8 @@ acpi_ut_debug_print (
if (thread_id != acpi_gbl_prev_thread_id) {
if (ACPI_LV_THREADS & acpi_dbg_level) {
- acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+ acpi_os_printf (
+ "\n**** Context Switch from TID %X to TID %X ****\n\n",
acpi_gbl_prev_thread_id, thread_id);
}
@@ -174,15 +175,16 @@ acpi_ut_debug_print (
acpi_os_printf ("[%04lX] ", thread_id);
}
- acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name);
+ acpi_os_printf ("[%02ld] %-22.22s: ",
+ acpi_gbl_nesting_level, dbg_info->proc_name);
va_start (args, format);
acpi_os_vprintf (format, args);
}
-EXPORT_SYMBOL(acpi_ut_debug_print);
+EXPORT_SYMBOL(acpi_ut_debug_print);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_debug_print_raw
*
@@ -200,7 +202,7 @@ EXPORT_SYMBOL(acpi_ut_debug_print);
* DESCRIPTION: Print message with no headers. Has same interface as
* debug_print so that the same macros can be used.
*
- ****************************************************************************/
+ ******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw (
@@ -224,7 +226,7 @@ acpi_ut_debug_print_raw (
EXPORT_SYMBOL(acpi_ut_debug_print_raw);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_trace
*
@@ -239,7 +241,7 @@ EXPORT_SYMBOL(acpi_ut_debug_print_raw);
* DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_trace (
@@ -256,7 +258,7 @@ acpi_ut_trace (
EXPORT_SYMBOL(acpi_ut_trace);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_ptr
*
@@ -272,7 +274,7 @@ EXPORT_SYMBOL(acpi_ut_trace);
* DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_trace_ptr (
@@ -288,7 +290,7 @@ acpi_ut_trace_ptr (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_str
*
@@ -304,7 +306,7 @@ acpi_ut_trace_ptr (
* DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_trace_str (
@@ -321,7 +323,7 @@ acpi_ut_trace_str (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_trace_u32
*
@@ -337,7 +339,7 @@ acpi_ut_trace_str (
* DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_trace_u32 (
@@ -354,7 +356,7 @@ acpi_ut_trace_u32 (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_exit
*
@@ -369,7 +371,7 @@ acpi_ut_trace_u32 (
* DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_exit (
@@ -385,7 +387,7 @@ acpi_ut_exit (
EXPORT_SYMBOL(acpi_ut_exit);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_status_exit
*
@@ -401,7 +403,7 @@ EXPORT_SYMBOL(acpi_ut_exit);
* DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit status also.
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_status_exit (
@@ -426,7 +428,7 @@ acpi_ut_status_exit (
EXPORT_SYMBOL(acpi_ut_status_exit);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_value_exit
*
@@ -442,7 +444,7 @@ EXPORT_SYMBOL(acpi_ut_status_exit);
* DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit value also.
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_value_exit (
@@ -460,7 +462,7 @@ acpi_ut_value_exit (
EXPORT_SYMBOL(acpi_ut_value_exit);
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_ptr_exit
*
@@ -469,14 +471,14 @@ EXPORT_SYMBOL(acpi_ut_value_exit);
* proc_name - Caller's procedure name
* module_name - Caller's module name
* component_id - Caller's component ID
- * Value - Value to be printed with exit msg
+ * Ptr - Pointer to display
*
* RETURN: None
*
* DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
* set in debug_level. Prints exit value also.
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_ptr_exit (
@@ -494,7 +496,7 @@ acpi_ut_ptr_exit (
#endif
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_dump_buffer
*
@@ -507,7 +509,7 @@ acpi_ut_ptr_exit (
*
* DESCRIPTION: Generic dump buffer in both hex and ascii.
*
- ****************************************************************************/
+ ******************************************************************************/
void
acpi_ut_dump_buffer (
@@ -533,34 +535,28 @@ acpi_ut_dump_buffer (
display = DB_BYTE_DISPLAY;
}
- acpi_os_printf ("\nOffset Value\n");
+ /* Nasty little dump buffer routine! */
- /*
- * Nasty little dump buffer routine!
- */
while (i < count) {
/* Print current offset */
- acpi_os_printf ("%05X ", (u32) i);
+ acpi_os_printf ("%6.4X: ", (u32) i);
/* Print 16 hex chars */
for (j = 0; j < 16;) {
if (i + j >= count) {
- acpi_os_printf ("\n");
- return;
- }
+ /* Dump fill spaces */
- /* Make sure that the s8 doesn't get sign-extended! */
+ acpi_os_printf ("%*s", ((display * 2) + 1), " ");
+ j += display;
+ continue;
+ }
switch (display) {
- /* Default is BYTE display */
+ default: /* Default is BYTE display */
- default:
-
- acpi_os_printf ("%02X ",
- *((u8 *) &buffer[i + j]));
- j += 1;
+ acpi_os_printf ("%02X ", buffer[i + j]);
break;
@@ -568,7 +564,6 @@ acpi_ut_dump_buffer (
ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]);
acpi_os_printf ("%04X ", temp32);
- j += 2;
break;
@@ -576,7 +571,6 @@ acpi_ut_dump_buffer (
ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
acpi_os_printf ("%08X ", temp32);
- j += 4;
break;
@@ -587,15 +581,17 @@ acpi_ut_dump_buffer (
ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]);
acpi_os_printf ("%08X ", temp32);
- j += 8;
break;
}
+
+ j += display;
}
/*
* Print the ASCII equivalent characters
* But watch out for the bad unprintable ones...
*/
+ acpi_os_printf (" ");
for (j = 0; j < 16; j++) {
if (i + j >= count) {
acpi_os_printf ("\n");
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 9a52ad52a23..bc540302268 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -51,12 +51,23 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utdelete")
+/* Local prototypes */
+
+static void
+acpi_ut_delete_internal_obj (
+ union acpi_operand_object *object);
+
+static void
+acpi_ut_update_ref_count (
+ union acpi_operand_object *object,
+ u32 action);
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_delete_internal_obj
*
- * PARAMETERS: *Object - Pointer to the list to be deleted
+ * PARAMETERS: Object - Object to be deleted
*
* RETURN: None
*
@@ -65,7 +76,7 @@
*
******************************************************************************/
-void
+static void
acpi_ut_delete_internal_obj (
union acpi_operand_object *object)
{
@@ -152,7 +163,8 @@ acpi_ut_delete_internal_obj (
case ACPI_TYPE_MUTEX:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Mutex %p, Semaphore %p\n",
object, object->mutex.semaphore));
acpi_ex_unlink_mutex (object);
@@ -162,7 +174,8 @@ acpi_ut_delete_internal_obj (
case ACPI_TYPE_EVENT:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Event %p, Semaphore %p\n",
object, object->event.semaphore));
(void) acpi_os_delete_semaphore (object->event.semaphore);
@@ -172,7 +185,8 @@ acpi_ut_delete_internal_obj (
case ACPI_TYPE_METHOD:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Method %p\n", object));
/* Delete the method semaphore if it exists */
@@ -185,7 +199,8 @@ acpi_ut_delete_internal_obj (
case ACPI_TYPE_REGION:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Region %p\n", object));
second_desc = acpi_ns_get_secondary_object (object);
if (second_desc) {
@@ -212,7 +227,8 @@ acpi_ut_delete_internal_obj (
case ACPI_TYPE_BUFFER_FIELD:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "***** Buffer Field %p\n", object));
second_desc = acpi_ns_get_secondary_object (object);
if (second_desc) {
@@ -247,7 +263,7 @@ acpi_ut_delete_internal_obj (
*
* FUNCTION: acpi_ut_delete_internal_object_list
*
- * PARAMETERS: *obj_list - Pointer to the list to be deleted
+ * PARAMETERS: obj_list - Pointer to the list to be deleted
*
* RETURN: None
*
@@ -283,7 +299,7 @@ acpi_ut_delete_internal_object_list (
*
* FUNCTION: acpi_ut_update_ref_count
*
- * PARAMETERS: *Object - Object whose ref count is to be updated
+ * PARAMETERS: Object - Object whose ref count is to be updated
* Action - What to do
*
* RETURN: New ref count
@@ -312,7 +328,8 @@ acpi_ut_update_ref_count (
new_count = count;
/*
- * Perform the reference count action (increment, decrement, or force delete)
+ * Perform the reference count action
+ * (increment, decrement, or force delete)
*/
switch (action) {
@@ -321,7 +338,8 @@ acpi_ut_update_ref_count (
new_count++;
object->common.reference_count = new_count;
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, [Incremented]\n",
object, new_count));
break;
@@ -329,7 +347,8 @@ acpi_ut_update_ref_count (
case REF_DECREMENT:
if (count < 1) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
object, new_count));
new_count = 0;
@@ -337,12 +356,14 @@ acpi_ut_update_ref_count (
else {
new_count--;
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, [Decremented]\n",
object, new_count));
}
if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Method Obj %p Refs=%X, [Decremented]\n",
object, new_count));
}
@@ -356,7 +377,8 @@ acpi_ut_update_ref_count (
case REF_FORCE_DELETE:
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Refs=%X, Force delete! (Set to 0)\n",
object, count));
new_count = 0;
@@ -390,7 +412,7 @@ acpi_ut_update_ref_count (
*
* FUNCTION: acpi_ut_update_object_reference
*
- * PARAMETERS: *Object - Increment ref count for this object
+ * PARAMETERS: Object - Increment ref count for this object
* and all sub-objects
* Action - Either REF_INCREMENT or REF_DECREMENT or
* REF_FORCE_DELETE
@@ -431,7 +453,8 @@ acpi_ut_update_object_reference (
/* Make sure that this isn't a namespace handle */
if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Object %p is NS handle\n", object));
return_ACPI_STATUS (AE_OK);
}
@@ -614,8 +637,8 @@ error_exit:
*
* FUNCTION: acpi_ut_add_reference
*
- * PARAMETERS: *Object - Object whose reference count is to be
- * incremented
+ * PARAMETERS: Object - Object whose reference count is to be
+ * incremented
*
* RETURN: None
*
@@ -652,7 +675,7 @@ acpi_ut_add_reference (
*
* FUNCTION: acpi_ut_remove_reference
*
- * PARAMETERS: *Object - Object whose ref count will be decremented
+ * PARAMETERS: Object - Object whose ref count will be decremented
*
* RETURN: None
*
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index ead27d2c4d1..00046dd5d92 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -50,6 +50,19 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("uteval")
+/* Local prototypes */
+
+static void
+acpi_ut_copy_id_string (
+ char *destination,
+ char *source,
+ acpi_size max_length);
+
+static acpi_status
+acpi_ut_translate_one_cid (
+ union acpi_operand_object *obj_desc,
+ struct acpi_compatible_id *one_cid);
+
/*******************************************************************************
*
@@ -237,9 +250,9 @@ acpi_ut_evaluate_object (
*
* FUNCTION: acpi_ut_evaluate_numeric_object
*
- * PARAMETERS: *object_name - Object name to be evaluated
+ * PARAMETERS: object_name - Object name to be evaluated
* device_node - Node for the device
- * *Address - Where the value is returned
+ * Address - Where the value is returned
*
* RETURN: Status
*
@@ -303,7 +316,6 @@ acpi_ut_copy_id_string (
acpi_size max_length)
{
-
/*
* Workaround for ID strings that have a leading asterisk. This construct
* is not allowed by the ACPI specification (ID strings must be
@@ -325,7 +337,7 @@ acpi_ut_copy_id_string (
* FUNCTION: acpi_ut_execute_HID
*
* PARAMETERS: device_node - Node for the device
- * *Hid - Where the HID is returned
+ * Hid - Where the HID is returned
*
* RETURN: Status
*
@@ -429,7 +441,7 @@ acpi_ut_translate_one_cid (
* FUNCTION: acpi_ut_execute_CID
*
* PARAMETERS: device_node - Node for the device
- * *Cid - Where the CID is returned
+ * return_cid_list - Where the CID list is returned
*
* RETURN: Status
*
@@ -488,10 +500,10 @@ acpi_ut_execute_CID (
cid_list->size = size;
/*
- * A _CID can return either a single compatible ID or a package of compatible
- * IDs. Each compatible ID can be one of the following:
- * -- Number (32 bit compressed EISA ID) or
- * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+ * A _CID can return either a single compatible ID or a package of
+ * compatible IDs. Each compatible ID can be one of the following:
+ * 1) Integer (32 bit compressed EISA ID) or
+ * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
*/
/* The _CID object can be either a single CID or a package (list) of CIDs */
@@ -534,7 +546,7 @@ acpi_ut_execute_CID (
* FUNCTION: acpi_ut_execute_UID
*
* PARAMETERS: device_node - Node for the device
- * *Uid - Where the UID is returned
+ * Uid - Where the UID is returned
*
* RETURN: Status
*
@@ -587,7 +599,7 @@ acpi_ut_execute_UID (
* FUNCTION: acpi_ut_execute_STA
*
* PARAMETERS: device_node - Node for the device
- * *Flags - Where the status flags are returned
+ * Flags - Where the status flags are returned
*
* RETURN: Status
*
@@ -641,7 +653,7 @@ acpi_ut_execute_STA (
* FUNCTION: acpi_ut_execute_Sxds
*
* PARAMETERS: device_node - Node for the device
- * *Flags - Where the status flags are returned
+ * Flags - Where the status flags are returned
*
* RETURN: Status
*
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 25b0f8ae1bc..4146019b543 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -44,7 +44,6 @@
#define DEFINE_ACPI_GLOBALS
#include <linux/module.h>
-
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
@@ -52,13 +51,14 @@
ACPI_MODULE_NAME ("utglobal")
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_format_exception
*
* PARAMETERS: Status - The acpi_status code to be formatted
*
- * RETURN: A string containing the exception text
+ * RETURN: A string containing the exception text. A valid pointer is
+ * always returned.
*
* DESCRIPTION: This function translates an ACPI exception into an ASCII string.
*
@@ -68,8 +68,8 @@ const char *
acpi_format_exception (
acpi_status status)
{
- const char *exception = "UNKNOWN_STATUS_CODE";
acpi_status sub_status;
+ const char *exception = NULL;
ACPI_FUNCTION_NAME ("format_exception");
@@ -82,57 +82,55 @@ acpi_format_exception (
if (sub_status <= AE_CODE_ENV_MAX) {
exception = acpi_gbl_exception_names_env [sub_status];
- break;
}
- goto unknown;
+ break;
case AE_CODE_PROGRAMMER:
if (sub_status <= AE_CODE_PGM_MAX) {
exception = acpi_gbl_exception_names_pgm [sub_status -1];
- break;
}
- goto unknown;
+ break;
case AE_CODE_ACPI_TABLES:
if (sub_status <= AE_CODE_TBL_MAX) {
exception = acpi_gbl_exception_names_tbl [sub_status -1];
- break;
}
- goto unknown;
+ break;
case AE_CODE_AML:
if (sub_status <= AE_CODE_AML_MAX) {
exception = acpi_gbl_exception_names_aml [sub_status -1];
- break;
}
- goto unknown;
+ break;
case AE_CODE_CONTROL:
if (sub_status <= AE_CODE_CTRL_MAX) {
exception = acpi_gbl_exception_names_ctrl [sub_status -1];
- break;
}
- goto unknown;
+ break;
default:
- goto unknown;
+ break;
}
+ if (!exception) {
+ /* Exception code was not recognized */
- return ((const char *) exception);
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unknown exception code: 0x%8.8X\n", status));
-unknown:
+ return ((const char *) "UNKNOWN_STATUS_CODE");
+ }
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status));
return ((const char *) exception);
}
-/******************************************************************************
+/*******************************************************************************
*
* Static global variable initialization.
*
@@ -212,13 +210,12 @@ const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STR
};
-/******************************************************************************
+/*******************************************************************************
*
* Namespace globals
*
******************************************************************************/
-
/*
* Predefined ACPI Names (Built-in to the Interpreter)
*
@@ -241,9 +238,11 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
{"_OSI", ACPI_TYPE_METHOD, (char *) 1},
#endif
- {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */
-};
+ /* Table terminator */
+
+ {NULL, ACPI_TYPE_ANY, NULL}
+};
/*
* Properties of the ACPI Object Types, both internal and external.
@@ -288,22 +287,25 @@ const u8 acpi_gbl_ns_properties[] =
/* Hex to ASCII conversion table */
static const char acpi_gbl_hex_to_ascii[] =
- {'0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F'};
+{
+ '0','1','2','3','4','5','6','7',
+ '8','9','A','B','C','D','E','F'
+};
+
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_hex_to_ascii_char
*
* PARAMETERS: Integer - Contains the hex digit
* Position - bit position of the digit within the
- * integer
+ * integer (multiple of 4)
*
- * RETURN: Ascii character
+ * RETURN: The converted Ascii character
*
- * DESCRIPTION: Convert a hex digit to an ascii character
+ * DESCRIPTION: Convert a hex digit to an Ascii character
*
- ****************************************************************************/
+ ******************************************************************************/
char
acpi_ut_hex_to_ascii_char (
@@ -315,7 +317,7 @@ acpi_ut_hex_to_ascii_char (
}
-/******************************************************************************
+/*******************************************************************************
*
* Table name globals
*
@@ -324,7 +326,7 @@ acpi_ut_hex_to_ascii_char (
* that are not used by the subsystem are simply ignored.
*
* Do NOT add any table to this list that is not consumed directly by this
- * subsystem.
+ * subsystem (No MADT, ECDT, SBST, etc.)
*
******************************************************************************/
@@ -391,7 +393,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVE
/* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE},
};
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_region_name
*
@@ -401,7 +403,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVE
*
* DESCRIPTION: Translate a Space ID into a name string (Debug only)
*
- ****************************************************************************/
+ ******************************************************************************/
/* Region type decoding */
@@ -429,7 +431,6 @@ acpi_ut_get_region_name (
{
return ("user_defined_region");
}
-
else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS)
{
return ("invalid_space_id");
@@ -439,7 +440,7 @@ acpi_ut_get_region_name (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_event_name
*
@@ -449,7 +450,7 @@ acpi_ut_get_region_name (
*
* DESCRIPTION: Translate a Event ID into a name string (Debug only)
*
- ****************************************************************************/
+ ******************************************************************************/
/* Event type decoding */
@@ -477,7 +478,7 @@ acpi_ut_get_event_name (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_type_name
*
@@ -487,20 +488,21 @@ acpi_ut_get_event_name (
*
* DESCRIPTION: Translate a Type ID into a name string (Debug only)
*
- ****************************************************************************/
+ ******************************************************************************/
/*
* Elements of acpi_gbl_ns_type_names below must match
* one-to-one with values of acpi_object_type
*
- * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
- * stored in a table it really means that we have thus far seen no evidence to
- * indicate what type is actually going to be stored for this entry.
+ * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
+ * when stored in a table it really means that we have thus far seen no
+ * evidence to indicate what type is actually going to be stored for this entry.
*/
static const char acpi_gbl_bad_type[] = "UNDEFINED";
-#define TYPE_NAME_LENGTH 12 /* Maximum length of each string */
-static const char *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */
+/* Printable names of the ACPI object types */
+
+static const char *acpi_gbl_ns_type_names[] =
{
/* 00 */ "Untyped",
/* 01 */ "Integer",
@@ -564,7 +566,7 @@ acpi_ut_get_object_type_name (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_node_name
*
@@ -574,7 +576,7 @@ acpi_ut_get_object_type_name (
*
* DESCRIPTION: Validate the node and return the node's ACPI name.
*
- ****************************************************************************/
+ ******************************************************************************/
char *
acpi_ut_get_node_name (
@@ -618,7 +620,7 @@ acpi_ut_get_node_name (
}
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_descriptor_name
*
@@ -628,9 +630,11 @@ acpi_ut_get_node_name (
*
* DESCRIPTION: Validate object and return the descriptor type
*
- ****************************************************************************/
+ ******************************************************************************/
+
+/* Printable names of object descriptor types */
-static const char *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
+static const char *acpi_gbl_desc_type_names[] =
{
/* 00 */ "Invalid",
/* 01 */ "Cached",
@@ -676,17 +680,18 @@ acpi_ut_get_descriptor_name (
* Strings and procedures used for debug only
*/
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_get_mutex_name
*
- * PARAMETERS: None.
+ * PARAMETERS: mutex_id - The predefined ID for this mutex.
*
- * RETURN: Status
+ * RETURN: String containing the name of the mutex. Always returns a valid
+ * pointer.
*
* DESCRIPTION: Translate a mutex ID into a name string (Debug only)
*
- ****************************************************************************/
+ ******************************************************************************/
char *
acpi_ut_get_mutex_name (
@@ -700,21 +705,20 @@ acpi_ut_get_mutex_name (
return (acpi_gbl_mutex_names[mutex_id]);
}
-
#endif
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_valid_object_type
*
* PARAMETERS: Type - Object type to be validated
*
- * RETURN: TRUE if valid object type
+ * RETURN: TRUE if valid object type, FALSE otherwise
*
* DESCRIPTION: Validate an object type
*
- ****************************************************************************/
+ ******************************************************************************/
u8
acpi_ut_valid_object_type (
@@ -732,7 +736,7 @@ acpi_ut_valid_object_type (
}
-/****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_allocate_owner_id
*
@@ -740,7 +744,10 @@ acpi_ut_valid_object_type (
*
* DESCRIPTION: Allocate a table or method owner id
*
- ***************************************************************************/
+ * NOTE: this algorithm has a wraparound problem at 64_k method invocations, and
+ * should be revisited (TBD)
+ *
+ ******************************************************************************/
acpi_owner_id
acpi_ut_allocate_owner_id (
@@ -796,16 +803,18 @@ acpi_ut_allocate_owner_id (
}
-/****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_ut_init_globals
*
- * PARAMETERS: none
+ * PARAMETERS: None
+ *
+ * RETURN: None
*
* DESCRIPTION: Init library globals. All globals that require specific
* initialization should be initialized here!
*
- ***************************************************************************/
+ ******************************************************************************/
void
acpi_ut_init_globals (
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index bdbadaf48d2..7f3713889ff 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -49,19 +49,29 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utinit")
+/* Local prototypes */
+
+static void
+acpi_ut_fadt_register_error (
+ char *register_name,
+ u32 value,
+ acpi_size offset);
+
+static void acpi_ut_terminate (
+ void);
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_fadt_register_error
*
- * PARAMETERS: *register_name - Pointer to string identifying register
+ * PARAMETERS: register_name - Pointer to string identifying register
* Value - Actual register contents value
- * acpi_test_spec_section - TDS section containing assertion
- * acpi_assertion - Assertion number being tested
+ * Offset - Byte offset in the FADT
*
* RETURN: AE_BAD_VALUE
*
- * DESCRIPTION: Display failure message and link failure to TDS assertion
+ * DESCRIPTION: Display failure message
*
******************************************************************************/
@@ -166,12 +176,13 @@ acpi_ut_validate_fadt (
*
* RETURN: none
*
- * DESCRIPTION: free global memory
+ * DESCRIPTION: Free global memory
*
******************************************************************************/
-void
-acpi_ut_terminate (void)
+static void
+acpi_ut_terminate (
+ void)
{
struct acpi_gpe_block_info *gpe_block;
struct acpi_gpe_block_info *next_gpe_block;
@@ -183,8 +194,6 @@ acpi_ut_terminate (void)
/* Free global tables, etc. */
-
-
/* Free global GPE blocks and related info structures */
gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
@@ -221,7 +230,8 @@ acpi_ut_terminate (void)
******************************************************************************/
void
-acpi_ut_subsystem_shutdown (void)
+acpi_ut_subsystem_shutdown (
+ void)
{
ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown");
@@ -229,14 +239,16 @@ acpi_ut_subsystem_shutdown (void)
/* Just exit if subsystem is already shutdown */
if (acpi_gbl_shutdown) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "ACPI Subsystem is already terminated\n"));
return_VOID;
}
/* Subsystem appears active, go ahead and shut it down */
acpi_gbl_shutdown = TRUE;
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Shutting down ACPI Subsystem...\n"));
/* Close the acpi_event Handling */
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 2525c1a9354..0d527c91543 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -259,6 +259,8 @@ acpi_ut_divide (
*
* FUNCTION: acpi_ut_short_divide, acpi_ut_divide
*
+ * PARAMETERS: See function headers above
+ *
* DESCRIPTION: Native versions of the ut_divide functions. Use these if either
* 1) The target is a 64-bit platform and therefore 64-bit
* integer math is supported directly by the machine.
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index f6598547389..f6de4ed3d52 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -49,12 +49,57 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utmisc")
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_create_mutex (
+ acpi_mutex_handle mutex_id);
+
+static acpi_status
+acpi_ut_delete_mutex (
+ acpi_mutex_handle mutex_id);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_strupr (strupr)
+ *
+ * PARAMETERS: src_string - The source string to convert
+ *
+ * RETURN: Converted src_string (same as input pointer)
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
+ *
+ ******************************************************************************/
+
+char *
+acpi_ut_strupr (
+ char *src_string)
+{
+ char *string;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Walk entire string, uppercasing the letters */
+
+ for (string = src_string; *string; string++) {
+ *string = (char) ACPI_TOUPPER (*string);
+ }
+
+ return (src_string);
+}
+
/*******************************************************************************
*
* FUNCTION: acpi_ut_print_string
*
* PARAMETERS: String - Null terminated ASCII string
+ * max_length - Maximum output length
*
* RETURN: None
*
@@ -148,6 +193,8 @@ acpi_ut_print_string (
*
* PARAMETERS: Value - Value to be converted
*
+ * RETURN: u32 integer with bytes swapped
+ *
* DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
*
******************************************************************************/
@@ -160,7 +207,6 @@ acpi_ut_dword_byte_swap (
u32 value;
u8 bytes[4];
} out;
-
union {
u32 value;
u8 bytes[4];
@@ -219,7 +265,8 @@ acpi_ut_set_integer_width (
*
* FUNCTION: acpi_ut_display_init_pathname
*
- * PARAMETERS: obj_handle - Handle whose pathname will be displayed
+ * PARAMETERS: Type - Object type of the node
+ * obj_handle - Handle whose pathname will be displayed
* Path - Additional path string to be appended.
* (NULL if no extra path)
*
@@ -270,7 +317,8 @@ acpi_ut_display_init_pathname (
/* Print the object type and pathname */
- acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer);
+ acpi_os_printf ("%-12s %s",
+ acpi_ut_get_type_name (type), (char *) buffer.pointer);
/* Extra path is used to append names like _STA, _INI, etc. */
@@ -288,9 +336,9 @@ acpi_ut_display_init_pathname (
*
* FUNCTION: acpi_ut_valid_acpi_name
*
- * PARAMETERS: Character - The character to be examined
+ * PARAMETERS: Name - The name to be examined
*
- * RETURN: 1 if Character may appear in a name, else 0
+ * RETURN: TRUE if the name is valid, FALSE otherwise
*
* DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
* 1) Upper case alpha
@@ -495,40 +543,6 @@ error_exit:
/*******************************************************************************
*
- * FUNCTION: acpi_ut_strupr
- *
- * PARAMETERS: src_string - The source string to convert to
- *
- * RETURN: src_string
- *
- * DESCRIPTION: Convert string to uppercase
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-char *
-acpi_ut_strupr (
- char *src_string)
-{
- char *string;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /* Walk entire string, uppercasing the letters */
-
- for (string = src_string; *string; ) {
- *string = (char) ACPI_TOUPPER (*string);
- string++;
- }
-
- return (src_string);
-}
-#endif /* ACPI_FUTURE_USAGE */
-
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ut_mutex_initialize
*
* PARAMETERS: None.
@@ -611,7 +625,7 @@ acpi_ut_mutex_terminate (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_create_mutex (
acpi_mutex_handle mutex_id)
{
@@ -648,7 +662,7 @@ acpi_ut_create_mutex (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_delete_mutex (
acpi_mutex_handle mutex_id)
{
@@ -715,16 +729,16 @@ acpi_ut_acquire_mutex (
if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
if (i == mutex_id) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Mutex [%s] already acquired by this thread [%X]\n",
- acpi_ut_get_mutex_name (mutex_id), this_thread_id));
+ "Mutex [%s] already acquired by this thread [%X]\n",
+ acpi_ut_get_mutex_name (mutex_id), this_thread_id));
return (AE_ALREADY_ACQUIRED);
}
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (i),
- acpi_ut_get_mutex_name (mutex_id)));
+ "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (i),
+ acpi_ut_get_mutex_name (mutex_id)));
return (AE_ACQUIRE_DEADLOCK);
}
@@ -733,22 +747,23 @@ acpi_ut_acquire_mutex (
#endif
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
- "Thread %X attempting to acquire Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+ "Thread %X attempting to acquire Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
1, ACPI_WAIT_FOREVER);
if (ACPI_SUCCESS (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
acpi_gbl_mutex_info[mutex_id].use_count++;
acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
}
else {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id),
- acpi_format_exception (status)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Thread %X could not acquire Mutex [%s] %s\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+ acpi_format_exception (status)));
}
return (status);
@@ -793,8 +808,8 @@ acpi_ut_release_mutex (
*/
if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Mutex [%s] is not acquired, cannot release\n",
- acpi_ut_get_mutex_name (mutex_id)));
+ "Mutex [%s] is not acquired, cannot release\n",
+ acpi_ut_get_mutex_name (mutex_id)));
return (AE_NOT_ACQUIRED);
}
@@ -812,8 +827,8 @@ acpi_ut_release_mutex (
}
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Invalid release order: owns [%s], releasing [%s]\n",
- acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
+ "Invalid release order: owns [%s], releasing [%s]\n",
+ acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
return (AE_RELEASE_DEADLOCK);
}
@@ -826,13 +841,14 @@ acpi_ut_release_mutex (
status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id),
- acpi_format_exception (status)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Thread %X could not release Mutex [%s] %s\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+ acpi_format_exception (status)));
}
else {
ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
- this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
}
return (status);
@@ -843,11 +859,11 @@ acpi_ut_release_mutex (
*
* FUNCTION: acpi_ut_create_update_state_and_push
*
- * PARAMETERS: *Object - Object to be added to the new state
+ * PARAMETERS: Object - Object to be added to the new state
* Action - Increment/Decrement
* state_list - List the state will be added to
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Create a new state and push it
*
@@ -885,15 +901,16 @@ acpi_ut_create_update_state_and_push (
*
* FUNCTION: acpi_ut_create_pkg_state_and_push
*
- * PARAMETERS: *Object - Object to be added to the new state
+ * PARAMETERS: Object - Object to be added to the new state
* Action - Increment/Decrement
* state_list - List the state will be added to
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Create a new state and push it
*
******************************************************************************/
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_ut_create_pkg_state_and_push (
@@ -925,7 +942,7 @@ acpi_ut_create_pkg_state_and_push (
* PARAMETERS: list_head - Head of the state stack
* State - State object to push
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Push a state object onto a state stack
*
@@ -954,7 +971,7 @@ acpi_ut_push_generic_state (
*
* PARAMETERS: list_head - Head of the state stack
*
- * RETURN: Status
+ * RETURN: The popped state object
*
* DESCRIPTION: Pop a state object from a state stack
*
@@ -989,7 +1006,7 @@ acpi_ut_pop_generic_state (
*
* PARAMETERS: None
*
- * RETURN: Status
+ * RETURN: The new state object. NULL on failure.
*
* DESCRIPTION: Create a generic state object. Attempt to obtain one from
* the global state cache; If none available, create a new one.
@@ -997,7 +1014,8 @@ acpi_ut_pop_generic_state (
******************************************************************************/
union acpi_generic_state *
-acpi_ut_create_generic_state (void)
+acpi_ut_create_generic_state (
+ void)
{
union acpi_generic_state *state;
@@ -1023,7 +1041,7 @@ acpi_ut_create_generic_state (void)
*
* PARAMETERS: None
*
- * RETURN: Thread State
+ * RETURN: New Thread State. NULL on failure
*
* DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
* to track per-thread info during method execution
@@ -1060,11 +1078,10 @@ acpi_ut_create_thread_state (
*
* FUNCTION: acpi_ut_create_update_state
*
- * PARAMETERS: Object - Initial Object to be installed in the
- * state
- * Action - Update action to be performed
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
*
- * RETURN: Status
+ * RETURN: New state object, null on failure
*
* DESCRIPTION: Create an "Update State" - a flavor of the generic state used
* to update reference counts and delete complex objects such
@@ -1104,11 +1121,10 @@ acpi_ut_create_update_state (
*
* FUNCTION: acpi_ut_create_pkg_state
*
- * PARAMETERS: Object - Initial Object to be installed in the
- * state
- * Action - Update action to be performed
+ * PARAMETERS: Object - Initial Object to be installed in the state
+ * Action - Update action to be performed
*
- * RETURN: Status
+ * RETURN: New state object, null on failure
*
* DESCRIPTION: Create a "Package State"
*
@@ -1151,7 +1167,7 @@ acpi_ut_create_pkg_state (
*
* PARAMETERS: None
*
- * RETURN: Status
+ * RETURN: New state object, null on failure
*
* DESCRIPTION: Create a "Control State" - a flavor of the generic state used
* to support nested IF/WHILE constructs in the AML.
@@ -1190,7 +1206,7 @@ acpi_ut_create_control_state (
*
* PARAMETERS: State - The state object to be deleted
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Put a state object back into the global state cache. The object
* is not actually freed at this time.
@@ -1216,7 +1232,7 @@ acpi_ut_delete_generic_state (
*
* PARAMETERS: None
*
- * RETURN: Status
+ * RETURN: None
*
* DESCRIPTION: Purge the global state object cache. Used during subsystem
* termination.
@@ -1240,7 +1256,10 @@ acpi_ut_delete_generic_state_cache (
*
* FUNCTION: acpi_ut_walk_package_tree
*
- * PARAMETERS: obj_desc - The Package object on which to resolve refs
+ * PARAMETERS: source_object - The package to walk
+ * target_object - Target object (if package is being copied)
+ * walk_callback - Called once for each package element
+ * Context - Passed to the callback function
*
* RETURN: Status
*
@@ -1359,7 +1378,7 @@ acpi_ut_walk_package_tree (
* PARAMETERS: Buffer - Buffer to be scanned
* Length - number of bytes to examine
*
- * RETURN: checksum
+ * RETURN: The generated checksum
*
* DESCRIPTION: Generate a checksum on a raw buffer
*
@@ -1442,7 +1461,6 @@ acpi_ut_get_resource_end_tag (
* PARAMETERS: module_name - Caller's module name (for error output)
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
- * Message - Error message to use on failure
*
* RETURN: None
*
@@ -1457,7 +1475,6 @@ acpi_ut_report_error (
u32 component_id)
{
-
acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
}
@@ -1469,7 +1486,6 @@ acpi_ut_report_error (
* PARAMETERS: module_name - Caller's module name (for error output)
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
- * Message - Error message to use on failure
*
* RETURN: None
*
@@ -1495,7 +1511,6 @@ acpi_ut_report_warning (
* PARAMETERS: module_name - Caller's module name (for error output)
* line_number - Caller's line number (for error output)
* component_id - Caller's component ID (for error output)
- * Message - Error message to use on failure
*
* RETURN: None
*
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 9ee40a484e0..cd3899b9cc5 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -50,6 +50,25 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utobject")
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_get_simple_object_size (
+ union acpi_operand_object *obj,
+ acpi_size *obj_length);
+
+static acpi_status
+acpi_ut_get_package_object_size (
+ union acpi_operand_object *obj,
+ acpi_size *obj_length);
+
+static acpi_status
+acpi_ut_get_element_length (
+ u8 object_type,
+ union acpi_operand_object *source_object,
+ union acpi_generic_state *state,
+ void *context);
+
/*******************************************************************************
*
@@ -60,7 +79,7 @@
* component_id - Component type of caller
* Type - ACPI Type of the new object
*
- * RETURN: Object - The new object. Null on failure
+ * RETURN: A new internal object, null on failure
*
* DESCRIPTION: Create and initialize a new internal object.
*
@@ -83,7 +102,8 @@ acpi_ut_create_internal_object_dbg (
union acpi_operand_object *second_object;
- ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type));
+ ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg",
+ acpi_ut_get_type_name (type));
/* Allocate the raw object descriptor */
@@ -99,7 +119,8 @@ acpi_ut_create_internal_object_dbg (
/* These types require a secondary object */
- second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+ second_object = acpi_ut_allocate_object_desc_dbg (module_name,
+ line_number, component_id);
if (!second_object) {
acpi_ut_delete_object_desc (object);
return_PTR (NULL);
@@ -138,7 +159,7 @@ acpi_ut_create_internal_object_dbg (
*
* PARAMETERS: buffer_size - Size of buffer to be created
*
- * RETURN: Pointer to a new Buffer object
+ * RETURN: Pointer to a new Buffer object, null on failure
*
* DESCRIPTION: Create a fully initialized buffer object
*
@@ -192,9 +213,9 @@ acpi_ut_create_buffer_object (
*
* FUNCTION: acpi_ut_create_string_object
*
- * PARAMETERS: string_size - Size of string to be created. Does not
- * include NULL terminator, this is added
- * automatically.
+ * PARAMETERS: string_size - Size of string to be created. Does not
+ * include NULL terminator, this is added
+ * automatically.
*
* RETURN: Pointer to a new String object
*
@@ -249,7 +270,9 @@ acpi_ut_create_string_object (
*
* PARAMETERS: Object - Object to be validated
*
- * RETURN: Validate a pointer to be an union acpi_operand_object
+ * RETURN: TRUE if object is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Validate a pointer to be an union acpi_operand_object
*
******************************************************************************/
@@ -399,8 +422,8 @@ acpi_ut_delete_object_cache (
*
* FUNCTION: acpi_ut_get_simple_object_size
*
- * PARAMETERS: *internal_object - Pointer to the object we are examining
- * *obj_length - Where the length is returned
+ * PARAMETERS: internal_object - An ACPI operand object
+ * obj_length - Where the length is returned
*
* RETURN: Status
*
@@ -412,7 +435,7 @@ acpi_ut_delete_object_cache (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_get_simple_object_size (
union acpi_operand_object *internal_object,
acpi_size *obj_length)
@@ -424,8 +447,10 @@ acpi_ut_get_simple_object_size (
ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object);
- /* Handle a null object (Could be a uninitialized package element -- which is legal) */
-
+ /*
+ * Handle a null object (Could be a uninitialized package
+ * element -- which is legal)
+ */
if (!internal_object) {
*obj_length = 0;
return_ACPI_STATUS (AE_OK);
@@ -480,7 +505,8 @@ acpi_ut_get_simple_object_size (
* Get the actual length of the full pathname to this object.
* The reference will be converted to the pathname to the object
*/
- length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
+ length += ACPI_ROUND_UP_TO_NATIVE_WORD (
+ acpi_ns_get_pathname_length (internal_object->reference.node));
break;
default:
@@ -530,7 +556,7 @@ acpi_ut_get_simple_object_size (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_get_element_length (
u8 object_type,
union acpi_operand_object *source_object,
@@ -582,8 +608,8 @@ acpi_ut_get_element_length (
*
* FUNCTION: acpi_ut_get_package_object_size
*
- * PARAMETERS: *internal_object - Pointer to the object we are examining
- * *obj_length - Where the length is returned
+ * PARAMETERS: internal_object - An ACPI internal object
+ * obj_length - Where the length is returned
*
* RETURN: Status
*
@@ -595,7 +621,7 @@ acpi_ut_get_element_length (
*
******************************************************************************/
-acpi_status
+static acpi_status
acpi_ut_get_package_object_size (
union acpi_operand_object *internal_object,
acpi_size *obj_length)
@@ -636,8 +662,8 @@ acpi_ut_get_package_object_size (
*
* FUNCTION: acpi_ut_get_object_size
*
- * PARAMETERS: *internal_object - Pointer to the object we are examining
- * *obj_length - Where the length will be returned
+ * PARAMETERS: internal_object - An ACPI internal object
+ * obj_length - Where the length will be returned
*
* RETURN: Status
*
@@ -647,7 +673,7 @@ acpi_ut_get_package_object_size (
******************************************************************************/
acpi_status
-acpi_ut_get_object_size(
+acpi_ut_get_object_size (
union acpi_operand_object *internal_object,
acpi_size *obj_length)
{
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index 97a91f3f06f..e8803d81065 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -73,6 +73,7 @@ acpi_initialize_subsystem (
{
acpi_status status;
+
ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");
@@ -105,7 +106,6 @@ acpi_initialize_subsystem (
* Initialize the namespace manager and
* the root of the namespace tree
*/
-
status = acpi_ns_root_initialize ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
@@ -113,7 +113,6 @@ acpi_initialize_subsystem (
return_ACPI_STATUS (status);
}
-
/* If configured, initialize the AML debugger */
ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());
@@ -150,7 +149,8 @@ acpi_enable_subsystem (
* The values from the FADT are validated here.
*/
if (!(flags & ACPI_NO_HARDWARE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI hardware\n"));
status = acpi_hw_initialize ();
if (ACPI_FAILURE (status)) {
@@ -178,7 +178,8 @@ acpi_enable_subsystem (
* install_address_space_handler interface.
*/
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Installing default address space handlers\n"));
status = acpi_ev_install_region_handlers ();
if (ACPI_FAILURE (status)) {
@@ -189,12 +190,14 @@ acpi_enable_subsystem (
/*
* Initialize ACPI Event handling (Fixed and General Purpose)
*
- * NOTE: We must have the hardware AND events initialized before we can execute
- * ANY control methods SAFELY. Any control method can require ACPI hardware
- * support, so the hardware MUST be initialized before execution!
+ * NOTE: We must have the hardware AND events initialized before we can
+ * execute ANY control methods SAFELY. Any control method can require
+ * ACPI hardware support, so the hardware MUST be initialized before
+ * execution!
*/
if (!(flags & ACPI_NO_EVENT_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI events\n"));
status = acpi_ev_initialize_events ();
if (ACPI_FAILURE (status)) {
@@ -205,7 +208,8 @@ acpi_enable_subsystem (
/* Install the SCI handler and Global Lock handler */
if (!(flags & ACPI_NO_HANDLER_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Installing SCI/GL handlers\n"));
status = acpi_ev_install_xrupt_handlers ();
if (ACPI_FAILURE (status)) {
@@ -247,7 +251,8 @@ acpi_initialize_objects (
* contain executable AML (see call to acpi_ns_initialize_objects below).
*/
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Executing _REG op_region methods\n"));
status = acpi_ev_initialize_op_regions ();
if (ACPI_FAILURE (status)) {
@@ -261,7 +266,8 @@ acpi_initialize_objects (
* objects: operation_regions, buffer_fields, Buffers, and Packages.
*/
if (!(flags & ACPI_NO_OBJECT_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Completing Initialization of ACPI Objects\n"));
status = acpi_ns_initialize_objects ();
if (ACPI_FAILURE (status)) {
@@ -274,7 +280,8 @@ acpi_initialize_objects (
* This runs the _STA and _INI methods.
*/
if (!(flags & ACPI_NO_DEVICE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI Devices\n"));
status = acpi_ns_initialize_devices ();
if (ACPI_FAILURE (status)) {
@@ -307,7 +314,8 @@ acpi_initialize_objects (
******************************************************************************/
acpi_status
-acpi_terminate (void)
+acpi_terminate (
+ void)
{
acpi_status status;
@@ -344,8 +352,7 @@ acpi_terminate (void)
#ifdef ACPI_FUTURE_USAGE
-
-/*****************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_subsystem_status
*
@@ -354,14 +361,16 @@ acpi_terminate (void)
* RETURN: Status of the ACPI subsystem
*
* DESCRIPTION: Other drivers that use the ACPI subsystem should call this
- * before making any other calls, to ensure the subsystem initial-
- * ized successfully.
+ * before making any other calls, to ensure the subsystem
+ * initialized successfully.
*
- ****************************************************************************/
+ ******************************************************************************/
acpi_status
-acpi_subsystem_status (void)
+acpi_subsystem_status (
+ void)
{
+
if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
return (AE_OK);
}
@@ -371,13 +380,12 @@ acpi_subsystem_status (void)
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_get_system_info
*
- * PARAMETERS: out_buffer - a pointer to a buffer to receive the
- * resources for the device
- * buffer_length - the number of bytes available in the buffer
+ * PARAMETERS: out_buffer - A buffer to receive the resources for the
+ * device
*
* RETURN: Status - the status of the call
*
@@ -395,8 +403,8 @@ acpi_get_system_info (
struct acpi_buffer *out_buffer)
{
struct acpi_system_info *info_ptr;
- u32 i;
acpi_status status;
+ u32 i;
ACPI_FUNCTION_TRACE ("acpi_get_system_info");
@@ -466,6 +474,7 @@ EXPORT_SYMBOL(acpi_get_system_info);
* FUNCTION: acpi_install_initialization_handler
*
* PARAMETERS: Handler - Callback procedure
+ * Function - Not (currently) used, see below
*
* RETURN: Status
*
@@ -495,7 +504,6 @@ acpi_install_initialization_handler (
#endif /* ACPI_FUTURE_USAGE */
-
/*****************************************************************************
*
* FUNCTION: acpi_purge_cached_objects
@@ -509,7 +517,8 @@ acpi_install_initialization_handler (
****************************************************************************/
acpi_status
-acpi_purge_cached_objects (void)
+acpi_purge_cached_objects (
+ void)
{
ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 71fa1011715..2cf264fd52e 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -564,12 +564,13 @@ acpi_video_device_find_cap (struct acpi_video_device *device)
int count = 0;
union acpi_object *o;
- br = kmalloc(sizeof &br, GFP_KERNEL);
+ br = kmalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
} else {
- memset(br, 0, sizeof &br);
- br->levels = kmalloc(obj->package.count * sizeof &br->levels, GFP_KERNEL);
+ memset(br, 0, sizeof(*br));
+ br->levels = kmalloc(obj->package.count *
+ sizeof *(br->levels), GFP_KERNEL);
if (!br->levels)
goto out;
@@ -584,8 +585,7 @@ acpi_video_device_find_cap (struct acpi_video_device *device)
}
out:
if (count < 2) {
- if (br->levels)
- kfree(br->levels);
+ kfree(br->levels);
kfree(br);
} else {
br->count = count;
@@ -595,8 +595,7 @@ out:
}
}
- if (obj)
- kfree(obj);
+ kfree(obj);
return_VOID;
}
@@ -1585,7 +1584,7 @@ acpi_video_switch_output(
ACPI_FUNCTION_TRACE("acpi_video_switch_output");
list_for_each_safe(node, next, &video->video_device_list) {
- struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry);
+ dev = container_of(node, struct acpi_video_device, entry);
status = acpi_video_device_get_state(dev, &state);
if (state & 0x2){
dev_next = container_of(node->next, struct acpi_video_device, entry);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index f37a13de804..214b9643540 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -22,7 +22,6 @@
#include <linux/string.h>
#include <linux/pm.h>
-
extern struct subsystem devices_subsys;
#define to_sysdev(k) container_of(k, struct sys_device, kobj)
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 5ef9adb9fe7..bd2ec7e284c 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -40,7 +40,6 @@
#include <linux/skbuff.h>
#include <asm/io.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -895,11 +894,6 @@ static dev_link_t *bluecard_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &bluecard_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -1103,6 +1097,7 @@ static struct pcmcia_driver bluecard_driver = {
.name = "bluecard_cs",
},
.attach = bluecard_attach,
+ .event = bluecard_event,
.detach = bluecard_detach,
.id_table = bluecard_ids,
};
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 9013cd759af..adf1750ea58 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -47,7 +47,6 @@
#include <linux/device.h>
#include <linux/firmware.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -696,11 +695,6 @@ static dev_link_t *bt3c_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &bt3c_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -947,6 +941,7 @@ static struct pcmcia_driver bt3c_driver = {
.name = "bt3c_cs",
},
.attach = bt3c_attach,
+ .event = bt3c_event,
.detach = bt3c_detach,
.id_table = bt3c_ids,
};
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index c479484a1f7..e4c59fdc0e1 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -43,7 +43,6 @@
#include <asm/system.h>
#include <asm/io.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -615,11 +614,6 @@ static dev_link_t *btuart_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &btuart_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -867,6 +861,7 @@ static struct pcmcia_driver btuart_driver = {
.name = "btuart_cs",
},
.attach = btuart_attach,
+ .event = btuart_event,
.detach = btuart_detach,
.id_table = btuart_ids,
};
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index bb12f7daeb9..e39868c3da4 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -43,7 +43,6 @@
#include <asm/system.h>
#include <asm/io.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -594,11 +593,6 @@ static dev_link_t *dtl1_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &dtl1_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -820,6 +814,7 @@ static struct pcmcia_driver dtl1_driver = {
.name = "dtl1_cs",
},
.attach = dtl1_attach,
+ .event = dtl1_event,
.detach = dtl1_detach,
.id_table = dtl1_ids,
};
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 3256192dcde..f9b956fb2b8 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -120,7 +120,7 @@ static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
poll_wait(file, &hci_vhci->read_wait, wait);
- if (skb_queue_len(&hci_vhci->readq))
+ if (!skb_queue_empty(&hci_vhci->readq))
return POLLIN | POLLRDNORM;
return POLLOUT | POLLWRNORM;
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 1aff819f383..08f69287ea3 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_RIO) += rio/ generic_serial.o
-obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o
+obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
obj-$(CONFIG_MMTIMER) += mmtimer.o
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index c2b12eab67c..123417e4304 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -96,3 +96,10 @@ config DRM_SIS
chipset. If M is selected the module will be called sis. AGP
support is required for this driver to work.
+config DRM_VIA
+ tristate "Via unichrome video cards"
+ depends on DRM
+ help
+ Choose this option if you have a Via unichrome or compatible video
+ chipset. If M is selected the module will be called via.
+
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 7444dec40b9..ddd941045b1 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -18,10 +18,14 @@ i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
ffb-objs := ffb_drv.o ffb_context.o
sis-objs := sis_drv.o sis_ds.o sis_mm.o
+via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o
ifeq ($(CONFIG_COMPAT),y)
drm-objs += drm_ioc32.o
radeon-objs += radeon_ioc32.o
+mga-objs += mga_ioc32.o
+r128-objs += r128_ioc32.o
+i915-objs += i915_ioc32.o
endif
obj-$(CONFIG_DRM) += drm.o
@@ -35,4 +39,5 @@ obj-$(CONFIG_DRM_I830) += i830.o
obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_SIS) += sis.o
+obj-$(CONFIG_DRM_VIA) +=via.o
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index fdca1876ecd..0aec5ef481b 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -52,7 +52,7 @@
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
-unsigned long drm_ati_alloc_pcigart_table( void )
+static unsigned long drm_ati_alloc_pcigart_table( void )
{
unsigned long address;
struct page *page;
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 587305282ea..e8371dd87fb 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -38,7 +38,9 @@
#define _DRM_H_
#if defined(__linux__)
+#if defined(__KERNEL__)
#include <linux/config.h>
+#endif
#include <asm/ioctl.h> /* For _IO* macros */
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IOC_VOID _IOC_NONE
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index b04ddf12a0f..5df09cc8c6d 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -774,8 +774,6 @@ extern int drm_cpu_valid( void );
/* Driver support (drm_drv.h) */
extern int drm_init(struct drm_driver *driver);
extern void drm_exit(struct drm_driver *driver);
-extern int drm_version(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern long drm_compat_ioctl(struct file *filp,
@@ -785,28 +783,19 @@ extern int drm_takedown(drm_device_t * dev);
/* Device support (drm_fops.h) */
extern int drm_open(struct inode *inode, struct file *filp);
extern int drm_stub_open(struct inode *inode, struct file *filp);
-extern int drm_open_helper(struct inode *inode, struct file *filp,
- drm_device_t *dev);
extern int drm_flush(struct file *filp);
extern int drm_fasync(int fd, struct file *filp, int on);
extern int drm_release(struct inode *inode, struct file *filp);
/* Mapping support (drm_vm.h) */
-extern void drm_vm_open(struct vm_area_struct *vma);
-extern void drm_vm_close(struct vm_area_struct *vma);
-extern void drm_vm_shm_close(struct vm_area_struct *vma);
-extern int drm_mmap_dma(struct file *filp,
- struct vm_area_struct *vma);
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
-extern ssize_t drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off);
/* Memory management support (drm_memory.h) */
#include "drm_memory.h"
extern void drm_mem_init(void);
extern int drm_mem_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
-extern void *drm_calloc(size_t nmemb, size_t size, int area);
extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
int area);
extern unsigned long drm_alloc_pages(int order, int area);
@@ -854,9 +843,6 @@ extern int drm_newctx( struct inode *inode, struct file *filp,
extern int drm_rmctx( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int drm_context_switch(drm_device_t *dev, int old, int new);
-extern int drm_context_switch_complete(drm_device_t *dev, int new);
-
extern int drm_ctxbitmap_init( drm_device_t *dev );
extern void drm_ctxbitmap_cleanup( drm_device_t *dev );
extern void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle );
@@ -874,9 +860,6 @@ extern int drm_rmdraw(struct inode *inode, struct file *filp,
/* Authentication IOCTL support (drm_auth.h) */
-extern int drm_add_magic(drm_device_t *dev, drm_file_t *priv,
- drm_magic_t magic);
-extern int drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
extern int drm_getmagic(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_authmagic(struct inode *inode, struct file *filp,
@@ -893,13 +876,9 @@ extern int drm_unlock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_lock_take(__volatile__ unsigned int *lock,
unsigned int context);
-extern int drm_lock_transfer(drm_device_t *dev,
- __volatile__ unsigned int *lock,
- unsigned int context);
extern int drm_lock_free(drm_device_t *dev,
__volatile__ unsigned int *lock,
unsigned int context);
-extern int drm_notifier(void *priv);
/* Buffer management support (drm_bufs.h) */
extern int drm_order( unsigned long size );
@@ -927,7 +906,6 @@ extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
/* IRQ support (drm_irq.h) */
extern int drm_control( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int drm_irq_install( drm_device_t *dev );
extern int drm_irq_uninstall( drm_device_t *dev );
extern irqreturn_t drm_irq_handler( DRM_IRQ_ARGS );
extern void drm_driver_irq_preinstall( drm_device_t *dev );
@@ -967,7 +945,6 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM *handle);
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
struct drm_driver *driver);
extern int drm_put_dev(drm_device_t * dev);
-extern int drm_get_head(drm_device_t * dev, drm_head_t *head);
extern int drm_put_head(drm_head_t * head);
extern unsigned int drm_debug;
extern unsigned int drm_cards_limit;
@@ -1064,9 +1041,16 @@ static __inline__ void drm_free(void *pt, size_t size, int area)
{
kfree(pt);
}
+
+/** Wrapper around kcalloc() */
+static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area)
+{
+ return kcalloc(nmemb, size, GFP_KERNEL);
+}
#else
extern void *drm_alloc(size_t size, int area);
extern void drm_free(void *pt, size_t size, int area);
+extern void *drm_calloc(size_t nmemb, size_t size, int area);
#endif
/*@}*/
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
index b428761c4e9..dd140bca8f7 100644
--- a/drivers/char/drm/drm_auth.c
+++ b/drivers/char/drm/drm_auth.c
@@ -87,7 +87,7 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
* associated the magic number hash key in drm_device::magiclist, while holding
* the drm_device::struct_sem lock.
*/
-int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
{
int hash;
drm_magic_entry_t *entry;
@@ -124,7 +124,7 @@ int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_sem lock.
*/
-int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
{
drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 3407380b865..4c6191d231b 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -356,8 +356,8 @@ static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
* reallocates the buffer list of the same size order to accommodate the new
* buffers.
*/
-int drm_addbufs_agp( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int drm_addbufs_agp( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -521,8 +521,8 @@ int drm_addbufs_agp( struct inode *inode, struct file *filp,
}
#endif /* __OS_HAS_AGP */
-int drm_addbufs_pci( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int drm_addbufs_pci( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -751,8 +751,8 @@ int drm_addbufs_pci( struct inode *inode, struct file *filp,
}
-int drm_addbufs_sg( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int drm_addbufs_sg( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index fdf661f234e..a7cfabd1ca2 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -84,7 +84,7 @@ failed:
* drm_device::context_sareas to accommodate the new entry while holding the
* drm_device::struct_sem lock.
*/
-int drm_ctxbitmap_next( drm_device_t *dev )
+static int drm_ctxbitmap_next( drm_device_t *dev )
{
int bit;
@@ -326,7 +326,7 @@ int drm_context_switch( drm_device_t *dev, int old, int new )
* hardware lock is held, clears the drm_device::context_flag and wakes up
* drm_device::context_wait.
*/
-int drm_context_switch_complete( drm_device_t *dev, int new )
+static int drm_context_switch_complete( drm_device_t *dev, int new )
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
dev->last_switch = jiffies;
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 1e37ed0c6b8..3333c250c4d 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -51,8 +51,11 @@
#include "drmP.h"
#include "drm_core.h"
+static int drm_version(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
/** Ioctl table */
-drm_ioctl_desc_t drm_ioctls[] = {
+static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
@@ -447,8 +450,8 @@ module_exit( drm_core_exit );
*
* Fills in the version information in \p arg.
*/
-int drm_version( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+static int drm_version( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 906794247ae..10e64fde8d7 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -37,6 +37,8 @@
#include "drmP.h"
#include <linux/poll.h>
+static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev);
+
static int drm_setup( drm_device_t *dev )
{
int i;
@@ -251,7 +253,7 @@ int drm_release( struct inode *inode, struct file *filp )
}
}
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release)
{
dev->driver->reclaim_buffers(dev, filp);
}
@@ -259,7 +261,7 @@ int drm_release( struct inode *inode, struct file *filp )
drm_fasync( -1, filp, 0 );
down( &dev->ctxlist_sem );
- if ( !list_empty( &dev->ctxlist->head ) ) {
+ if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
drm_ctx_list_t *pos, *n;
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
@@ -341,7 +343,7 @@ EXPORT_SYMBOL(drm_release);
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
-int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
+static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
{
int minor = iminor(inode);
drm_file_t *priv;
@@ -443,9 +445,3 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
}
EXPORT_SYMBOL(drm_poll);
-
-/** No-op. */
-ssize_t drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
-{
- return 0;
-}
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index 2e236ebcf27..cdd4aecd25e 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -89,7 +89,7 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
* before and after the installation.
*/
-int drm_irq_install( drm_device_t *dev )
+static int drm_irq_install( drm_device_t *dev )
{
int ret;
unsigned long sh_flags=0;
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index d0d6fc66162..4702d863bcc 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -35,6 +35,11 @@
#include "drmP.h"
+static int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+static int drm_notifier(void *priv);
+
/**
* Lock ioctl.
*
@@ -225,8 +230,9 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
-int drm_lock_transfer(drm_device_t *dev,
- __volatile__ unsigned int *lock, unsigned int context)
+static int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context)
{
unsigned int old, new, prev;
@@ -282,7 +288,7 @@ int drm_lock_free(drm_device_t *dev,
* \return one if the signal should be delivered normally, or zero if the
* signal should be blocked.
*/
-int drm_notifier(void *priv)
+static int drm_notifier(void *priv)
{
drm_sigdata_t *s = (drm_sigdata_t *)priv;
unsigned int old, new, prev;
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index 7f53f756c05..ace3d42f440 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -65,19 +65,6 @@ int drm_mem_info(char *buf, char **start, off_t offset,
return 0;
}
-/** Wrapper around kmalloc() */
-void *drm_calloc(size_t nmemb, size_t size, int area)
-{
- void *addr;
-
- addr = kmalloc(size * nmemb, GFP_KERNEL);
- if (addr != NULL)
- memset((void *)addr, 0, size * nmemb);
-
- return addr;
-}
-EXPORT_SYMBOL(drm_calloc);
-
/** Wrapper around kmalloc() and kfree() */
void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
{
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 11c6950158b..70ca4fa55c9 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -223,3 +223,10 @@
{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
+#define viadrv_PCI_IDS \
+ {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0, 0, 0}
+
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 6e06e8c6a51..4774087d2e9 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -57,7 +57,7 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
/**
* Proc file list.
*/
-struct drm_proc_list {
+static struct drm_proc_list {
const char *name; /**< file name */
int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
} drm_proc_list[] = {
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 8ccbdef7bb3..48829a1a086 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -157,52 +157,6 @@ int drm_stub_open(struct inode *inode, struct file *filp)
return err;
}
-
-/**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
- *
- * Attempt to gets inter module "drm" information. If we are first
- * then register the character device and inter module information.
- * Try and register, if we fail to register, backout previous work.
- */
-int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
- struct drm_driver *driver)
-{
- drm_device_t *dev;
- int ret;
-
- DRM_DEBUG("\n");
-
- dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
- if (!dev)
- return -ENOMEM;
-
- pci_enable_device(pdev);
-
- if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
- printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
- goto err_g1;
- }
- if ((ret = drm_get_head(dev, &dev->primary)))
- goto err_g1;
-
- /* postinit is a required function to display the signon banner */
- /* drivers add secondary heads here if needed */
- if ((ret = dev->driver->postinit(dev, ent->driver_data)))
- goto err_g1;
-
- return 0;
-
-err_g1:
- drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
- return ret;
-}
-EXPORT_SYMBOL(drm_get_dev);
-
/**
* Get a secondary minor number.
*
@@ -214,7 +168,7 @@ EXPORT_SYMBOL(drm_get_dev);
* create the proc init entry via proc_init(). This routines assigns
* minor numbers to secondary heads of multi-headed cards
*/
-int drm_get_head(drm_device_t *dev, drm_head_t *head)
+static int drm_get_head(drm_device_t *dev, drm_head_t *head)
{
drm_head_t **heads = drm_heads;
int ret;
@@ -262,6 +216,50 @@ err_g1:
return ret;
}
+/**
+ * Register.
+ *
+ * \param pdev - PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+ struct drm_driver *driver)
+{
+ drm_device_t *dev;
+ int ret;
+
+ DRM_DEBUG("\n");
+
+ dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+ if (!dev)
+ return -ENOMEM;
+
+ pci_enable_device(pdev);
+
+ if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g1;
+ }
+ if ((ret = drm_get_head(dev, &dev->primary)))
+ goto err_g1;
+
+ /* postinit is a required function to display the signon banner */
+ /* drivers add secondary heads here if needed */
+ if ((ret = dev->driver->postinit(dev, ent->driver_data)))
+ goto err_g1;
+
+ return 0;
+
+err_g1:
+ drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+ return ret;
+}
+EXPORT_SYMBOL(drm_get_dev);
/**
* Put a device minor number.
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index fc72f30f312..621220f3f37 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -38,6 +38,8 @@
#include <linux/efi.h>
#endif
+static void drm_vm_open(struct vm_area_struct *vma);
+static void drm_vm_close(struct vm_area_struct *vma);
/**
* \c nopage method for AGP virtual memory.
@@ -163,7 +165,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
* Deletes map information if we are the last
* person to close a mapping and it's not in the global maplist.
*/
-void drm_vm_shm_close(struct vm_area_struct *vma)
+static void drm_vm_shm_close(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
@@ -399,7 +401,7 @@ static struct vm_operations_struct drm_vm_sg_ops = {
* Create a new drm_vma_entry structure as the \p vma private data entry and
* add it to drm_device::vmalist.
*/
-void drm_vm_open(struct vm_area_struct *vma)
+static void drm_vm_open(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
@@ -428,7 +430,7 @@ void drm_vm_open(struct vm_area_struct *vma)
* Search the \p vma private data entry in drm_device::vmalist, unlink it, and
* free it.
*/
-void drm_vm_close(struct vm_area_struct *vma)
+static void drm_vm_close(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
@@ -463,7 +465,7 @@ void drm_vm_close(struct vm_area_struct *vma)
* Sets the virtual memory area operations structure to vm_dma_ops, the file
* pointer, and calls vm_open().
*/
-int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 24857cc6c23..18e0b762289 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -90,16 +90,7 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
return 0;
}
-static struct file_operations i810_buffer_fops = {
- .open = drm_open,
- .flush = drm_flush,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = i810_mmap_buffers,
- .fasync = drm_fasync,
-};
-
-int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
@@ -126,6 +117,15 @@ int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
return 0;
}
+static struct file_operations i810_buffer_fops = {
+ .open = drm_open,
+ .flush = drm_flush,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = i810_mmap_buffers,
+ .fasync = drm_fasync,
+};
+
static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
{
drm_file_t *priv = filp->private_data;
@@ -1003,8 +1003,8 @@ void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
}
}
-int i810_flush_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index fa23ca454e5..1b40538d172 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -115,7 +115,6 @@ typedef struct drm_i810_private {
/* i810_dma.c */
extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
-extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
extern int i810_driver_dma_quiescent(drm_device_t *dev);
extern void i810_driver_release(drm_device_t *dev, struct file *filp);
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 98adccf8e43..dc773303586 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -92,16 +92,7 @@ static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf)
return 0;
}
-static struct file_operations i830_buffer_fops = {
- .open = drm_open,
- .flush = drm_flush,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = i830_mmap_buffers,
- .fasync = drm_fasync,
-};
-
-int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
@@ -128,6 +119,15 @@ int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
return 0;
}
+static struct file_operations i830_buffer_fops = {
+ .open = drm_open,
+ .flush = drm_flush,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = i830_mmap_buffers,
+ .fasync = drm_fasync,
+};
+
static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
{
drm_file_t *priv = filp->private_data;
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index aa80ad6a5ee..bc36be76b8b 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,7 +40,7 @@
#include "drm_pciids.h"
-int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit( struct drm_device *dev, unsigned long flags )
{
dev->counters += 4;
dev->types[6] = _DRM_STAT_IRQ;
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index d4b2d093d6a..df7746131de 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -123,8 +123,6 @@ typedef struct drm_i830_private {
/* i830_dma.c */
extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
-extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
-
/* i830_irq.c */
extern int i830_irq_emit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
index 6d7729ffe2d..a5923e5d0a7 100644
--- a/drivers/char/drm/i830_irq.c
+++ b/drivers/char/drm/i830_irq.c
@@ -54,8 +54,7 @@ irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS )
return IRQ_HANDLED;
}
-
-int i830_emit_irq(drm_device_t *dev)
+static int i830_emit_irq(drm_device_t *dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
@@ -73,7 +72,7 @@ int i830_emit_irq(drm_device_t *dev)
}
-int i830_wait_irq(drm_device_t *dev, int irq_nr)
+static int i830_wait_irq(drm_device_t *dev, int irq_nr)
{
drm_i830_private_t *dev_priv =
(drm_i830_private_t *)dev->dev_private;
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index b5903f9f142..acf9e52a950 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -32,23 +32,6 @@
#include "i915_drm.h"
#include "i915_drv.h"
-drm_ioctl_desc_t i915_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
- [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
- [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
-};
-
-int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
-
/* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time
* the head pointer changes, so that EBUSY only happens if the ring
@@ -95,7 +78,7 @@ void i915_kernel_lost_context(drm_device_t * dev)
dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
-int i915_dma_cleanup(drm_device_t * dev)
+static int i915_dma_cleanup(drm_device_t * dev)
{
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
@@ -247,7 +230,7 @@ static int i915_resume(drm_device_t * dev)
return 0;
}
-int i915_dma_init(DRM_IOCTL_ARGS)
+static int i915_dma_init(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_i915_private_t *dev_priv;
@@ -558,7 +541,7 @@ static int i915_quiescent(drm_device_t * dev)
return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
}
-int i915_flush_ioctl(DRM_IOCTL_ARGS)
+static int i915_flush_ioctl(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
@@ -567,7 +550,7 @@ int i915_flush_ioctl(DRM_IOCTL_ARGS)
return i915_quiescent(dev);
}
-int i915_batchbuffer(DRM_IOCTL_ARGS)
+static int i915_batchbuffer(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -601,7 +584,7 @@ int i915_batchbuffer(DRM_IOCTL_ARGS)
return ret;
}
-int i915_cmdbuffer(DRM_IOCTL_ARGS)
+static int i915_cmdbuffer(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -637,18 +620,7 @@ int i915_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
-int i915_do_cleanup_pageflip(drm_device_t * dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
-
- DRM_DEBUG("%s\n", __FUNCTION__);
- if (dev_priv->current_page != 0)
- i915_dispatch_flip(dev);
-
- return 0;
-}
-
-int i915_flip_bufs(DRM_IOCTL_ARGS)
+static int i915_flip_bufs(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
@@ -659,7 +631,7 @@ int i915_flip_bufs(DRM_IOCTL_ARGS)
return i915_dispatch_flip(dev);
}
-int i915_getparam(DRM_IOCTL_ARGS)
+static int i915_getparam(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -694,7 +666,7 @@ int i915_getparam(DRM_IOCTL_ARGS)
return 0;
}
-int i915_setparam(DRM_IOCTL_ARGS)
+static int i915_setparam(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -743,3 +715,19 @@ void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
}
}
+drm_ioctl_desc_t i915_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
+ [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
+ [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
+ [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
+ [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
+};
+
+int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index e6a9e1d1d28..1f59d3fc79b 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -34,7 +34,7 @@
#include "drm_pciids.h"
-int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit( struct drm_device *dev, unsigned long flags )
{
dev->counters += 4;
dev->types[6] = _DRM_STAT_IRQ;
@@ -97,6 +97,9 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = i915_compat_ioctl,
+#endif
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index fa940d64b85..9c37d2367dd 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -99,14 +99,6 @@ typedef struct drm_i915_private {
} drm_i915_private_t;
/* i915_dma.c */
-extern int i915_dma_init(DRM_IOCTL_ARGS);
-extern int i915_dma_cleanup(drm_device_t * dev);
-extern int i915_flush_ioctl(DRM_IOCTL_ARGS);
-extern int i915_batchbuffer(DRM_IOCTL_ARGS);
-extern int i915_flip_bufs(DRM_IOCTL_ARGS);
-extern int i915_getparam(DRM_IOCTL_ARGS);
-extern int i915_setparam(DRM_IOCTL_ARGS);
-extern int i915_cmdbuffer(DRM_IOCTL_ARGS);
extern void i915_kernel_lost_context(drm_device_t * dev);
extern void i915_driver_pretakedown(drm_device_t *dev);
extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
@@ -114,8 +106,6 @@ extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
/* i915_irq.c */
extern int i915_irq_emit(DRM_IOCTL_ARGS);
extern int i915_irq_wait(DRM_IOCTL_ARGS);
-extern int i915_wait_irq(drm_device_t * dev, int irq_nr);
-extern int i915_emit_irq(drm_device_t * dev);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(drm_device_t *dev);
@@ -130,6 +120,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
extern void i915_mem_release(drm_device_t * dev,
DRMFILE filp, struct mem_block *heap);
+extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
+
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
new file mode 100644
index 00000000000..fe009e1b3a3
--- /dev/null
+++ b/drivers/char/drm/i915_ioc32.c
@@ -0,0 +1,221 @@
+/**
+ * \file i915_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the i915 DRM.
+ *
+ * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Alan Hourihane 2005
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+
+typedef struct _drm_i915_batchbuffer32 {
+ int start; /* agp offset */
+ int used; /* nr bytes in use */
+ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
+ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
+ int num_cliprects; /* mulitpass with multiple cliprects? */
+ u32 cliprects; /* pointer to userspace cliprects */
+} drm_i915_batchbuffer32_t;
+
+static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_i915_batchbuffer32_t batchbuffer32;
+ drm_i915_batchbuffer_t __user *batchbuffer;
+
+ if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
+ return -EFAULT;
+
+ batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
+ if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
+ || __put_user(batchbuffer32.start, &batchbuffer->start)
+ || __put_user(batchbuffer32.used, &batchbuffer->used)
+ || __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
+ || __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
+ || __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects)
+ || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
+ &batchbuffer->cliprects))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer);
+}
+
+typedef struct _drm_i915_cmdbuffer32 {
+ u32 buf; /* pointer to userspace command buffer */
+ int sz; /* nr bytes in buf */
+ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
+ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
+ int num_cliprects; /* mulitpass with multiple cliprects? */
+ u32 cliprects; /* pointer to userspace cliprects */
+} drm_i915_cmdbuffer32_t;
+
+static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_i915_cmdbuffer32_t cmdbuffer32;
+ drm_i915_cmdbuffer_t __user *cmdbuffer;
+
+ if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
+ return -EFAULT;
+
+ cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
+ if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
+ || __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
+ &cmdbuffer->buf)
+ || __put_user(cmdbuffer32.sz, &cmdbuffer->sz)
+ || __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1)
+ || __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4)
+ || __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects)
+ || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
+ &cmdbuffer->cliprects))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer);
+}
+
+typedef struct drm_i915_irq_emit32 {
+ u32 irq_seq;
+} drm_i915_irq_emit32_t;
+
+static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_i915_irq_emit32_t req32;
+ drm_i915_irq_emit_t __user *request;
+
+ if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ return -EFAULT;
+
+ request = compat_alloc_user_space(sizeof(*request));
+ if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+ || __put_user((int __user *)(unsigned long)req32.irq_seq,
+ &request->irq_seq))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request);
+}
+typedef struct drm_i915_getparam32 {
+ int param;
+ u32 value;
+} drm_i915_getparam32_t;
+
+static int compat_i915_getparam(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_i915_getparam32_t req32;
+ drm_i915_getparam_t __user *request;
+
+ if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ return -EFAULT;
+
+ request = compat_alloc_user_space(sizeof(*request));
+ if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+ || __put_user(req32.param, &request->param)
+ || __put_user((void __user *)(unsigned long)req32.value,
+ &request->value))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_I915_GETPARAM, (unsigned long) request);
+}
+
+typedef struct drm_i915_mem_alloc32 {
+ int region;
+ int alignment;
+ int size;
+ u32 region_offset; /* offset from start of fb or agp */
+} drm_i915_mem_alloc32_t;
+
+static int compat_i915_alloc(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_i915_mem_alloc32_t req32;
+ drm_i915_mem_alloc_t __user *request;
+
+ if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+ return -EFAULT;
+
+ request = compat_alloc_user_space(sizeof(*request));
+ if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+ || __put_user(req32.region, &request->region)
+ || __put_user(req32.alignment, &request->alignment)
+ || __put_user(req32.size, &request->size)
+ || __put_user((void __user *)(unsigned long)req32.region_offset,
+ &request->region_offset))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_I915_ALLOC, (unsigned long) request);
+}
+
+
+drm_ioctl_compat_t *i915_compat_ioctls[] = {
+ [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
+ [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
+ [DRM_I915_GETPARAM] = compat_i915_getparam,
+ [DRM_I915_IRQ_EMIT] = compat_i915_irq_emit,
+ [DRM_I915_ALLOC] = compat_i915_alloc
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int nr = DRM_IOCTL_NR(cmd);
+ drm_ioctl_compat_t *fn = NULL;
+ int ret;
+
+ if (nr < DRM_COMMAND_BASE)
+ return drm_compat_ioctl(filp, cmd, arg);
+
+ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
+ fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+ lock_kernel(); /* XXX for now */
+ if (fn != NULL)
+ ret = (*fn)(filp, cmd, arg);
+ else
+ ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index a101cc9cfd7..4fa448ee846 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -56,7 +56,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_HANDLED;
}
-int i915_emit_irq(drm_device_t * dev)
+static int i915_emit_irq(drm_device_t * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
u32 ret;
@@ -76,7 +76,7 @@ int i915_emit_irq(drm_device_t * dev)
return ret;
}
-int i915_wait_irq(drm_device_t * dev, int irq_nr)
+static int i915_wait_irq(drm_device_t * dev, int irq_nr)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = 0;
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 22dab3e9d92..844cca9cb29 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -101,6 +101,9 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = mga_compat_ioctl,
+#endif
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 1d84a1eb34d..9412e2816eb 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -137,6 +137,8 @@ extern irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS );
extern void mga_driver_irq_preinstall( drm_device_t *dev );
extern void mga_driver_irq_postinstall( drm_device_t *dev );
extern void mga_driver_irq_uninstall( drm_device_t *dev );
+extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER()
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
new file mode 100644
index 00000000000..bc745cfa209
--- /dev/null
+++ b/drivers/char/drm/mga_ioc32.c
@@ -0,0 +1,167 @@
+/**
+ * \file mga_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the MGA DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "mga_drm.h"
+
+typedef struct drm32_mga_init {
+ int func;
+ u32 sarea_priv_offset;
+ int chipset;
+ int sgram;
+ unsigned int maccess;
+ unsigned int fb_cpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int back_offset, back_pitch;
+ unsigned int depth_cpp;
+ unsigned int depth_offset, depth_pitch;
+ unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+ unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ u32 fb_offset;
+ u32 mmio_offset;
+ u32 status_offset;
+ u32 warp_offset;
+ u32 primary_offset;
+ u32 buffers_offset;
+} drm_mga_init32_t;
+
+static int compat_mga_init(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_mga_init32_t init32;
+ drm_mga_init_t __user *init;
+ int err = 0, i;
+
+ if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+ return -EFAULT;
+
+ init = compat_alloc_user_space(sizeof(*init));
+ if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+ || __put_user(init32.func, &init->func)
+ || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+ || __put_user(init32.chipset, &init->chipset)
+ || __put_user(init32.sgram, &init->sgram)
+ || __put_user(init32.maccess, &init->maccess)
+ || __put_user(init32.fb_cpp, &init->fb_cpp)
+ || __put_user(init32.front_offset, &init->front_offset)
+ || __put_user(init32.front_pitch, &init->front_pitch)
+ || __put_user(init32.back_offset, &init->back_offset)
+ || __put_user(init32.back_pitch, &init->back_pitch)
+ || __put_user(init32.depth_cpp, &init->depth_cpp)
+ || __put_user(init32.depth_offset, &init->depth_offset)
+ || __put_user(init32.depth_pitch, &init->depth_pitch)
+ || __put_user(init32.fb_offset, &init->fb_offset)
+ || __put_user(init32.mmio_offset, &init->mmio_offset)
+ || __put_user(init32.status_offset, &init->status_offset)
+ || __put_user(init32.warp_offset, &init->warp_offset)
+ || __put_user(init32.primary_offset, &init->primary_offset)
+ || __put_user(init32.buffers_offset, &init->buffers_offset))
+ return -EFAULT;
+
+ for (i=0; i<MGA_NR_TEX_HEAPS; i++)
+ {
+ err |= __put_user(init32.texture_offset[i], &init->texture_offset[i]);
+ err |= __put_user(init32.texture_size[i], &init->texture_size[i]);
+ }
+ if (err)
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_MGA_INIT, (unsigned long) init);
+}
+
+
+typedef struct drm_mga_getparam32 {
+ int param;
+ u32 value;
+} drm_mga_getparam32_t;
+
+
+static int compat_mga_getparam(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_mga_getparam32_t getparam32;
+ drm_mga_getparam_t __user *getparam;
+
+ if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
+ return -EFAULT;
+
+ getparam = compat_alloc_user_space(sizeof(*getparam));
+ if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+ || __put_user(getparam32.param, &getparam->param)
+ || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+}
+
+drm_ioctl_compat_t *mga_compat_ioctls[] = {
+ [DRM_MGA_INIT] = compat_mga_init,
+ [DRM_MGA_GETPARAM] = compat_mga_getparam,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long mga_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int nr = DRM_IOCTL_NR(cmd);
+ drm_ioctl_compat_t *fn = NULL;
+ int ret;
+
+ if (nr < DRM_COMMAND_BASE)
+ return drm_compat_ioctl(filp, cmd, arg);
+
+ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
+ fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+ lock_kernel(); /* XXX for now */
+ if (fn != NULL)
+ ret = (*fn)(filp, cmd, arg);
+ else
+ ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index ced63810237..bc446da1b21 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -96,6 +96,9 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = r128_compat_ioctl,
+#endif
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index cf1aa5df459..0fb687c9505 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -156,6 +156,9 @@ extern void r128_driver_irq_uninstall( drm_device_t *dev );
extern void r128_driver_pretakedown(drm_device_t *dev);
extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
/* Register definitions, register access macros and drmAddMap constants
* for Rage 128 kernel driver.
*/
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
new file mode 100644
index 00000000000..60598ef9475
--- /dev/null
+++ b/drivers/char/drm/r128_ioc32.c
@@ -0,0 +1,219 @@
+/**
+ * \file r128_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the R128 DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "r128_drm.h"
+
+typedef struct drm_r128_init32 {
+ int func;
+ unsigned int sarea_priv_offset;
+ int is_pci;
+ int cce_mode;
+ int cce_secure;
+ int ring_size;
+ int usec_timeout;
+
+ unsigned int fb_bpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int back_offset, back_pitch;
+ unsigned int depth_bpp;
+ unsigned int depth_offset, depth_pitch;
+ unsigned int span_offset;
+
+ unsigned int fb_offset;
+ unsigned int mmio_offset;
+ unsigned int ring_offset;
+ unsigned int ring_rptr_offset;
+ unsigned int buffers_offset;
+ unsigned int agp_textures_offset;
+} drm_r128_init32_t;
+
+static int compat_r128_init(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_r128_init32_t init32;
+ drm_r128_init_t __user *init;
+
+ if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+ return -EFAULT;
+
+ init = compat_alloc_user_space(sizeof(*init));
+ if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+ || __put_user(init32.func, &init->func)
+ || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+ || __put_user(init32.is_pci, &init->is_pci)
+ || __put_user(init32.cce_mode, &init->cce_mode)
+ || __put_user(init32.cce_secure, &init->cce_secure)
+ || __put_user(init32.ring_size, &init->ring_size)
+ || __put_user(init32.usec_timeout, &init->usec_timeout)
+ || __put_user(init32.fb_bpp, &init->fb_bpp)
+ || __put_user(init32.front_offset, &init->front_offset)
+ || __put_user(init32.front_pitch, &init->front_pitch)
+ || __put_user(init32.back_offset, &init->back_offset)
+ || __put_user(init32.back_pitch, &init->back_pitch)
+ || __put_user(init32.depth_bpp, &init->depth_bpp)
+ || __put_user(init32.depth_offset, &init->depth_offset)
+ || __put_user(init32.depth_pitch, &init->depth_pitch)
+ || __put_user(init32.span_offset, &init->span_offset)
+ || __put_user(init32.fb_offset, &init->fb_offset)
+ || __put_user(init32.mmio_offset, &init->mmio_offset)
+ || __put_user(init32.ring_offset, &init->ring_offset)
+ || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
+ || __put_user(init32.buffers_offset, &init->buffers_offset)
+ || __put_user(init32.agp_textures_offset, &init->agp_textures_offset))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_R128_INIT, (unsigned long)init);
+}
+
+
+typedef struct drm_r128_depth32 {
+ int func;
+ int n;
+ u32 x;
+ u32 y;
+ u32 buffer;
+ u32 mask;
+} drm_r128_depth32_t;
+
+static int compat_r128_depth(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_r128_depth32_t depth32;
+ drm_r128_depth_t __user *depth;
+
+ if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
+ return -EFAULT;
+
+ depth = compat_alloc_user_space(sizeof(*depth));
+ if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth))
+ || __put_user(depth32.func, &depth->func)
+ || __put_user(depth32.n, &depth->n)
+ || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
+ || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
+ || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)
+ || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
+
+}
+
+typedef struct drm_r128_stipple32 {
+ u32 mask;
+} drm_r128_stipple32_t;
+
+static int compat_r128_stipple(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_r128_stipple32_t stipple32;
+ drm_r128_stipple_t __user *stipple;
+
+ if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
+ return -EFAULT;
+
+ stipple = compat_alloc_user_space(sizeof(*stipple));
+ if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
+ || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
+}
+
+typedef struct drm_r128_getparam32 {
+ int param;
+ u32 value;
+} drm_r128_getparam32_t;
+
+static int compat_r128_getparam(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_r128_getparam32_t getparam32;
+ drm_r128_getparam_t __user *getparam;
+
+ if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
+ return -EFAULT;
+
+ getparam = compat_alloc_user_space(sizeof(*getparam));
+ if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+ || __put_user(getparam32.param, &getparam->param)
+ || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+ return -EFAULT;
+
+ return drm_ioctl(file->f_dentry->d_inode, file,
+ DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+}
+
+drm_ioctl_compat_t *r128_compat_ioctls[] = {
+ [DRM_R128_INIT] = compat_r128_init,
+ [DRM_R128_DEPTH] = compat_r128_depth,
+ [DRM_R128_STIPPLE] = compat_r128_stipple,
+ [DRM_R128_GETPARAM] = compat_r128_getparam,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int nr = DRM_IOCTL_NR(cmd);
+ drm_ioctl_compat_t *fn = NULL;
+ int ret;
+
+ if (nr < DRM_COMMAND_BASE)
+ return drm_compat_ioctl(filp, cmd, arg);
+
+ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))
+ fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+ lock_kernel(); /* XXX for now */
+ if (fn != NULL)
+ ret = (*fn)(filp, cmd, arg);
+ else
+ ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index 53af6916282..426a71c049d 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1307,7 +1307,7 @@ static int r128_do_init_pageflip( drm_device_t *dev )
return 0;
}
-int r128_do_cleanup_pageflip( drm_device_t *dev )
+static int r128_do_cleanup_pageflip( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "\n" );
diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h
new file mode 100644
index 00000000000..cf61bb514db
--- /dev/null
+++ b/drivers/char/drm/via_3d_reg.h
@@ -0,0 +1,1651 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VIA_3D_REG_H
+#define VIA_3D_REG_H
+#define HC_REG_BASE 0x0400
+
+#define HC_REG_TRANS_SPACE 0x0040
+
+#define HC_ParaN_MASK 0xffffffff
+#define HC_Para_MASK 0x00ffffff
+#define HC_SubA_MASK 0xff000000
+#define HC_SubA_SHIFT 24
+/* Transmission Setting
+ */
+#define HC_REG_TRANS_SET 0x003c
+#define HC_ParaSubType_MASK 0xff000000
+#define HC_ParaType_MASK 0x00ff0000
+#define HC_ParaOS_MASK 0x0000ff00
+#define HC_ParaAdr_MASK 0x000000ff
+#define HC_ParaSubType_SHIFT 24
+#define HC_ParaType_SHIFT 16
+#define HC_ParaOS_SHIFT 8
+#define HC_ParaAdr_SHIFT 0
+
+#define HC_ParaType_CmdVdata 0x0000
+#define HC_ParaType_NotTex 0x0001
+#define HC_ParaType_Tex 0x0002
+#define HC_ParaType_Palette 0x0003
+#define HC_ParaType_PreCR 0x0010
+#define HC_ParaType_Auto 0x00fe
+
+/* Transmission Space
+ */
+#define HC_REG_Hpara0 0x0040
+#define HC_REG_HpataAF 0x02fc
+
+/* Read
+ */
+#define HC_REG_HREngSt 0x0000
+#define HC_REG_HRFIFOempty 0x0004
+#define HC_REG_HRFIFOfull 0x0008
+#define HC_REG_HRErr 0x000c
+#define HC_REG_FIFOstatus 0x0010
+/* HC_REG_HREngSt 0x0000
+ */
+#define HC_HDASZC_MASK 0x00010000
+#define HC_HSGEMI_MASK 0x0000f000
+#define HC_HLGEMISt_MASK 0x00000f00
+#define HC_HCRSt_MASK 0x00000080
+#define HC_HSE0St_MASK 0x00000040
+#define HC_HSE1St_MASK 0x00000020
+#define HC_HPESt_MASK 0x00000010
+#define HC_HXESt_MASK 0x00000008
+#define HC_HBESt_MASK 0x00000004
+#define HC_HE2St_MASK 0x00000002
+#define HC_HE3St_MASK 0x00000001
+/* HC_REG_HRFIFOempty 0x0004
+ */
+#define HC_HRZDempty_MASK 0x00000010
+#define HC_HRTXAempty_MASK 0x00000008
+#define HC_HRTXDempty_MASK 0x00000004
+#define HC_HWZDempty_MASK 0x00000002
+#define HC_HWCDempty_MASK 0x00000001
+/* HC_REG_HRFIFOfull 0x0008
+ */
+#define HC_HRZDfull_MASK 0x00000010
+#define HC_HRTXAfull_MASK 0x00000008
+#define HC_HRTXDfull_MASK 0x00000004
+#define HC_HWZDfull_MASK 0x00000002
+#define HC_HWCDfull_MASK 0x00000001
+/* HC_REG_HRErr 0x000c
+ */
+#define HC_HAGPCMErr_MASK 0x80000000
+#define HC_HAGPCMErrC_MASK 0x70000000
+/* HC_REG_FIFOstatus 0x0010
+ */
+#define HC_HRFIFOATall_MASK 0x80000000
+#define HC_HRFIFOATbusy_MASK 0x40000000
+#define HC_HRATFGMDo_MASK 0x00000100
+#define HC_HRATFGMDi_MASK 0x00000080
+#define HC_HRATFRZD_MASK 0x00000040
+#define HC_HRATFRTXA_MASK 0x00000020
+#define HC_HRATFRTXD_MASK 0x00000010
+#define HC_HRATFWZD_MASK 0x00000008
+#define HC_HRATFWCD_MASK 0x00000004
+#define HC_HRATTXTAG_MASK 0x00000002
+#define HC_HRATTXCH_MASK 0x00000001
+
+/* AGP Command Setting
+ */
+#define HC_SubA_HAGPBstL 0x0060
+#define HC_SubA_HAGPBendL 0x0061
+#define HC_SubA_HAGPCMNT 0x0062
+#define HC_SubA_HAGPBpL 0x0063
+#define HC_SubA_HAGPBpH 0x0064
+/* HC_SubA_HAGPCMNT 0x0062
+ */
+#define HC_HAGPCMNT_MASK 0x00800000
+#define HC_HCmdErrClr_MASK 0x00400000
+#define HC_HAGPBendH_MASK 0x0000ff00
+#define HC_HAGPBstH_MASK 0x000000ff
+#define HC_HAGPBendH_SHIFT 8
+#define HC_HAGPBstH_SHIFT 0
+/* HC_SubA_HAGPBpL 0x0063
+ */
+#define HC_HAGPBpL_MASK 0x00fffffc
+#define HC_HAGPBpID_MASK 0x00000003
+#define HC_HAGPBpID_PAUSE 0x00000000
+#define HC_HAGPBpID_JUMP 0x00000001
+#define HC_HAGPBpID_STOP 0x00000002
+/* HC_SubA_HAGPBpH 0x0064
+ */
+#define HC_HAGPBpH_MASK 0x00ffffff
+
+/* Miscellaneous Settings
+ */
+#define HC_SubA_HClipTB 0x0070
+#define HC_SubA_HClipLR 0x0071
+#define HC_SubA_HFPClipTL 0x0072
+#define HC_SubA_HFPClipBL 0x0073
+#define HC_SubA_HFPClipLL 0x0074
+#define HC_SubA_HFPClipRL 0x0075
+#define HC_SubA_HFPClipTBH 0x0076
+#define HC_SubA_HFPClipLRH 0x0077
+#define HC_SubA_HLP 0x0078
+#define HC_SubA_HLPRF 0x0079
+#define HC_SubA_HSolidCL 0x007a
+#define HC_SubA_HPixGC 0x007b
+#define HC_SubA_HSPXYOS 0x007c
+#define HC_SubA_HVertexCNT 0x007d
+
+#define HC_HClipT_MASK 0x00fff000
+#define HC_HClipT_SHIFT 12
+#define HC_HClipB_MASK 0x00000fff
+#define HC_HClipB_SHIFT 0
+#define HC_HClipL_MASK 0x00fff000
+#define HC_HClipL_SHIFT 12
+#define HC_HClipR_MASK 0x00000fff
+#define HC_HClipR_SHIFT 0
+#define HC_HFPClipBH_MASK 0x0000ff00
+#define HC_HFPClipBH_SHIFT 8
+#define HC_HFPClipTH_MASK 0x000000ff
+#define HC_HFPClipTH_SHIFT 0
+#define HC_HFPClipRH_MASK 0x0000ff00
+#define HC_HFPClipRH_SHIFT 8
+#define HC_HFPClipLH_MASK 0x000000ff
+#define HC_HFPClipLH_SHIFT 0
+#define HC_HSolidCH_MASK 0x000000ff
+#define HC_HPixGC_MASK 0x00800000
+#define HC_HSPXOS_MASK 0x00fff000
+#define HC_HSPXOS_SHIFT 12
+#define HC_HSPYOS_MASK 0x00000fff
+
+/* Command
+ * Command A
+ */
+#define HC_HCmdHeader_MASK 0xfe000000 /*0xffe00000 */
+#define HC_HE3Fire_MASK 0x00100000
+#define HC_HPMType_MASK 0x000f0000
+#define HC_HEFlag_MASK 0x0000e000
+#define HC_HShading_MASK 0x00001c00
+#define HC_HPMValidN_MASK 0x00000200
+#define HC_HPLEND_MASK 0x00000100
+#define HC_HVCycle_MASK 0x000000ff
+#define HC_HVCycle_Style_MASK 0x000000c0
+#define HC_HVCycle_ChgA_MASK 0x00000030
+#define HC_HVCycle_ChgB_MASK 0x0000000c
+#define HC_HVCycle_ChgC_MASK 0x00000003
+#define HC_HPMType_Point 0x00000000
+#define HC_HPMType_Line 0x00010000
+#define HC_HPMType_Tri 0x00020000
+#define HC_HPMType_TriWF 0x00040000
+#define HC_HEFlag_NoAA 0x00000000
+#define HC_HEFlag_ab 0x00008000
+#define HC_HEFlag_bc 0x00004000
+#define HC_HEFlag_ca 0x00002000
+#define HC_HShading_Solid 0x00000000
+#define HC_HShading_FlatA 0x00000400
+#define HC_HShading_FlatB 0x00000800
+#define HC_HShading_FlatC 0x00000c00
+#define HC_HShading_Gouraud 0x00001000
+#define HC_HVCycle_Full 0x00000000
+#define HC_HVCycle_AFP 0x00000040
+#define HC_HVCycle_One 0x000000c0
+#define HC_HVCycle_NewA 0x00000000
+#define HC_HVCycle_AA 0x00000010
+#define HC_HVCycle_AB 0x00000020
+#define HC_HVCycle_AC 0x00000030
+#define HC_HVCycle_NewB 0x00000000
+#define HC_HVCycle_BA 0x00000004
+#define HC_HVCycle_BB 0x00000008
+#define HC_HVCycle_BC 0x0000000c
+#define HC_HVCycle_NewC 0x00000000
+#define HC_HVCycle_CA 0x00000001
+#define HC_HVCycle_CB 0x00000002
+#define HC_HVCycle_CC 0x00000003
+
+/* Command B
+ */
+#define HC_HLPrst_MASK 0x00010000
+#define HC_HLLastP_MASK 0x00008000
+#define HC_HVPMSK_MASK 0x00007f80
+#define HC_HBFace_MASK 0x00000040
+#define HC_H2nd1VT_MASK 0x0000003f
+#define HC_HVPMSK_X 0x00004000
+#define HC_HVPMSK_Y 0x00002000
+#define HC_HVPMSK_Z 0x00001000
+#define HC_HVPMSK_W 0x00000800
+#define HC_HVPMSK_Cd 0x00000400
+#define HC_HVPMSK_Cs 0x00000200
+#define HC_HVPMSK_S 0x00000100
+#define HC_HVPMSK_T 0x00000080
+
+/* Enable Setting
+ */
+#define HC_SubA_HEnable 0x0000
+#define HC_HenTXEnvMap_MASK 0x00200000
+#define HC_HenVertexCNT_MASK 0x00100000
+#define HC_HenCPUDAZ_MASK 0x00080000
+#define HC_HenDASZWC_MASK 0x00040000
+#define HC_HenFBCull_MASK 0x00020000
+#define HC_HenCW_MASK 0x00010000
+#define HC_HenAA_MASK 0x00008000
+#define HC_HenST_MASK 0x00004000
+#define HC_HenZT_MASK 0x00002000
+#define HC_HenZW_MASK 0x00001000
+#define HC_HenAT_MASK 0x00000800
+#define HC_HenAW_MASK 0x00000400
+#define HC_HenSP_MASK 0x00000200
+#define HC_HenLP_MASK 0x00000100
+#define HC_HenTXCH_MASK 0x00000080
+#define HC_HenTXMP_MASK 0x00000040
+#define HC_HenTXPP_MASK 0x00000020
+#define HC_HenTXTR_MASK 0x00000010
+#define HC_HenCS_MASK 0x00000008
+#define HC_HenFOG_MASK 0x00000004
+#define HC_HenABL_MASK 0x00000002
+#define HC_HenDT_MASK 0x00000001
+
+/* Z Setting
+ */
+#define HC_SubA_HZWBBasL 0x0010
+#define HC_SubA_HZWBBasH 0x0011
+#define HC_SubA_HZWBType 0x0012
+#define HC_SubA_HZBiasL 0x0013
+#define HC_SubA_HZWBend 0x0014
+#define HC_SubA_HZWTMD 0x0015
+#define HC_SubA_HZWCDL 0x0016
+#define HC_SubA_HZWCTAGnum 0x0017
+#define HC_SubA_HZCYNum 0x0018
+#define HC_SubA_HZWCFire 0x0019
+/* HC_SubA_HZWBType
+ */
+#define HC_HZWBType_MASK 0x00800000
+#define HC_HZBiasedWB_MASK 0x00400000
+#define HC_HZONEasFF_MASK 0x00200000
+#define HC_HZOONEasFF_MASK 0x00100000
+#define HC_HZWBFM_MASK 0x00030000
+#define HC_HZWBLoc_MASK 0x0000c000
+#define HC_HZWBPit_MASK 0x00003fff
+#define HC_HZWBFM_16 0x00000000
+#define HC_HZWBFM_32 0x00020000
+#define HC_HZWBFM_24 0x00030000
+#define HC_HZWBLoc_Local 0x00000000
+#define HC_HZWBLoc_SyS 0x00004000
+/* HC_SubA_HZWBend
+ */
+#define HC_HZWBend_MASK 0x00ffe000
+#define HC_HZBiasH_MASK 0x000000ff
+#define HC_HZWBend_SHIFT 10
+/* HC_SubA_HZWTMD
+ */
+#define HC_HZWTMD_MASK 0x00070000
+#define HC_HEBEBias_MASK 0x00007f00
+#define HC_HZNF_MASK 0x000000ff
+#define HC_HZWTMD_NeverPass 0x00000000
+#define HC_HZWTMD_LT 0x00010000
+#define HC_HZWTMD_EQ 0x00020000
+#define HC_HZWTMD_LE 0x00030000
+#define HC_HZWTMD_GT 0x00040000
+#define HC_HZWTMD_NE 0x00050000
+#define HC_HZWTMD_GE 0x00060000
+#define HC_HZWTMD_AllPass 0x00070000
+#define HC_HEBEBias_SHIFT 8
+/* HC_SubA_HZWCDL 0x0016
+ */
+#define HC_HZWCDL_MASK 0x00ffffff
+/* HC_SubA_HZWCTAGnum 0x0017
+ */
+#define HC_HZWCTAGnum_MASK 0x00ff0000
+#define HC_HZWCTAGnum_SHIFT 16
+#define HC_HZWCDH_MASK 0x000000ff
+#define HC_HZWCDH_SHIFT 0
+/* HC_SubA_HZCYNum 0x0018
+ */
+#define HC_HZCYNum_MASK 0x00030000
+#define HC_HZCYNum_SHIFT 16
+#define HC_HZWCQWnum_MASK 0x00003fff
+#define HC_HZWCQWnum_SHIFT 0
+/* HC_SubA_HZWCFire 0x0019
+ */
+#define HC_ZWCFire_MASK 0x00010000
+#define HC_HZWCQWnumLast_MASK 0x00003fff
+#define HC_HZWCQWnumLast_SHIFT 0
+
+/* Stencil Setting
+ */
+#define HC_SubA_HSTREF 0x0023
+#define HC_SubA_HSTMD 0x0024
+/* HC_SubA_HSBFM
+ */
+#define HC_HSBFM_MASK 0x00030000
+#define HC_HSBLoc_MASK 0x0000c000
+#define HC_HSBPit_MASK 0x00003fff
+/* HC_SubA_HSTREF
+ */
+#define HC_HSTREF_MASK 0x00ff0000
+#define HC_HSTOPMSK_MASK 0x0000ff00
+#define HC_HSTBMSK_MASK 0x000000ff
+#define HC_HSTREF_SHIFT 16
+#define HC_HSTOPMSK_SHIFT 8
+/* HC_SubA_HSTMD
+ */
+#define HC_HSTMD_MASK 0x00070000
+#define HC_HSTOPSF_MASK 0x000001c0
+#define HC_HSTOPSPZF_MASK 0x00000038
+#define HC_HSTOPSPZP_MASK 0x00000007
+#define HC_HSTMD_NeverPass 0x00000000
+#define HC_HSTMD_LT 0x00010000
+#define HC_HSTMD_EQ 0x00020000
+#define HC_HSTMD_LE 0x00030000
+#define HC_HSTMD_GT 0x00040000
+#define HC_HSTMD_NE 0x00050000
+#define HC_HSTMD_GE 0x00060000
+#define HC_HSTMD_AllPass 0x00070000
+#define HC_HSTOPSF_KEEP 0x00000000
+#define HC_HSTOPSF_ZERO 0x00000040
+#define HC_HSTOPSF_REPLACE 0x00000080
+#define HC_HSTOPSF_INCRSAT 0x000000c0
+#define HC_HSTOPSF_DECRSAT 0x00000100
+#define HC_HSTOPSF_INVERT 0x00000140
+#define HC_HSTOPSF_INCR 0x00000180
+#define HC_HSTOPSF_DECR 0x000001c0
+#define HC_HSTOPSPZF_KEEP 0x00000000
+#define HC_HSTOPSPZF_ZERO 0x00000008
+#define HC_HSTOPSPZF_REPLACE 0x00000010
+#define HC_HSTOPSPZF_INCRSAT 0x00000018
+#define HC_HSTOPSPZF_DECRSAT 0x00000020
+#define HC_HSTOPSPZF_INVERT 0x00000028
+#define HC_HSTOPSPZF_INCR 0x00000030
+#define HC_HSTOPSPZF_DECR 0x00000038
+#define HC_HSTOPSPZP_KEEP 0x00000000
+#define HC_HSTOPSPZP_ZERO 0x00000001
+#define HC_HSTOPSPZP_REPLACE 0x00000002
+#define HC_HSTOPSPZP_INCRSAT 0x00000003
+#define HC_HSTOPSPZP_DECRSAT 0x00000004
+#define HC_HSTOPSPZP_INVERT 0x00000005
+#define HC_HSTOPSPZP_INCR 0x00000006
+#define HC_HSTOPSPZP_DECR 0x00000007
+
+/* Alpha Setting
+ */
+#define HC_SubA_HABBasL 0x0030
+#define HC_SubA_HABBasH 0x0031
+#define HC_SubA_HABFM 0x0032
+#define HC_SubA_HATMD 0x0033
+#define HC_SubA_HABLCsat 0x0034
+#define HC_SubA_HABLCop 0x0035
+#define HC_SubA_HABLAsat 0x0036
+#define HC_SubA_HABLAop 0x0037
+#define HC_SubA_HABLRCa 0x0038
+#define HC_SubA_HABLRFCa 0x0039
+#define HC_SubA_HABLRCbias 0x003a
+#define HC_SubA_HABLRCb 0x003b
+#define HC_SubA_HABLRFCb 0x003c
+#define HC_SubA_HABLRAa 0x003d
+#define HC_SubA_HABLRAb 0x003e
+/* HC_SubA_HABFM
+ */
+#define HC_HABFM_MASK 0x00030000
+#define HC_HABLoc_MASK 0x0000c000
+#define HC_HABPit_MASK 0x000007ff
+/* HC_SubA_HATMD
+ */
+#define HC_HATMD_MASK 0x00000700
+#define HC_HATREF_MASK 0x000000ff
+#define HC_HATMD_NeverPass 0x00000000
+#define HC_HATMD_LT 0x00000100
+#define HC_HATMD_EQ 0x00000200
+#define HC_HATMD_LE 0x00000300
+#define HC_HATMD_GT 0x00000400
+#define HC_HATMD_NE 0x00000500
+#define HC_HATMD_GE 0x00000600
+#define HC_HATMD_AllPass 0x00000700
+/* HC_SubA_HABLCsat
+ */
+#define HC_HABLCsat_MASK 0x00010000
+#define HC_HABLCa_MASK 0x0000fc00
+#define HC_HABLCa_C_MASK 0x0000c000
+#define HC_HABLCa_OPC_MASK 0x00003c00
+#define HC_HABLFCa_MASK 0x000003f0
+#define HC_HABLFCa_C_MASK 0x00000300
+#define HC_HABLFCa_OPC_MASK 0x000000f0
+#define HC_HABLCbias_MASK 0x0000000f
+#define HC_HABLCbias_C_MASK 0x00000008
+#define HC_HABLCbias_OPC_MASK 0x00000007
+/*-- Define the input color.
+ */
+#define HC_XC_Csrc 0x00000000
+#define HC_XC_Cdst 0x00000001
+#define HC_XC_Asrc 0x00000002
+#define HC_XC_Adst 0x00000003
+#define HC_XC_Fog 0x00000004
+#define HC_XC_HABLRC 0x00000005
+#define HC_XC_minSrcDst 0x00000006
+#define HC_XC_maxSrcDst 0x00000007
+#define HC_XC_mimAsrcInvAdst 0x00000008
+#define HC_XC_OPC 0x00000000
+#define HC_XC_InvOPC 0x00000010
+#define HC_XC_OPCp5 0x00000020
+/*-- Define the input Alpha
+ */
+#define HC_XA_OPA 0x00000000
+#define HC_XA_InvOPA 0x00000010
+#define HC_XA_OPAp5 0x00000020
+#define HC_XA_0 0x00000000
+#define HC_XA_Asrc 0x00000001
+#define HC_XA_Adst 0x00000002
+#define HC_XA_Fog 0x00000003
+#define HC_XA_minAsrcFog 0x00000004
+#define HC_XA_minAsrcAdst 0x00000005
+#define HC_XA_maxAsrcFog 0x00000006
+#define HC_XA_maxAsrcAdst 0x00000007
+#define HC_XA_HABLRA 0x00000008
+#define HC_XA_minAsrcInvAdst 0x00000008
+#define HC_XA_HABLFRA 0x00000009
+/*--
+ */
+#define HC_HABLCa_OPC (HC_XC_OPC << 10)
+#define HC_HABLCa_InvOPC (HC_XC_InvOPC << 10)
+#define HC_HABLCa_OPCp5 (HC_XC_OPCp5 << 10)
+#define HC_HABLCa_Csrc (HC_XC_Csrc << 10)
+#define HC_HABLCa_Cdst (HC_XC_Cdst << 10)
+#define HC_HABLCa_Asrc (HC_XC_Asrc << 10)
+#define HC_HABLCa_Adst (HC_XC_Adst << 10)
+#define HC_HABLCa_Fog (HC_XC_Fog << 10)
+#define HC_HABLCa_HABLRCa (HC_XC_HABLRC << 10)
+#define HC_HABLCa_minSrcDst (HC_XC_minSrcDst << 10)
+#define HC_HABLCa_maxSrcDst (HC_XC_maxSrcDst << 10)
+#define HC_HABLFCa_OPC (HC_XC_OPC << 4)
+#define HC_HABLFCa_InvOPC (HC_XC_InvOPC << 4)
+#define HC_HABLFCa_OPCp5 (HC_XC_OPCp5 << 4)
+#define HC_HABLFCa_Csrc (HC_XC_Csrc << 4)
+#define HC_HABLFCa_Cdst (HC_XC_Cdst << 4)
+#define HC_HABLFCa_Asrc (HC_XC_Asrc << 4)
+#define HC_HABLFCa_Adst (HC_XC_Adst << 4)
+#define HC_HABLFCa_Fog (HC_XC_Fog << 4)
+#define HC_HABLFCa_HABLRCa (HC_XC_HABLRC << 4)
+#define HC_HABLFCa_minSrcDst (HC_XC_minSrcDst << 4)
+#define HC_HABLFCa_maxSrcDst (HC_XC_maxSrcDst << 4)
+#define HC_HABLFCa_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 4)
+#define HC_HABLCbias_HABLRCbias 0x00000000
+#define HC_HABLCbias_Asrc 0x00000001
+#define HC_HABLCbias_Adst 0x00000002
+#define HC_HABLCbias_Fog 0x00000003
+#define HC_HABLCbias_Cin 0x00000004
+/* HC_SubA_HABLCop 0x0035
+ */
+#define HC_HABLdot_MASK 0x00010000
+#define HC_HABLCop_MASK 0x00004000
+#define HC_HABLCb_MASK 0x00003f00
+#define HC_HABLCb_C_MASK 0x00003000
+#define HC_HABLCb_OPC_MASK 0x00000f00
+#define HC_HABLFCb_MASK 0x000000fc
+#define HC_HABLFCb_C_MASK 0x000000c0
+#define HC_HABLFCb_OPC_MASK 0x0000003c
+#define HC_HABLCshift_MASK 0x00000003
+#define HC_HABLCb_OPC (HC_XC_OPC << 8)
+#define HC_HABLCb_InvOPC (HC_XC_InvOPC << 8)
+#define HC_HABLCb_OPCp5 (HC_XC_OPCp5 << 8)
+#define HC_HABLCb_Csrc (HC_XC_Csrc << 8)
+#define HC_HABLCb_Cdst (HC_XC_Cdst << 8)
+#define HC_HABLCb_Asrc (HC_XC_Asrc << 8)
+#define HC_HABLCb_Adst (HC_XC_Adst << 8)
+#define HC_HABLCb_Fog (HC_XC_Fog << 8)
+#define HC_HABLCb_HABLRCa (HC_XC_HABLRC << 8)
+#define HC_HABLCb_minSrcDst (HC_XC_minSrcDst << 8)
+#define HC_HABLCb_maxSrcDst (HC_XC_maxSrcDst << 8)
+#define HC_HABLFCb_OPC (HC_XC_OPC << 2)
+#define HC_HABLFCb_InvOPC (HC_XC_InvOPC << 2)
+#define HC_HABLFCb_OPCp5 (HC_XC_OPCp5 << 2)
+#define HC_HABLFCb_Csrc (HC_XC_Csrc << 2)
+#define HC_HABLFCb_Cdst (HC_XC_Cdst << 2)
+#define HC_HABLFCb_Asrc (HC_XC_Asrc << 2)
+#define HC_HABLFCb_Adst (HC_XC_Adst << 2)
+#define HC_HABLFCb_Fog (HC_XC_Fog << 2)
+#define HC_HABLFCb_HABLRCb (HC_XC_HABLRC << 2)
+#define HC_HABLFCb_minSrcDst (HC_XC_minSrcDst << 2)
+#define HC_HABLFCb_maxSrcDst (HC_XC_maxSrcDst << 2)
+#define HC_HABLFCb_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 2)
+/* HC_SubA_HABLAsat 0x0036
+ */
+#define HC_HABLAsat_MASK 0x00010000
+#define HC_HABLAa_MASK 0x0000fc00
+#define HC_HABLAa_A_MASK 0x0000c000
+#define HC_HABLAa_OPA_MASK 0x00003c00
+#define HC_HABLFAa_MASK 0x000003f0
+#define HC_HABLFAa_A_MASK 0x00000300
+#define HC_HABLFAa_OPA_MASK 0x000000f0
+#define HC_HABLAbias_MASK 0x0000000f
+#define HC_HABLAbias_A_MASK 0x00000008
+#define HC_HABLAbias_OPA_MASK 0x00000007
+#define HC_HABLAa_OPA (HC_XA_OPA << 10)
+#define HC_HABLAa_InvOPA (HC_XA_InvOPA << 10)
+#define HC_HABLAa_OPAp5 (HC_XA_OPAp5 << 10)
+#define HC_HABLAa_0 (HC_XA_0 << 10)
+#define HC_HABLAa_Asrc (HC_XA_Asrc << 10)
+#define HC_HABLAa_Adst (HC_XA_Adst << 10)
+#define HC_HABLAa_Fog (HC_XA_Fog << 10)
+#define HC_HABLAa_minAsrcFog (HC_XA_minAsrcFog << 10)
+#define HC_HABLAa_minAsrcAdst (HC_XA_minAsrcAdst << 10)
+#define HC_HABLAa_maxAsrcFog (HC_XA_maxAsrcFog << 10)
+#define HC_HABLAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 10)
+#define HC_HABLAa_HABLRA (HC_XA_HABLRA << 10)
+#define HC_HABLFAa_OPA (HC_XA_OPA << 4)
+#define HC_HABLFAa_InvOPA (HC_XA_InvOPA << 4)
+#define HC_HABLFAa_OPAp5 (HC_XA_OPAp5 << 4)
+#define HC_HABLFAa_0 (HC_XA_0 << 4)
+#define HC_HABLFAa_Asrc (HC_XA_Asrc << 4)
+#define HC_HABLFAa_Adst (HC_XA_Adst << 4)
+#define HC_HABLFAa_Fog (HC_XA_Fog << 4)
+#define HC_HABLFAa_minAsrcFog (HC_XA_minAsrcFog << 4)
+#define HC_HABLFAa_minAsrcAdst (HC_XA_minAsrcAdst << 4)
+#define HC_HABLFAa_maxAsrcFog (HC_XA_maxAsrcFog << 4)
+#define HC_HABLFAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 4)
+#define HC_HABLFAa_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 4)
+#define HC_HABLFAa_HABLFRA (HC_XA_HABLFRA << 4)
+#define HC_HABLAbias_HABLRAbias 0x00000000
+#define HC_HABLAbias_Asrc 0x00000001
+#define HC_HABLAbias_Adst 0x00000002
+#define HC_HABLAbias_Fog 0x00000003
+#define HC_HABLAbias_Aaa 0x00000004
+/* HC_SubA_HABLAop 0x0037
+ */
+#define HC_HABLAop_MASK 0x00004000
+#define HC_HABLAb_MASK 0x00003f00
+#define HC_HABLAb_OPA_MASK 0x00000f00
+#define HC_HABLFAb_MASK 0x000000fc
+#define HC_HABLFAb_OPA_MASK 0x0000003c
+#define HC_HABLAshift_MASK 0x00000003
+#define HC_HABLAb_OPA (HC_XA_OPA << 8)
+#define HC_HABLAb_InvOPA (HC_XA_InvOPA << 8)
+#define HC_HABLAb_OPAp5 (HC_XA_OPAp5 << 8)
+#define HC_HABLAb_0 (HC_XA_0 << 8)
+#define HC_HABLAb_Asrc (HC_XA_Asrc << 8)
+#define HC_HABLAb_Adst (HC_XA_Adst << 8)
+#define HC_HABLAb_Fog (HC_XA_Fog << 8)
+#define HC_HABLAb_minAsrcFog (HC_XA_minAsrcFog << 8)
+#define HC_HABLAb_minAsrcAdst (HC_XA_minAsrcAdst << 8)
+#define HC_HABLAb_maxAsrcFog (HC_XA_maxAsrcFog << 8)
+#define HC_HABLAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 8)
+#define HC_HABLAb_HABLRA (HC_XA_HABLRA << 8)
+#define HC_HABLFAb_OPA (HC_XA_OPA << 2)
+#define HC_HABLFAb_InvOPA (HC_XA_InvOPA << 2)
+#define HC_HABLFAb_OPAp5 (HC_XA_OPAp5 << 2)
+#define HC_HABLFAb_0 (HC_XA_0 << 2)
+#define HC_HABLFAb_Asrc (HC_XA_Asrc << 2)
+#define HC_HABLFAb_Adst (HC_XA_Adst << 2)
+#define HC_HABLFAb_Fog (HC_XA_Fog << 2)
+#define HC_HABLFAb_minAsrcFog (HC_XA_minAsrcFog << 2)
+#define HC_HABLFAb_minAsrcAdst (HC_XA_minAsrcAdst << 2)
+#define HC_HABLFAb_maxAsrcFog (HC_XA_maxAsrcFog << 2)
+#define HC_HABLFAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 2)
+#define HC_HABLFAb_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 2)
+#define HC_HABLFAb_HABLFRA (HC_XA_HABLFRA << 2)
+/* HC_SubA_HABLRAa 0x003d
+ */
+#define HC_HABLRAa_MASK 0x00ff0000
+#define HC_HABLRFAa_MASK 0x0000ff00
+#define HC_HABLRAbias_MASK 0x000000ff
+#define HC_HABLRAa_SHIFT 16
+#define HC_HABLRFAa_SHIFT 8
+/* HC_SubA_HABLRAb 0x003e
+ */
+#define HC_HABLRAb_MASK 0x0000ff00
+#define HC_HABLRFAb_MASK 0x000000ff
+#define HC_HABLRAb_SHIFT 8
+
+/* Destination Setting
+ */
+#define HC_SubA_HDBBasL 0x0040
+#define HC_SubA_HDBBasH 0x0041
+#define HC_SubA_HDBFM 0x0042
+#define HC_SubA_HFBBMSKL 0x0043
+#define HC_SubA_HROP 0x0044
+/* HC_SubA_HDBFM 0x0042
+ */
+#define HC_HDBFM_MASK 0x001f0000
+#define HC_HDBLoc_MASK 0x0000c000
+#define HC_HDBPit_MASK 0x00003fff
+#define HC_HDBFM_RGB555 0x00000000
+#define HC_HDBFM_RGB565 0x00010000
+#define HC_HDBFM_ARGB4444 0x00020000
+#define HC_HDBFM_ARGB1555 0x00030000
+#define HC_HDBFM_BGR555 0x00040000
+#define HC_HDBFM_BGR565 0x00050000
+#define HC_HDBFM_ABGR4444 0x00060000
+#define HC_HDBFM_ABGR1555 0x00070000
+#define HC_HDBFM_ARGB0888 0x00080000
+#define HC_HDBFM_ARGB8888 0x00090000
+#define HC_HDBFM_ABGR0888 0x000a0000
+#define HC_HDBFM_ABGR8888 0x000b0000
+#define HC_HDBLoc_Local 0x00000000
+#define HC_HDBLoc_Sys 0x00004000
+/* HC_SubA_HROP 0x0044
+ */
+#define HC_HROP_MASK 0x00000f00
+#define HC_HFBBMSKH_MASK 0x000000ff
+#define HC_HROP_BLACK 0x00000000
+#define HC_HROP_DPon 0x00000100
+#define HC_HROP_DPna 0x00000200
+#define HC_HROP_Pn 0x00000300
+#define HC_HROP_PDna 0x00000400
+#define HC_HROP_Dn 0x00000500
+#define HC_HROP_DPx 0x00000600
+#define HC_HROP_DPan 0x00000700
+#define HC_HROP_DPa 0x00000800
+#define HC_HROP_DPxn 0x00000900
+#define HC_HROP_D 0x00000a00
+#define HC_HROP_DPno 0x00000b00
+#define HC_HROP_P 0x00000c00
+#define HC_HROP_PDno 0x00000d00
+#define HC_HROP_DPo 0x00000e00
+#define HC_HROP_WHITE 0x00000f00
+
+/* Fog Setting
+ */
+#define HC_SubA_HFogLF 0x0050
+#define HC_SubA_HFogCL 0x0051
+#define HC_SubA_HFogCH 0x0052
+#define HC_SubA_HFogStL 0x0053
+#define HC_SubA_HFogStH 0x0054
+#define HC_SubA_HFogOOdMF 0x0055
+#define HC_SubA_HFogOOdEF 0x0056
+#define HC_SubA_HFogEndL 0x0057
+#define HC_SubA_HFogDenst 0x0058
+/* HC_SubA_FogLF 0x0050
+ */
+#define HC_FogLF_MASK 0x00000010
+#define HC_FogEq_MASK 0x00000008
+#define HC_FogMD_MASK 0x00000007
+#define HC_FogMD_LocalFog 0x00000000
+#define HC_FogMD_LinearFog 0x00000002
+#define HC_FogMD_ExponentialFog 0x00000004
+#define HC_FogMD_Exponential2Fog 0x00000005
+/* #define HC_FogMD_FogTable 0x00000003 */
+
+/* HC_SubA_HFogDenst 0x0058
+ */
+#define HC_FogDenst_MASK 0x001fff00
+#define HC_FogEndL_MASK 0x000000ff
+
+/* Texture subtype definitions
+ */
+#define HC_SubType_Tex0 0x00000000
+#define HC_SubType_Tex1 0x00000001
+#define HC_SubType_TexGeneral 0x000000fe
+
+/* Attribute of texture n
+ */
+#define HC_SubA_HTXnL0BasL 0x0000
+#define HC_SubA_HTXnL1BasL 0x0001
+#define HC_SubA_HTXnL2BasL 0x0002
+#define HC_SubA_HTXnL3BasL 0x0003
+#define HC_SubA_HTXnL4BasL 0x0004
+#define HC_SubA_HTXnL5BasL 0x0005
+#define HC_SubA_HTXnL6BasL 0x0006
+#define HC_SubA_HTXnL7BasL 0x0007
+#define HC_SubA_HTXnL8BasL 0x0008
+#define HC_SubA_HTXnL9BasL 0x0009
+#define HC_SubA_HTXnLaBasL 0x000a
+#define HC_SubA_HTXnLbBasL 0x000b
+#define HC_SubA_HTXnLcBasL 0x000c
+#define HC_SubA_HTXnLdBasL 0x000d
+#define HC_SubA_HTXnLeBasL 0x000e
+#define HC_SubA_HTXnLfBasL 0x000f
+#define HC_SubA_HTXnL10BasL 0x0010
+#define HC_SubA_HTXnL11BasL 0x0011
+#define HC_SubA_HTXnL012BasH 0x0020
+#define HC_SubA_HTXnL345BasH 0x0021
+#define HC_SubA_HTXnL678BasH 0x0022
+#define HC_SubA_HTXnL9abBasH 0x0023
+#define HC_SubA_HTXnLcdeBasH 0x0024
+#define HC_SubA_HTXnLf1011BasH 0x0025
+#define HC_SubA_HTXnL0Pit 0x002b
+#define HC_SubA_HTXnL1Pit 0x002c
+#define HC_SubA_HTXnL2Pit 0x002d
+#define HC_SubA_HTXnL3Pit 0x002e
+#define HC_SubA_HTXnL4Pit 0x002f
+#define HC_SubA_HTXnL5Pit 0x0030
+#define HC_SubA_HTXnL6Pit 0x0031
+#define HC_SubA_HTXnL7Pit 0x0032
+#define HC_SubA_HTXnL8Pit 0x0033
+#define HC_SubA_HTXnL9Pit 0x0034
+#define HC_SubA_HTXnLaPit 0x0035
+#define HC_SubA_HTXnLbPit 0x0036
+#define HC_SubA_HTXnLcPit 0x0037
+#define HC_SubA_HTXnLdPit 0x0038
+#define HC_SubA_HTXnLePit 0x0039
+#define HC_SubA_HTXnLfPit 0x003a
+#define HC_SubA_HTXnL10Pit 0x003b
+#define HC_SubA_HTXnL11Pit 0x003c
+#define HC_SubA_HTXnL0_5WE 0x004b
+#define HC_SubA_HTXnL6_bWE 0x004c
+#define HC_SubA_HTXnLc_11WE 0x004d
+#define HC_SubA_HTXnL0_5HE 0x0051
+#define HC_SubA_HTXnL6_bHE 0x0052
+#define HC_SubA_HTXnLc_11HE 0x0053
+#define HC_SubA_HTXnL0OS 0x0077
+#define HC_SubA_HTXnTB 0x0078
+#define HC_SubA_HTXnMPMD 0x0079
+#define HC_SubA_HTXnCLODu 0x007a
+#define HC_SubA_HTXnFM 0x007b
+#define HC_SubA_HTXnTRCH 0x007c
+#define HC_SubA_HTXnTRCL 0x007d
+#define HC_SubA_HTXnTBC 0x007e
+#define HC_SubA_HTXnTRAH 0x007f
+#define HC_SubA_HTXnTBLCsat 0x0080
+#define HC_SubA_HTXnTBLCop 0x0081
+#define HC_SubA_HTXnTBLMPfog 0x0082
+#define HC_SubA_HTXnTBLAsat 0x0083
+#define HC_SubA_HTXnTBLRCa 0x0085
+#define HC_SubA_HTXnTBLRCb 0x0086
+#define HC_SubA_HTXnTBLRCc 0x0087
+#define HC_SubA_HTXnTBLRCbias 0x0088
+#define HC_SubA_HTXnTBLRAa 0x0089
+#define HC_SubA_HTXnTBLRFog 0x008a
+#define HC_SubA_HTXnBumpM00 0x0090
+#define HC_SubA_HTXnBumpM01 0x0091
+#define HC_SubA_HTXnBumpM10 0x0092
+#define HC_SubA_HTXnBumpM11 0x0093
+#define HC_SubA_HTXnLScale 0x0094
+#define HC_SubA_HTXSMD 0x0000
+/* HC_SubA_HTXnL012BasH 0x0020
+ */
+#define HC_HTXnL0BasH_MASK 0x000000ff
+#define HC_HTXnL1BasH_MASK 0x0000ff00
+#define HC_HTXnL2BasH_MASK 0x00ff0000
+#define HC_HTXnL1BasH_SHIFT 8
+#define HC_HTXnL2BasH_SHIFT 16
+/* HC_SubA_HTXnL345BasH 0x0021
+ */
+#define HC_HTXnL3BasH_MASK 0x000000ff
+#define HC_HTXnL4BasH_MASK 0x0000ff00
+#define HC_HTXnL5BasH_MASK 0x00ff0000
+#define HC_HTXnL4BasH_SHIFT 8
+#define HC_HTXnL5BasH_SHIFT 16
+/* HC_SubA_HTXnL678BasH 0x0022
+ */
+#define HC_HTXnL6BasH_MASK 0x000000ff
+#define HC_HTXnL7BasH_MASK 0x0000ff00
+#define HC_HTXnL8BasH_MASK 0x00ff0000
+#define HC_HTXnL7BasH_SHIFT 8
+#define HC_HTXnL8BasH_SHIFT 16
+/* HC_SubA_HTXnL9abBasH 0x0023
+ */
+#define HC_HTXnL9BasH_MASK 0x000000ff
+#define HC_HTXnLaBasH_MASK 0x0000ff00
+#define HC_HTXnLbBasH_MASK 0x00ff0000
+#define HC_HTXnLaBasH_SHIFT 8
+#define HC_HTXnLbBasH_SHIFT 16
+/* HC_SubA_HTXnLcdeBasH 0x0024
+ */
+#define HC_HTXnLcBasH_MASK 0x000000ff
+#define HC_HTXnLdBasH_MASK 0x0000ff00
+#define HC_HTXnLeBasH_MASK 0x00ff0000
+#define HC_HTXnLdBasH_SHIFT 8
+#define HC_HTXnLeBasH_SHIFT 16
+/* HC_SubA_HTXnLcdeBasH 0x0025
+ */
+#define HC_HTXnLfBasH_MASK 0x000000ff
+#define HC_HTXnL10BasH_MASK 0x0000ff00
+#define HC_HTXnL11BasH_MASK 0x00ff0000
+#define HC_HTXnL10BasH_SHIFT 8
+#define HC_HTXnL11BasH_SHIFT 16
+/* HC_SubA_HTXnL0Pit 0x002b
+ */
+#define HC_HTXnLnPit_MASK 0x00003fff
+#define HC_HTXnEnPit_MASK 0x00080000
+#define HC_HTXnLnPitE_MASK 0x00f00000
+#define HC_HTXnLnPitE_SHIFT 20
+/* HC_SubA_HTXnL0_5WE 0x004b
+ */
+#define HC_HTXnL0WE_MASK 0x0000000f
+#define HC_HTXnL1WE_MASK 0x000000f0
+#define HC_HTXnL2WE_MASK 0x00000f00
+#define HC_HTXnL3WE_MASK 0x0000f000
+#define HC_HTXnL4WE_MASK 0x000f0000
+#define HC_HTXnL5WE_MASK 0x00f00000
+#define HC_HTXnL1WE_SHIFT 4
+#define HC_HTXnL2WE_SHIFT 8
+#define HC_HTXnL3WE_SHIFT 12
+#define HC_HTXnL4WE_SHIFT 16
+#define HC_HTXnL5WE_SHIFT 20
+/* HC_SubA_HTXnL6_bWE 0x004c
+ */
+#define HC_HTXnL6WE_MASK 0x0000000f
+#define HC_HTXnL7WE_MASK 0x000000f0
+#define HC_HTXnL8WE_MASK 0x00000f00
+#define HC_HTXnL9WE_MASK 0x0000f000
+#define HC_HTXnLaWE_MASK 0x000f0000
+#define HC_HTXnLbWE_MASK 0x00f00000
+#define HC_HTXnL7WE_SHIFT 4
+#define HC_HTXnL8WE_SHIFT 8
+#define HC_HTXnL9WE_SHIFT 12
+#define HC_HTXnLaWE_SHIFT 16
+#define HC_HTXnLbWE_SHIFT 20
+/* HC_SubA_HTXnLc_11WE 0x004d
+ */
+#define HC_HTXnLcWE_MASK 0x0000000f
+#define HC_HTXnLdWE_MASK 0x000000f0
+#define HC_HTXnLeWE_MASK 0x00000f00
+#define HC_HTXnLfWE_MASK 0x0000f000
+#define HC_HTXnL10WE_MASK 0x000f0000
+#define HC_HTXnL11WE_MASK 0x00f00000
+#define HC_HTXnLdWE_SHIFT 4
+#define HC_HTXnLeWE_SHIFT 8
+#define HC_HTXnLfWE_SHIFT 12
+#define HC_HTXnL10WE_SHIFT 16
+#define HC_HTXnL11WE_SHIFT 20
+/* HC_SubA_HTXnL0_5HE 0x0051
+ */
+#define HC_HTXnL0HE_MASK 0x0000000f
+#define HC_HTXnL1HE_MASK 0x000000f0
+#define HC_HTXnL2HE_MASK 0x00000f00
+#define HC_HTXnL3HE_MASK 0x0000f000
+#define HC_HTXnL4HE_MASK 0x000f0000
+#define HC_HTXnL5HE_MASK 0x00f00000
+#define HC_HTXnL1HE_SHIFT 4
+#define HC_HTXnL2HE_SHIFT 8
+#define HC_HTXnL3HE_SHIFT 12
+#define HC_HTXnL4HE_SHIFT 16
+#define HC_HTXnL5HE_SHIFT 20
+/* HC_SubA_HTXnL6_bHE 0x0052
+ */
+#define HC_HTXnL6HE_MASK 0x0000000f
+#define HC_HTXnL7HE_MASK 0x000000f0
+#define HC_HTXnL8HE_MASK 0x00000f00
+#define HC_HTXnL9HE_MASK 0x0000f000
+#define HC_HTXnLaHE_MASK 0x000f0000
+#define HC_HTXnLbHE_MASK 0x00f00000
+#define HC_HTXnL7HE_SHIFT 4
+#define HC_HTXnL8HE_SHIFT 8
+#define HC_HTXnL9HE_SHIFT 12
+#define HC_HTXnLaHE_SHIFT 16
+#define HC_HTXnLbHE_SHIFT 20
+/* HC_SubA_HTXnLc_11HE 0x0053
+ */
+#define HC_HTXnLcHE_MASK 0x0000000f
+#define HC_HTXnLdHE_MASK 0x000000f0
+#define HC_HTXnLeHE_MASK 0x00000f00
+#define HC_HTXnLfHE_MASK 0x0000f000
+#define HC_HTXnL10HE_MASK 0x000f0000
+#define HC_HTXnL11HE_MASK 0x00f00000
+#define HC_HTXnLdHE_SHIFT 4
+#define HC_HTXnLeHE_SHIFT 8
+#define HC_HTXnLfHE_SHIFT 12
+#define HC_HTXnL10HE_SHIFT 16
+#define HC_HTXnL11HE_SHIFT 20
+/* HC_SubA_HTXnL0OS 0x0077
+ */
+#define HC_HTXnL0OS_MASK 0x003ff000
+#define HC_HTXnLVmax_MASK 0x00000fc0
+#define HC_HTXnLVmin_MASK 0x0000003f
+#define HC_HTXnL0OS_SHIFT 12
+#define HC_HTXnLVmax_SHIFT 6
+/* HC_SubA_HTXnTB 0x0078
+ */
+#define HC_HTXnTB_MASK 0x00f00000
+#define HC_HTXnFLSe_MASK 0x0000e000
+#define HC_HTXnFLSs_MASK 0x00001c00
+#define HC_HTXnFLTe_MASK 0x00000380
+#define HC_HTXnFLTs_MASK 0x00000070
+#define HC_HTXnFLDs_MASK 0x0000000f
+#define HC_HTXnTB_NoTB 0x00000000
+#define HC_HTXnTB_TBC_S 0x00100000
+#define HC_HTXnTB_TBC_T 0x00200000
+#define HC_HTXnTB_TB_S 0x00400000
+#define HC_HTXnTB_TB_T 0x00800000
+#define HC_HTXnFLSe_Nearest 0x00000000
+#define HC_HTXnFLSe_Linear 0x00002000
+#define HC_HTXnFLSe_NonLinear 0x00004000
+#define HC_HTXnFLSe_Sharp 0x00008000
+#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000
+#define HC_HTXnFLSs_Nearest 0x00000000
+#define HC_HTXnFLSs_Linear 0x00000400
+#define HC_HTXnFLSs_NonLinear 0x00000800
+#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800
+#define HC_HTXnFLTe_Nearest 0x00000000
+#define HC_HTXnFLTe_Linear 0x00000080
+#define HC_HTXnFLTe_NonLinear 0x00000100
+#define HC_HTXnFLTe_Sharp 0x00000180
+#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300
+#define HC_HTXnFLTs_Nearest 0x00000000
+#define HC_HTXnFLTs_Linear 0x00000010
+#define HC_HTXnFLTs_NonLinear 0x00000020
+#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060
+#define HC_HTXnFLDs_Tex0 0x00000000
+#define HC_HTXnFLDs_Nearest 0x00000001
+#define HC_HTXnFLDs_Linear 0x00000002
+#define HC_HTXnFLDs_NonLinear 0x00000003
+#define HC_HTXnFLDs_Dither 0x00000004
+#define HC_HTXnFLDs_ConstLOD 0x00000005
+#define HC_HTXnFLDs_Ani 0x00000006
+#define HC_HTXnFLDs_AniDither 0x00000007
+/* HC_SubA_HTXnMPMD 0x0079
+ */
+#define HC_HTXnMPMD_SMASK 0x00070000
+#define HC_HTXnMPMD_TMASK 0x00380000
+#define HC_HTXnLODDTf_MASK 0x00000007
+#define HC_HTXnXY2ST_MASK 0x00000008
+#define HC_HTXnMPMD_Tsingle 0x00000000
+#define HC_HTXnMPMD_Tclamp 0x00080000
+#define HC_HTXnMPMD_Trepeat 0x00100000
+#define HC_HTXnMPMD_Tmirror 0x00180000
+#define HC_HTXnMPMD_Twrap 0x00200000
+#define HC_HTXnMPMD_Ssingle 0x00000000
+#define HC_HTXnMPMD_Sclamp 0x00010000
+#define HC_HTXnMPMD_Srepeat 0x00020000
+#define HC_HTXnMPMD_Smirror 0x00030000
+#define HC_HTXnMPMD_Swrap 0x00040000
+/* HC_SubA_HTXnCLODu 0x007a
+ */
+#define HC_HTXnCLODu_MASK 0x000ffc00
+#define HC_HTXnCLODd_MASK 0x000003ff
+#define HC_HTXnCLODu_SHIFT 10
+/* HC_SubA_HTXnFM 0x007b
+ */
+#define HC_HTXnFM_MASK 0x00ff0000
+#define HC_HTXnLoc_MASK 0x00000003
+#define HC_HTXnFM_INDEX 0x00000000
+#define HC_HTXnFM_Intensity 0x00080000
+#define HC_HTXnFM_Lum 0x00100000
+#define HC_HTXnFM_Alpha 0x00180000
+#define HC_HTXnFM_DX 0x00280000
+#define HC_HTXnFM_ARGB16 0x00880000
+#define HC_HTXnFM_ARGB32 0x00980000
+#define HC_HTXnFM_ABGR16 0x00a80000
+#define HC_HTXnFM_ABGR32 0x00b80000
+#define HC_HTXnFM_RGBA16 0x00c80000
+#define HC_HTXnFM_RGBA32 0x00d80000
+#define HC_HTXnFM_BGRA16 0x00e80000
+#define HC_HTXnFM_BGRA32 0x00f80000
+#define HC_HTXnFM_BUMPMAP 0x00380000
+#define HC_HTXnFM_Index1 (HC_HTXnFM_INDEX | 0x00000000)
+#define HC_HTXnFM_Index2 (HC_HTXnFM_INDEX | 0x00010000)
+#define HC_HTXnFM_Index4 (HC_HTXnFM_INDEX | 0x00020000)
+#define HC_HTXnFM_Index8 (HC_HTXnFM_INDEX | 0x00030000)
+#define HC_HTXnFM_T1 (HC_HTXnFM_Intensity | 0x00000000)
+#define HC_HTXnFM_T2 (HC_HTXnFM_Intensity | 0x00010000)
+#define HC_HTXnFM_T4 (HC_HTXnFM_Intensity | 0x00020000)
+#define HC_HTXnFM_T8 (HC_HTXnFM_Intensity | 0x00030000)
+#define HC_HTXnFM_L1 (HC_HTXnFM_Lum | 0x00000000)
+#define HC_HTXnFM_L2 (HC_HTXnFM_Lum | 0x00010000)
+#define HC_HTXnFM_L4 (HC_HTXnFM_Lum | 0x00020000)
+#define HC_HTXnFM_L8 (HC_HTXnFM_Lum | 0x00030000)
+#define HC_HTXnFM_AL44 (HC_HTXnFM_Lum | 0x00040000)
+#define HC_HTXnFM_AL88 (HC_HTXnFM_Lum | 0x00050000)
+#define HC_HTXnFM_A1 (HC_HTXnFM_Alpha | 0x00000000)
+#define HC_HTXnFM_A2 (HC_HTXnFM_Alpha | 0x00010000)
+#define HC_HTXnFM_A4 (HC_HTXnFM_Alpha | 0x00020000)
+#define HC_HTXnFM_A8 (HC_HTXnFM_Alpha | 0x00030000)
+#define HC_HTXnFM_DX1 (HC_HTXnFM_DX | 0x00010000)
+#define HC_HTXnFM_DX23 (HC_HTXnFM_DX | 0x00020000)
+#define HC_HTXnFM_DX45 (HC_HTXnFM_DX | 0x00030000)
+#define HC_HTXnFM_RGB555 (HC_HTXnFM_ARGB16 | 0x00000000)
+#define HC_HTXnFM_RGB565 (HC_HTXnFM_ARGB16 | 0x00010000)
+#define HC_HTXnFM_ARGB1555 (HC_HTXnFM_ARGB16 | 0x00020000)
+#define HC_HTXnFM_ARGB4444 (HC_HTXnFM_ARGB16 | 0x00030000)
+#define HC_HTXnFM_ARGB0888 (HC_HTXnFM_ARGB32 | 0x00000000)
+#define HC_HTXnFM_ARGB8888 (HC_HTXnFM_ARGB32 | 0x00010000)
+#define HC_HTXnFM_BGR555 (HC_HTXnFM_ABGR16 | 0x00000000)
+#define HC_HTXnFM_BGR565 (HC_HTXnFM_ABGR16 | 0x00010000)
+#define HC_HTXnFM_ABGR1555 (HC_HTXnFM_ABGR16 | 0x00020000)
+#define HC_HTXnFM_ABGR4444 (HC_HTXnFM_ABGR16 | 0x00030000)
+#define HC_HTXnFM_ABGR0888 (HC_HTXnFM_ABGR32 | 0x00000000)
+#define HC_HTXnFM_ABGR8888 (HC_HTXnFM_ABGR32 | 0x00010000)
+#define HC_HTXnFM_RGBA5550 (HC_HTXnFM_RGBA16 | 0x00000000)
+#define HC_HTXnFM_RGBA5551 (HC_HTXnFM_RGBA16 | 0x00020000)
+#define HC_HTXnFM_RGBA4444 (HC_HTXnFM_RGBA16 | 0x00030000)
+#define HC_HTXnFM_RGBA8880 (HC_HTXnFM_RGBA32 | 0x00000000)
+#define HC_HTXnFM_RGBA8888 (HC_HTXnFM_RGBA32 | 0x00010000)
+#define HC_HTXnFM_BGRA5550 (HC_HTXnFM_BGRA16 | 0x00000000)
+#define HC_HTXnFM_BGRA5551 (HC_HTXnFM_BGRA16 | 0x00020000)
+#define HC_HTXnFM_BGRA4444 (HC_HTXnFM_BGRA16 | 0x00030000)
+#define HC_HTXnFM_BGRA8880 (HC_HTXnFM_BGRA32 | 0x00000000)
+#define HC_HTXnFM_BGRA8888 (HC_HTXnFM_BGRA32 | 0x00010000)
+#define HC_HTXnFM_VU88 (HC_HTXnFM_BUMPMAP | 0x00000000)
+#define HC_HTXnFM_LVU655 (HC_HTXnFM_BUMPMAP | 0x00010000)
+#define HC_HTXnFM_LVU888 (HC_HTXnFM_BUMPMAP | 0x00020000)
+#define HC_HTXnLoc_Local 0x00000000
+#define HC_HTXnLoc_Sys 0x00000002
+#define HC_HTXnLoc_AGP 0x00000003
+/* HC_SubA_HTXnTRAH 0x007f
+ */
+#define HC_HTXnTRAH_MASK 0x00ff0000
+#define HC_HTXnTRAL_MASK 0x0000ff00
+#define HC_HTXnTBA_MASK 0x000000ff
+#define HC_HTXnTRAH_SHIFT 16
+#define HC_HTXnTRAL_SHIFT 8
+/* HC_SubA_HTXnTBLCsat 0x0080
+ *-- Define the input texture.
+ */
+#define HC_XTC_TOPC 0x00000000
+#define HC_XTC_InvTOPC 0x00000010
+#define HC_XTC_TOPCp5 0x00000020
+#define HC_XTC_Cbias 0x00000000
+#define HC_XTC_InvCbias 0x00000010
+#define HC_XTC_0 0x00000000
+#define HC_XTC_Dif 0x00000001
+#define HC_XTC_Spec 0x00000002
+#define HC_XTC_Tex 0x00000003
+#define HC_XTC_Cur 0x00000004
+#define HC_XTC_Adif 0x00000005
+#define HC_XTC_Fog 0x00000006
+#define HC_XTC_Atex 0x00000007
+#define HC_XTC_Acur 0x00000008
+#define HC_XTC_HTXnTBLRC 0x00000009
+#define HC_XTC_Ctexnext 0x0000000a
+/*--
+ */
+#define HC_HTXnTBLCsat_MASK 0x00800000
+#define HC_HTXnTBLCa_MASK 0x000fc000
+#define HC_HTXnTBLCb_MASK 0x00001f80
+#define HC_HTXnTBLCc_MASK 0x0000003f
+#define HC_HTXnTBLCa_TOPC (HC_XTC_TOPC << 14)
+#define HC_HTXnTBLCa_InvTOPC (HC_XTC_InvTOPC << 14)
+#define HC_HTXnTBLCa_TOPCp5 (HC_XTC_TOPCp5 << 14)
+#define HC_HTXnTBLCa_0 (HC_XTC_0 << 14)
+#define HC_HTXnTBLCa_Dif (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCa_Spec (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCa_Tex (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCa_Cur (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCa_Adif (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCa_Fog (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCa_Atex (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCa_Acur (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCa_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCa_Ctexnext (HC_XTC_Ctexnext << 14)
+#define HC_HTXnTBLCb_TOPC (HC_XTC_TOPC << 7)
+#define HC_HTXnTBLCb_InvTOPC (HC_XTC_InvTOPC << 7)
+#define HC_HTXnTBLCb_TOPCp5 (HC_XTC_TOPCp5 << 7)
+#define HC_HTXnTBLCb_0 (HC_XTC_0 << 7)
+#define HC_HTXnTBLCb_Dif (HC_XTC_Dif << 7)
+#define HC_HTXnTBLCb_Spec (HC_XTC_Spec << 7)
+#define HC_HTXnTBLCb_Tex (HC_XTC_Tex << 7)
+#define HC_HTXnTBLCb_Cur (HC_XTC_Cur << 7)
+#define HC_HTXnTBLCb_Adif (HC_XTC_Adif << 7)
+#define HC_HTXnTBLCb_Fog (HC_XTC_Fog << 7)
+#define HC_HTXnTBLCb_Atex (HC_XTC_Atex << 7)
+#define HC_HTXnTBLCb_Acur (HC_XTC_Acur << 7)
+#define HC_HTXnTBLCb_HTXnTBLRC (HC_XTC_HTXnTBLRC << 7)
+#define HC_HTXnTBLCb_Ctexnext (HC_XTC_Ctexnext << 7)
+#define HC_HTXnTBLCc_TOPC (HC_XTC_TOPC << 0)
+#define HC_HTXnTBLCc_InvTOPC (HC_XTC_InvTOPC << 0)
+#define HC_HTXnTBLCc_TOPCp5 (HC_XTC_TOPCp5 << 0)
+#define HC_HTXnTBLCc_0 (HC_XTC_0 << 0)
+#define HC_HTXnTBLCc_Dif (HC_XTC_Dif << 0)
+#define HC_HTXnTBLCc_Spec (HC_XTC_Spec << 0)
+#define HC_HTXnTBLCc_Tex (HC_XTC_Tex << 0)
+#define HC_HTXnTBLCc_Cur (HC_XTC_Cur << 0)
+#define HC_HTXnTBLCc_Adif (HC_XTC_Adif << 0)
+#define HC_HTXnTBLCc_Fog (HC_XTC_Fog << 0)
+#define HC_HTXnTBLCc_Atex (HC_XTC_Atex << 0)
+#define HC_HTXnTBLCc_Acur (HC_XTC_Acur << 0)
+#define HC_HTXnTBLCc_HTXnTBLRC (HC_XTC_HTXnTBLRC << 0)
+#define HC_HTXnTBLCc_Ctexnext (HC_XTC_Ctexnext << 0)
+/* HC_SubA_HTXnTBLCop 0x0081
+ */
+#define HC_HTXnTBLdot_MASK 0x00c00000
+#define HC_HTXnTBLCop_MASK 0x00380000
+#define HC_HTXnTBLCbias_MASK 0x0007c000
+#define HC_HTXnTBLCshift_MASK 0x00001800
+#define HC_HTXnTBLAop_MASK 0x00000380
+#define HC_HTXnTBLAbias_MASK 0x00000078
+#define HC_HTXnTBLAshift_MASK 0x00000003
+#define HC_HTXnTBLCop_Add 0x00000000
+#define HC_HTXnTBLCop_Sub 0x00080000
+#define HC_HTXnTBLCop_Min 0x00100000
+#define HC_HTXnTBLCop_Max 0x00180000
+#define HC_HTXnTBLCop_Mask 0x00200000
+#define HC_HTXnTBLCbias_Cbias (HC_XTC_Cbias << 14)
+#define HC_HTXnTBLCbias_InvCbias (HC_XTC_InvCbias << 14)
+#define HC_HTXnTBLCbias_0 (HC_XTC_0 << 14)
+#define HC_HTXnTBLCbias_Dif (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCbias_Spec (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCbias_Tex (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCbias_Cur (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCbias_Adif (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCbias_Fog (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCbias_Atex (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCbias_Acur (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCbias_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCshift_1 0x00000000
+#define HC_HTXnTBLCshift_2 0x00000800
+#define HC_HTXnTBLCshift_No 0x00001000
+#define HC_HTXnTBLCshift_DotP 0x00001800
+/*=* John Sheng [2003.7.18] texture combine *=*/
+#define HC_HTXnTBLDOT3 0x00080000
+#define HC_HTXnTBLDOT4 0x000C0000
+
+#define HC_HTXnTBLAop_Add 0x00000000
+#define HC_HTXnTBLAop_Sub 0x00000080
+#define HC_HTXnTBLAop_Min 0x00000100
+#define HC_HTXnTBLAop_Max 0x00000180
+#define HC_HTXnTBLAop_Mask 0x00000200
+#define HC_HTXnTBLAbias_Inv 0x00000040
+#define HC_HTXnTBLAbias_Adif 0x00000000
+#define HC_HTXnTBLAbias_Fog 0x00000008
+#define HC_HTXnTBLAbias_Acur 0x00000010
+#define HC_HTXnTBLAbias_HTXnTBLRAbias 0x00000018
+#define HC_HTXnTBLAbias_Atex 0x00000020
+#define HC_HTXnTBLAshift_1 0x00000000
+#define HC_HTXnTBLAshift_2 0x00000001
+#define HC_HTXnTBLAshift_No 0x00000002
+/* #define HC_HTXnTBLAshift_DotP 0x00000003 */
+/* HC_SubA_HTXnTBLMPFog 0x0082
+ */
+#define HC_HTXnTBLMPfog_MASK 0x00e00000
+#define HC_HTXnTBLMPfog_0 0x00000000
+#define HC_HTXnTBLMPfog_Adif 0x00200000
+#define HC_HTXnTBLMPfog_Fog 0x00400000
+#define HC_HTXnTBLMPfog_Atex 0x00600000
+#define HC_HTXnTBLMPfog_Acur 0x00800000
+#define HC_HTXnTBLMPfog_GHTXnTBLRFog 0x00a00000
+/* HC_SubA_HTXnTBLAsat 0x0083
+ *-- Define the texture alpha input.
+ */
+#define HC_XTA_TOPA 0x00000000
+#define HC_XTA_InvTOPA 0x00000008
+#define HC_XTA_TOPAp5 0x00000010
+#define HC_XTA_Adif 0x00000000
+#define HC_XTA_Fog 0x00000001
+#define HC_XTA_Acur 0x00000002
+#define HC_XTA_HTXnTBLRA 0x00000003
+#define HC_XTA_Atex 0x00000004
+#define HC_XTA_Atexnext 0x00000005
+/*--
+ */
+#define HC_HTXnTBLAsat_MASK 0x00800000
+#define HC_HTXnTBLAMB_MASK 0x00700000
+#define HC_HTXnTBLAa_MASK 0x0007c000
+#define HC_HTXnTBLAb_MASK 0x00000f80
+#define HC_HTXnTBLAc_MASK 0x0000001f
+#define HC_HTXnTBLAMB_SHIFT 20
+#define HC_HTXnTBLAa_TOPA (HC_XTA_TOPA << 14)
+#define HC_HTXnTBLAa_InvTOPA (HC_XTA_InvTOPA << 14)
+#define HC_HTXnTBLAa_TOPAp5 (HC_XTA_TOPAp5 << 14)
+#define HC_HTXnTBLAa_Adif (HC_XTA_Adif << 14)
+#define HC_HTXnTBLAa_Fog (HC_XTA_Fog << 14)
+#define HC_HTXnTBLAa_Acur (HC_XTA_Acur << 14)
+#define HC_HTXnTBLAa_HTXnTBLRA (HC_XTA_HTXnTBLRA << 14)
+#define HC_HTXnTBLAa_Atex (HC_XTA_Atex << 14)
+#define HC_HTXnTBLAa_Atexnext (HC_XTA_Atexnext << 14)
+#define HC_HTXnTBLAb_TOPA (HC_XTA_TOPA << 7)
+#define HC_HTXnTBLAb_InvTOPA (HC_XTA_InvTOPA << 7)
+#define HC_HTXnTBLAb_TOPAp5 (HC_XTA_TOPAp5 << 7)
+#define HC_HTXnTBLAb_Adif (HC_XTA_Adif << 7)
+#define HC_HTXnTBLAb_Fog (HC_XTA_Fog << 7)
+#define HC_HTXnTBLAb_Acur (HC_XTA_Acur << 7)
+#define HC_HTXnTBLAb_HTXnTBLRA (HC_XTA_HTXnTBLRA << 7)
+#define HC_HTXnTBLAb_Atex (HC_XTA_Atex << 7)
+#define HC_HTXnTBLAb_Atexnext (HC_XTA_Atexnext << 7)
+#define HC_HTXnTBLAc_TOPA (HC_XTA_TOPA << 0)
+#define HC_HTXnTBLAc_InvTOPA (HC_XTA_InvTOPA << 0)
+#define HC_HTXnTBLAc_TOPAp5 (HC_XTA_TOPAp5 << 0)
+#define HC_HTXnTBLAc_Adif (HC_XTA_Adif << 0)
+#define HC_HTXnTBLAc_Fog (HC_XTA_Fog << 0)
+#define HC_HTXnTBLAc_Acur (HC_XTA_Acur << 0)
+#define HC_HTXnTBLAc_HTXnTBLRA (HC_XTA_HTXnTBLRA << 0)
+#define HC_HTXnTBLAc_Atex (HC_XTA_Atex << 0)
+#define HC_HTXnTBLAc_Atexnext (HC_XTA_Atexnext << 0)
+/* HC_SubA_HTXnTBLRAa 0x0089
+ */
+#define HC_HTXnTBLRAa_MASK 0x00ff0000
+#define HC_HTXnTBLRAb_MASK 0x0000ff00
+#define HC_HTXnTBLRAc_MASK 0x000000ff
+#define HC_HTXnTBLRAa_SHIFT 16
+#define HC_HTXnTBLRAb_SHIFT 8
+#define HC_HTXnTBLRAc_SHIFT 0
+/* HC_SubA_HTXnTBLRFog 0x008a
+ */
+#define HC_HTXnTBLRFog_MASK 0x0000ff00
+#define HC_HTXnTBLRAbias_MASK 0x000000ff
+#define HC_HTXnTBLRFog_SHIFT 8
+#define HC_HTXnTBLRAbias_SHIFT 0
+/* HC_SubA_HTXnLScale 0x0094
+ */
+#define HC_HTXnLScale_MASK 0x0007fc00
+#define HC_HTXnLOff_MASK 0x000001ff
+#define HC_HTXnLScale_SHIFT 10
+/* HC_SubA_HTXSMD 0x0000
+ */
+#define HC_HTXSMD_MASK 0x00000080
+#define HC_HTXTMD_MASK 0x00000040
+#define HC_HTXNum_MASK 0x00000038
+#define HC_HTXTRMD_MASK 0x00000006
+#define HC_HTXCHCLR_MASK 0x00000001
+#define HC_HTXNum_SHIFT 3
+
+/* Texture Palette n
+ */
+#define HC_SubType_TexPalette0 0x00000000
+#define HC_SubType_TexPalette1 0x00000001
+#define HC_SubType_FogTable 0x00000010
+#define HC_SubType_Stipple 0x00000014
+/* HC_SubA_TexPalette0 0x0000
+ */
+#define HC_HTPnA_MASK 0xff000000
+#define HC_HTPnR_MASK 0x00ff0000
+#define HC_HTPnG_MASK 0x0000ff00
+#define HC_HTPnB_MASK 0x000000ff
+/* HC_SubA_FogTable 0x0010
+ */
+#define HC_HFPn3_MASK 0xff000000
+#define HC_HFPn2_MASK 0x00ff0000
+#define HC_HFPn1_MASK 0x0000ff00
+#define HC_HFPn_MASK 0x000000ff
+#define HC_HFPn3_SHIFT 24
+#define HC_HFPn2_SHIFT 16
+#define HC_HFPn1_SHIFT 8
+
+/* Auto Testing & Security
+ */
+#define HC_SubA_HenFIFOAT 0x0000
+#define HC_SubA_HFBDrawFirst 0x0004
+#define HC_SubA_HFBBasL 0x0005
+#define HC_SubA_HFBDst 0x0006
+/* HC_SubA_HenFIFOAT 0x0000
+ */
+#define HC_HenFIFOAT_MASK 0x00000020
+#define HC_HenGEMILock_MASK 0x00000010
+#define HC_HenFBASwap_MASK 0x00000008
+#define HC_HenOT_MASK 0x00000004
+#define HC_HenCMDQ_MASK 0x00000002
+#define HC_HenTXCTSU_MASK 0x00000001
+/* HC_SubA_HFBDrawFirst 0x0004
+ */
+#define HC_HFBDrawFirst_MASK 0x00000800
+#define HC_HFBQueue_MASK 0x00000400
+#define HC_HFBLock_MASK 0x00000200
+#define HC_HEOF_MASK 0x00000100
+#define HC_HFBBasH_MASK 0x000000ff
+
+/* GEMI Setting
+ */
+#define HC_SubA_HTArbRCM 0x0008
+#define HC_SubA_HTArbRZ 0x000a
+#define HC_SubA_HTArbWZ 0x000b
+#define HC_SubA_HTArbRTX 0x000c
+#define HC_SubA_HTArbRCW 0x000d
+#define HC_SubA_HTArbE2 0x000e
+#define HC_SubA_HArbRQCM 0x0010
+#define HC_SubA_HArbWQCM 0x0011
+#define HC_SubA_HGEMITout 0x0020
+#define HC_SubA_HFthRTXD 0x0040
+#define HC_SubA_HFthRTXA 0x0044
+#define HC_SubA_HCMDQstL 0x0050
+#define HC_SubA_HCMDQendL 0x0051
+#define HC_SubA_HCMDQLen 0x0052
+/* HC_SubA_HTArbRCM 0x0008
+ */
+#define HC_HTArbRCM_MASK 0x0000ffff
+/* HC_SubA_HTArbRZ 0x000a
+ */
+#define HC_HTArbRZ_MASK 0x0000ffff
+/* HC_SubA_HTArbWZ 0x000b
+ */
+#define HC_HTArbWZ_MASK 0x0000ffff
+/* HC_SubA_HTArbRTX 0x000c
+ */
+#define HC_HTArbRTX_MASK 0x0000ffff
+/* HC_SubA_HTArbRCW 0x000d
+ */
+#define HC_HTArbRCW_MASK 0x0000ffff
+/* HC_SubA_HTArbE2 0x000e
+ */
+#define HC_HTArbE2_MASK 0x0000ffff
+/* HC_SubA_HArbRQCM 0x0010
+ */
+#define HC_HTArbRQCM_MASK 0x0000ffff
+/* HC_SubA_HArbWQCM 0x0011
+ */
+#define HC_HArbWQCM_MASK 0x0000ffff
+/* HC_SubA_HGEMITout 0x0020
+ */
+#define HC_HGEMITout_MASK 0x000f0000
+#define HC_HNPArbZC_MASK 0x0000ffff
+#define HC_HGEMITout_SHIFT 16
+/* HC_SubA_HFthRTXD 0x0040
+ */
+#define HC_HFthRTXD_MASK 0x00ff0000
+#define HC_HFthRZD_MASK 0x0000ff00
+#define HC_HFthWZD_MASK 0x000000ff
+#define HC_HFthRTXD_SHIFT 16
+#define HC_HFthRZD_SHIFT 8
+/* HC_SubA_HFthRTXA 0x0044
+ */
+#define HC_HFthRTXA_MASK 0x000000ff
+
+/******************************************************************************
+** Define the Halcyon Internal register access constants. For simulator only.
+******************************************************************************/
+#define HC_SIMA_HAGPBstL 0x0000
+#define HC_SIMA_HAGPBendL 0x0001
+#define HC_SIMA_HAGPCMNT 0x0002
+#define HC_SIMA_HAGPBpL 0x0003
+#define HC_SIMA_HAGPBpH 0x0004
+#define HC_SIMA_HClipTB 0x0005
+#define HC_SIMA_HClipLR 0x0006
+#define HC_SIMA_HFPClipTL 0x0007
+#define HC_SIMA_HFPClipBL 0x0008
+#define HC_SIMA_HFPClipLL 0x0009
+#define HC_SIMA_HFPClipRL 0x000a
+#define HC_SIMA_HFPClipTBH 0x000b
+#define HC_SIMA_HFPClipLRH 0x000c
+#define HC_SIMA_HLP 0x000d
+#define HC_SIMA_HLPRF 0x000e
+#define HC_SIMA_HSolidCL 0x000f
+#define HC_SIMA_HPixGC 0x0010
+#define HC_SIMA_HSPXYOS 0x0011
+#define HC_SIMA_HCmdA 0x0012
+#define HC_SIMA_HCmdB 0x0013
+#define HC_SIMA_HEnable 0x0014
+#define HC_SIMA_HZWBBasL 0x0015
+#define HC_SIMA_HZWBBasH 0x0016
+#define HC_SIMA_HZWBType 0x0017
+#define HC_SIMA_HZBiasL 0x0018
+#define HC_SIMA_HZWBend 0x0019
+#define HC_SIMA_HZWTMD 0x001a
+#define HC_SIMA_HZWCDL 0x001b
+#define HC_SIMA_HZWCTAGnum 0x001c
+#define HC_SIMA_HZCYNum 0x001d
+#define HC_SIMA_HZWCFire 0x001e
+/* #define HC_SIMA_HSBBasL 0x001d */
+/* #define HC_SIMA_HSBBasH 0x001e */
+/* #define HC_SIMA_HSBFM 0x001f */
+#define HC_SIMA_HSTREF 0x0020
+#define HC_SIMA_HSTMD 0x0021
+#define HC_SIMA_HABBasL 0x0022
+#define HC_SIMA_HABBasH 0x0023
+#define HC_SIMA_HABFM 0x0024
+#define HC_SIMA_HATMD 0x0025
+#define HC_SIMA_HABLCsat 0x0026
+#define HC_SIMA_HABLCop 0x0027
+#define HC_SIMA_HABLAsat 0x0028
+#define HC_SIMA_HABLAop 0x0029
+#define HC_SIMA_HABLRCa 0x002a
+#define HC_SIMA_HABLRFCa 0x002b
+#define HC_SIMA_HABLRCbias 0x002c
+#define HC_SIMA_HABLRCb 0x002d
+#define HC_SIMA_HABLRFCb 0x002e
+#define HC_SIMA_HABLRAa 0x002f
+#define HC_SIMA_HABLRAb 0x0030
+#define HC_SIMA_HDBBasL 0x0031
+#define HC_SIMA_HDBBasH 0x0032
+#define HC_SIMA_HDBFM 0x0033
+#define HC_SIMA_HFBBMSKL 0x0034
+#define HC_SIMA_HROP 0x0035
+#define HC_SIMA_HFogLF 0x0036
+#define HC_SIMA_HFogCL 0x0037
+#define HC_SIMA_HFogCH 0x0038
+#define HC_SIMA_HFogStL 0x0039
+#define HC_SIMA_HFogStH 0x003a
+#define HC_SIMA_HFogOOdMF 0x003b
+#define HC_SIMA_HFogOOdEF 0x003c
+#define HC_SIMA_HFogEndL 0x003d
+#define HC_SIMA_HFogDenst 0x003e
+/*---- start of texture 0 setting ----
+ */
+#define HC_SIMA_HTX0L0BasL 0x0040
+#define HC_SIMA_HTX0L1BasL 0x0041
+#define HC_SIMA_HTX0L2BasL 0x0042
+#define HC_SIMA_HTX0L3BasL 0x0043
+#define HC_SIMA_HTX0L4BasL 0x0044
+#define HC_SIMA_HTX0L5BasL 0x0045
+#define HC_SIMA_HTX0L6BasL 0x0046
+#define HC_SIMA_HTX0L7BasL 0x0047
+#define HC_SIMA_HTX0L8BasL 0x0048
+#define HC_SIMA_HTX0L9BasL 0x0049
+#define HC_SIMA_HTX0LaBasL 0x004a
+#define HC_SIMA_HTX0LbBasL 0x004b
+#define HC_SIMA_HTX0LcBasL 0x004c
+#define HC_SIMA_HTX0LdBasL 0x004d
+#define HC_SIMA_HTX0LeBasL 0x004e
+#define HC_SIMA_HTX0LfBasL 0x004f
+#define HC_SIMA_HTX0L10BasL 0x0050
+#define HC_SIMA_HTX0L11BasL 0x0051
+#define HC_SIMA_HTX0L012BasH 0x0052
+#define HC_SIMA_HTX0L345BasH 0x0053
+#define HC_SIMA_HTX0L678BasH 0x0054
+#define HC_SIMA_HTX0L9abBasH 0x0055
+#define HC_SIMA_HTX0LcdeBasH 0x0056
+#define HC_SIMA_HTX0Lf1011BasH 0x0057
+#define HC_SIMA_HTX0L0Pit 0x0058
+#define HC_SIMA_HTX0L1Pit 0x0059
+#define HC_SIMA_HTX0L2Pit 0x005a
+#define HC_SIMA_HTX0L3Pit 0x005b
+#define HC_SIMA_HTX0L4Pit 0x005c
+#define HC_SIMA_HTX0L5Pit 0x005d
+#define HC_SIMA_HTX0L6Pit 0x005e
+#define HC_SIMA_HTX0L7Pit 0x005f
+#define HC_SIMA_HTX0L8Pit 0x0060
+#define HC_SIMA_HTX0L9Pit 0x0061
+#define HC_SIMA_HTX0LaPit 0x0062
+#define HC_SIMA_HTX0LbPit 0x0063
+#define HC_SIMA_HTX0LcPit 0x0064
+#define HC_SIMA_HTX0LdPit 0x0065
+#define HC_SIMA_HTX0LePit 0x0066
+#define HC_SIMA_HTX0LfPit 0x0067
+#define HC_SIMA_HTX0L10Pit 0x0068
+#define HC_SIMA_HTX0L11Pit 0x0069
+#define HC_SIMA_HTX0L0_5WE 0x006a
+#define HC_SIMA_HTX0L6_bWE 0x006b
+#define HC_SIMA_HTX0Lc_11WE 0x006c
+#define HC_SIMA_HTX0L0_5HE 0x006d
+#define HC_SIMA_HTX0L6_bHE 0x006e
+#define HC_SIMA_HTX0Lc_11HE 0x006f
+#define HC_SIMA_HTX0L0OS 0x0070
+#define HC_SIMA_HTX0TB 0x0071
+#define HC_SIMA_HTX0MPMD 0x0072
+#define HC_SIMA_HTX0CLODu 0x0073
+#define HC_SIMA_HTX0FM 0x0074
+#define HC_SIMA_HTX0TRCH 0x0075
+#define HC_SIMA_HTX0TRCL 0x0076
+#define HC_SIMA_HTX0TBC 0x0077
+#define HC_SIMA_HTX0TRAH 0x0078
+#define HC_SIMA_HTX0TBLCsat 0x0079
+#define HC_SIMA_HTX0TBLCop 0x007a
+#define HC_SIMA_HTX0TBLMPfog 0x007b
+#define HC_SIMA_HTX0TBLAsat 0x007c
+#define HC_SIMA_HTX0TBLRCa 0x007d
+#define HC_SIMA_HTX0TBLRCb 0x007e
+#define HC_SIMA_HTX0TBLRCc 0x007f
+#define HC_SIMA_HTX0TBLRCbias 0x0080
+#define HC_SIMA_HTX0TBLRAa 0x0081
+#define HC_SIMA_HTX0TBLRFog 0x0082
+#define HC_SIMA_HTX0BumpM00 0x0083
+#define HC_SIMA_HTX0BumpM01 0x0084
+#define HC_SIMA_HTX0BumpM10 0x0085
+#define HC_SIMA_HTX0BumpM11 0x0086
+#define HC_SIMA_HTX0LScale 0x0087
+/*---- end of texture 0 setting ---- 0x008f
+ */
+#define HC_SIMA_TX0TX1_OFF 0x0050
+/*---- start of texture 1 setting ----
+ */
+#define HC_SIMA_HTX1L0BasL (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1BasL (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2BasL (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3BasL (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4BasL (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5BasL (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6BasL (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7BasL (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8BasL (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9BasL (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaBasL (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbBasL (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcBasL (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdBasL (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LeBasL (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfBasL (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10BasL (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11BasL (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L012BasH (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L345BasH (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L678BasH (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9abBasH (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcdeBasH (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lf1011BasH (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0Pit (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1Pit (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2Pit (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3Pit (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4Pit (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5Pit (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6Pit (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7Pit (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8Pit (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9Pit (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaPit (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbPit (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcPit (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdPit (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LePit (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfPit (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10Pit (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11Pit (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5WE (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bWE (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11WE (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5HE (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bHE (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11HE (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0OS (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TB (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1MPMD (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1CLODu (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1FM (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCH (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCL (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBC (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRAH (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTC (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTA (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCsat (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCop (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLMPfog (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLAsat (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCa (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCb (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCc (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCbias (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRAa (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRFog (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM00 (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM01 (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM10 (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM11 (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LScale (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF)
+/*---- end of texture 1 setting ---- 0xaf
+ */
+#define HC_SIMA_HTXSMD 0x00b0
+#define HC_SIMA_HenFIFOAT 0x00b1
+#define HC_SIMA_HFBDrawFirst 0x00b2
+#define HC_SIMA_HFBBasL 0x00b3
+#define HC_SIMA_HTArbRCM 0x00b4
+#define HC_SIMA_HTArbRZ 0x00b5
+#define HC_SIMA_HTArbWZ 0x00b6
+#define HC_SIMA_HTArbRTX 0x00b7
+#define HC_SIMA_HTArbRCW 0x00b8
+#define HC_SIMA_HTArbE2 0x00b9
+#define HC_SIMA_HGEMITout 0x00ba
+#define HC_SIMA_HFthRTXD 0x00bb
+#define HC_SIMA_HFthRTXA 0x00bc
+/* Define the texture palette 0
+ */
+#define HC_SIMA_HTP0 0x0100
+#define HC_SIMA_HTP1 0x0200
+#define HC_SIMA_FOGTABLE 0x0300
+#define HC_SIMA_STIPPLE 0x0400
+#define HC_SIMA_HE3Fire 0x0440
+#define HC_SIMA_TRANS_SET 0x0441
+#define HC_SIMA_HREngSt 0x0442
+#define HC_SIMA_HRFIFOempty 0x0443
+#define HC_SIMA_HRFIFOfull 0x0444
+#define HC_SIMA_HRErr 0x0445
+#define HC_SIMA_FIFOstatus 0x0446
+
+/******************************************************************************
+** Define the AGP command header.
+******************************************************************************/
+#define HC_ACMD_MASK 0xfe000000
+#define HC_ACMD_SUB_MASK 0x0c000000
+#define HC_ACMD_HCmdA 0xee000000
+#define HC_ACMD_HCmdB 0xec000000
+#define HC_ACMD_HCmdC 0xea000000
+#define HC_ACMD_H1 0xf0000000
+#define HC_ACMD_H2 0xf2000000
+#define HC_ACMD_H3 0xf4000000
+#define HC_ACMD_H4 0xf6000000
+
+#define HC_ACMD_H1IO_MASK 0x000001ff
+#define HC_ACMD_H2IO1_MASK 0x001ff000
+#define HC_ACMD_H2IO2_MASK 0x000001ff
+#define HC_ACMD_H2IO1_SHIFT 12
+#define HC_ACMD_H2IO2_SHIFT 0
+#define HC_ACMD_H3IO_MASK 0x000001ff
+#define HC_ACMD_H3COUNT_MASK 0x01fff000
+#define HC_ACMD_H3COUNT_SHIFT 12
+#define HC_ACMD_H4ID_MASK 0x000001ff
+#define HC_ACMD_H4COUNT_MASK 0x01fffe00
+#define HC_ACMD_H4COUNT_SHIFT 9
+
+/********************************************************************************
+** Define Header
+********************************************************************************/
+#define HC_HEADER2 0xF210F110
+
+/********************************************************************************
+** Define Dummy Value
+********************************************************************************/
+#define HC_DUMMY 0xCCCCCCCC
+/********************************************************************************
+** Define for DMA use
+********************************************************************************/
+#define HALCYON_HEADER2 0XF210F110
+#define HALCYON_FIRECMD 0XEE100000
+#define HALCYON_FIREMASK 0XFFF00000
+#define HALCYON_CMDB 0XEC000000
+#define HALCYON_CMDBMASK 0XFFFE0000
+#define HALCYON_SUB_ADDR0 0X00000000
+#define HALCYON_HEADER1MASK 0XFFFFFC00
+#define HALCYON_HEADER1 0XF0000000
+#define HC_SubA_HAGPBstL 0x0060
+#define HC_SubA_HAGPBendL 0x0061
+#define HC_SubA_HAGPCMNT 0x0062
+#define HC_SubA_HAGPBpL 0x0063
+#define HC_SubA_HAGPBpH 0x0064
+#define HC_HAGPCMNT_MASK 0x00800000
+#define HC_HCmdErrClr_MASK 0x00400000
+#define HC_HAGPBendH_MASK 0x0000ff00
+#define HC_HAGPBstH_MASK 0x000000ff
+#define HC_HAGPBendH_SHIFT 8
+#define HC_HAGPBstH_SHIFT 0
+#define HC_HAGPBpL_MASK 0x00fffffc
+#define HC_HAGPBpID_MASK 0x00000003
+#define HC_HAGPBpID_PAUSE 0x00000000
+#define HC_HAGPBpID_JUMP 0x00000001
+#define HC_HAGPBpID_STOP 0x00000002
+#define HC_HAGPBpH_MASK 0x00ffffff
+
+
+#define VIA_VIDEO_HEADER5 0xFE040000
+#define VIA_VIDEO_HEADER6 0xFE050000
+#define VIA_VIDEO_HEADER7 0xFE060000
+#define VIA_VIDEOMASK 0xFFFF0000
+#endif
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
new file mode 100644
index 00000000000..82f83945162
--- /dev/null
+++ b/drivers/char/drm/via_dma.c
@@ -0,0 +1,741 @@
+/* via_dma.c -- DMA support for the VIA Unichrome/Pro
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
+ * All Rights Reserved.
+ *
+ * Copyright 2004 The Unichrome project.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Tungsten Graphics,
+ * Erdi Chen,
+ * Thomas Hellstrom.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "via_3d_reg.h"
+
+#define CMDBUF_ALIGNMENT_SIZE (0x100)
+#define CMDBUF_ALIGNMENT_MASK (0x0ff)
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS 0x400
+#define VIA_REG_TRANSET 0x43C
+#define VIA_REG_TRANSPACE 0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
+
+#define SetReg2DAGP(nReg, nData) { \
+ *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
+ *((uint32_t *)(vb) + 1) = (nData); \
+ vb = ((uint32_t *)vb) + 2; \
+ dev_priv->dma_low +=8; \
+}
+
+#define via_flush_write_combine() DRM_MEMORYBARRIER()
+
+#define VIA_OUT_RING_QW(w1,w2) \
+ *vb++ = (w1); \
+ *vb++ = (w2); \
+ dev_priv->dma_low += 8;
+
+static void via_cmdbuf_start(drm_via_private_t * dev_priv);
+static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
+static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
+static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
+static int via_wait_idle(drm_via_private_t * dev_priv);
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
+
+
+/*
+ * Free space in command buffer.
+ */
+
+static uint32_t
+via_cmdbuf_space(drm_via_private_t *dev_priv)
+{
+ uint32_t agp_base = dev_priv->dma_offset +
+ (uint32_t) dev_priv->agpAddr;
+ uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+
+ return ((hw_addr <= dev_priv->dma_low) ?
+ (dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
+ (hw_addr - dev_priv->dma_low));
+}
+
+/*
+ * How much does the command regulator lag behind?
+ */
+
+static uint32_t
+via_cmdbuf_lag(drm_via_private_t *dev_priv)
+{
+ uint32_t agp_base = dev_priv->dma_offset +
+ (uint32_t) dev_priv->agpAddr;
+ uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+
+ return ((hw_addr <= dev_priv->dma_low) ?
+ (dev_priv->dma_low - hw_addr) :
+ (dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
+}
+
+/*
+ * Check that the given size fits in the buffer, otherwise wait.
+ */
+
+static inline int
+via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
+{
+ uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ uint32_t cur_addr, hw_addr, next_addr;
+ volatile uint32_t *hw_addr_ptr;
+ uint32_t count;
+ hw_addr_ptr = dev_priv->hw_addr_ptr;
+ cur_addr = dev_priv->dma_low;
+ next_addr = cur_addr + size + 512*1024;
+ count = 1000000;
+ do {
+ hw_addr = *hw_addr_ptr - agp_base;
+ if (count-- == 0) {
+ DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
+ hw_addr, cur_addr, next_addr);
+ return -1;
+ }
+ } while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
+ return 0;
+}
+
+
+/*
+ * Checks whether buffer head has reach the end. Rewind the ring buffer
+ * when necessary.
+ *
+ * Returns virtual pointer to ring buffer.
+ */
+
+static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
+ unsigned int size)
+{
+ if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
+ via_cmdbuf_rewind(dev_priv);
+ }
+ if (via_cmdbuf_wait(dev_priv, size) != 0) {
+ return NULL;
+ }
+
+ return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
+}
+
+int via_dma_cleanup(drm_device_t * dev)
+{
+ if (dev->dev_private) {
+ drm_via_private_t *dev_priv =
+ (drm_via_private_t *) dev->dev_private;
+
+ if (dev_priv->ring.virtual_start) {
+ via_cmdbuf_reset(dev_priv);
+
+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
+ dev_priv->ring.virtual_start = NULL;
+ }
+
+ }
+
+ return 0;
+}
+
+static int via_initialize(drm_device_t * dev,
+ drm_via_private_t * dev_priv,
+ drm_via_dma_init_t * init)
+{
+ if (!dev_priv || !dev_priv->mmio) {
+ DRM_ERROR("via_dma_init called before via_map_init\n");
+ return DRM_ERR(EFAULT);
+ }
+
+ if (dev_priv->ring.virtual_start != NULL) {
+ DRM_ERROR("%s called again without calling cleanup\n",
+ __FUNCTION__);
+ return DRM_ERR(EFAULT);
+ }
+
+ if (!dev->agp || !dev->agp->base) {
+ DRM_ERROR("%s called with no agp memory available\n",
+ __FUNCTION__);
+ return DRM_ERR(EFAULT);
+ }
+
+ dev_priv->ring.map.offset = dev->agp->base + init->offset;
+ dev_priv->ring.map.size = init->size;
+ dev_priv->ring.map.type = 0;
+ dev_priv->ring.map.flags = 0;
+ dev_priv->ring.map.mtrr = 0;
+
+ drm_core_ioremap(&dev_priv->ring.map, dev);
+
+ if (dev_priv->ring.map.handle == NULL) {
+ via_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
+ " ring buffer\n");
+ return DRM_ERR(ENOMEM);
+ }
+
+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+
+ dev_priv->dma_ptr = dev_priv->ring.virtual_start;
+ dev_priv->dma_low = 0;
+ dev_priv->dma_high = init->size;
+ dev_priv->dma_wrap = init->size;
+ dev_priv->dma_offset = init->offset;
+ dev_priv->last_pause_ptr = NULL;
+ dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr;
+
+ via_cmdbuf_start(dev_priv);
+
+ return 0;
+}
+
+int via_dma_init(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_dma_init_t init;
+ int retcode = 0;
+
+ DRM_COPY_FROM_USER_IOCTL(init, (drm_via_dma_init_t *) data,
+ sizeof(init));
+
+ switch (init.func) {
+ case VIA_INIT_DMA:
+ if (!capable(CAP_SYS_ADMIN))
+ retcode = DRM_ERR(EPERM);
+ else
+ retcode = via_initialize(dev, dev_priv, &init);
+ break;
+ case VIA_CLEANUP_DMA:
+ if (!capable(CAP_SYS_ADMIN))
+ retcode = DRM_ERR(EPERM);
+ else
+ retcode = via_dma_cleanup(dev);
+ break;
+ case VIA_DMA_INITIALIZED:
+ retcode = (dev_priv->ring.virtual_start != NULL) ?
+ 0: DRM_ERR( EFAULT );
+ break;
+ default:
+ retcode = DRM_ERR(EINVAL);
+ break;
+ }
+
+ return retcode;
+}
+
+
+
+static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
+{
+ drm_via_private_t *dev_priv;
+ uint32_t *vb;
+ int ret;
+
+ dev_priv = (drm_via_private_t *) dev->dev_private;
+
+ if (dev_priv->ring.virtual_start == NULL) {
+ DRM_ERROR("%s called without initializing AGP ring buffer.\n",
+ __FUNCTION__);
+ return DRM_ERR(EFAULT);
+ }
+
+ if (cmd->size > VIA_PCI_BUF_SIZE) {
+ return DRM_ERR(ENOMEM);
+ }
+
+
+ if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+ return DRM_ERR(EFAULT);
+
+ /*
+ * Running this function on AGP memory is dead slow. Therefore
+ * we run it on a temporary cacheable system memory buffer and
+ * copy it to AGP memory when ready.
+ */
+
+
+ if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) {
+ return ret;
+ }
+
+
+ vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
+ if (vb == NULL) {
+ return DRM_ERR(EAGAIN);
+ }
+
+ memcpy(vb, dev_priv->pci_buf, cmd->size);
+
+ dev_priv->dma_low += cmd->size;
+
+ /*
+ * Small submissions somehow stalls the CPU. (AGP cache effects?)
+ * pad to greater size.
+ */
+
+ if (cmd->size < 0x100)
+ via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3);
+ via_cmdbuf_pause(dev_priv);
+
+ return 0;
+}
+
+int via_driver_dma_quiescent(drm_device_t * dev)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+
+ if (!via_wait_idle(dev_priv)) {
+ return DRM_ERR(EBUSY);
+ }
+ return 0;
+}
+
+int via_flush_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
+ return via_driver_dma_quiescent(dev);
+}
+
+int via_cmdbuffer(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_cmdbuffer_t cmdbuf;
+ int ret;
+
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
+ DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t *) data,
+ sizeof(cmdbuf));
+
+ DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size);
+
+ ret = via_dispatch_cmdbuffer(dev, &cmdbuf);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+extern int
+via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size);
+static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
+ drm_via_cmdbuffer_t * cmd)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ if (cmd->size > VIA_PCI_BUF_SIZE) {
+ return DRM_ERR(ENOMEM);
+ }
+ if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+ return DRM_ERR(EFAULT);
+
+ if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) {
+ return ret;
+ }
+
+ ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size);
+ return ret;
+}
+
+int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_cmdbuffer_t cmdbuf;
+ int ret;
+
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
+ DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t *) data,
+ sizeof(cmdbuf));
+
+ DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf,
+ cmdbuf.size);
+
+ ret = via_dispatch_pci_cmdbuffer(dev, &cmdbuf);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
+ uint32_t * vb, int qw_count)
+{
+ for (; qw_count > 0; --qw_count) {
+ VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
+ }
+ return vb;
+}
+
+
+/*
+ * This function is used internally by ring buffer mangement code.
+ *
+ * Returns virtual pointer to ring buffer.
+ */
+static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
+{
+ return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
+}
+
+/*
+ * Hooks a segment of data into the tail of the ring-buffer by
+ * modifying the pause address stored in the buffer itself. If
+ * the regulator has already paused, restart it.
+ */
+static int via_hook_segment(drm_via_private_t *dev_priv,
+ uint32_t pause_addr_hi, uint32_t pause_addr_lo,
+ int no_pci_fire)
+{
+ int paused, count;
+ volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
+
+ via_flush_write_combine();
+ while(! *(via_get_dma(dev_priv)-1));
+ *dev_priv->last_pause_ptr = pause_addr_lo;
+ via_flush_write_combine();
+
+ /*
+ * The below statement is inserted to really force the flush.
+ * Not sure it is needed.
+ */
+
+ while(! *dev_priv->last_pause_ptr);
+ dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
+ while(! *dev_priv->last_pause_ptr);
+
+
+ paused = 0;
+ count = 20;
+
+ while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
+ if ((count <= 8) && (count >= 0)) {
+ uint32_t rgtr, ptr;
+ rgtr = *(dev_priv->hw_addr_ptr);
+ ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
+ CMDBUF_ALIGNMENT_SIZE;
+ if (rgtr <= ptr) {
+ DRM_ERROR("Command regulator\npaused at count %d, address %x, "
+ "while current pause address is %x.\n"
+ "Please mail this message to "
+ "<unichrome-devel@lists.sourceforge.net>\n",
+ count, rgtr, ptr);
+ }
+ }
+
+ if (paused && !no_pci_fire) {
+ uint32_t rgtr,ptr;
+ uint32_t ptr_low;
+
+ count = 1000000;
+ while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
+
+ rgtr = *(dev_priv->hw_addr_ptr);
+ ptr = ((char *)paused_at - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+
+
+ ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ?
+ ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
+ if (rgtr <= ptr && rgtr >= ptr_low) {
+ VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+ VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
+ VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
+ }
+ }
+ return paused;
+}
+
+
+
+static int via_wait_idle(drm_via_private_t * dev_priv)
+{
+ int count = 10000000;
+ while (count-- && (VIA_READ(VIA_REG_STATUS) &
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
+ VIA_3D_ENG_BUSY))) ;
+ return count;
+}
+
+static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
+ uint32_t addr, uint32_t *cmd_addr_hi,
+ uint32_t *cmd_addr_lo,
+ int skip_wait)
+{
+ uint32_t agp_base;
+ uint32_t cmd_addr, addr_lo, addr_hi;
+ uint32_t *vb;
+ uint32_t qw_pad_count;
+
+ if (!skip_wait)
+ via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
+
+ vb = via_get_dma(dev_priv);
+ VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
+ (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
+ agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
+ ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
+
+
+ cmd_addr = (addr) ? addr :
+ agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
+ addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
+ (cmd_addr & HC_HAGPBpL_MASK));
+ addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
+
+ vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
+ VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi,
+ *cmd_addr_lo = addr_lo);
+ return vb;
+}
+
+
+
+
+static void via_cmdbuf_start(drm_via_private_t * dev_priv)
+{
+ uint32_t pause_addr_lo, pause_addr_hi;
+ uint32_t start_addr, start_addr_lo;
+ uint32_t end_addr, end_addr_lo;
+ uint32_t command;
+ uint32_t agp_base;
+
+
+ dev_priv->dma_low = 0;
+
+ agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ start_addr = agp_base;
+ end_addr = agp_base + dev_priv->dma_high;
+
+ start_addr_lo = ((HC_SubA_HAGPBstL << 24) | (start_addr & 0xFFFFFF));
+ end_addr_lo = ((HC_SubA_HAGPBendL << 24) | (end_addr & 0xFFFFFF));
+ command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
+ ((end_addr & 0xff000000) >> 16));
+
+ dev_priv->last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
+ &pause_addr_hi, & pause_addr_lo, 1) - 1;
+
+ via_flush_write_combine();
+ while(! *dev_priv->last_pause_ptr);
+
+ VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+ VIA_WRITE(VIA_REG_TRANSPACE, command);
+ VIA_WRITE(VIA_REG_TRANSPACE, start_addr_lo);
+ VIA_WRITE(VIA_REG_TRANSPACE, end_addr_lo);
+
+ VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
+ VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
+
+ VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
+}
+
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
+{
+ uint32_t *vb;
+
+ via_cmdbuf_wait(dev_priv, qwords + 2);
+ vb = via_get_dma(dev_priv);
+ VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
+ via_align_buffer(dev_priv,vb,qwords);
+}
+
+static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
+{
+ uint32_t *vb = via_get_dma(dev_priv);
+ SetReg2DAGP(0x0C, (0 | (0 << 16)));
+ SetReg2DAGP(0x10, 0 | (0 << 16));
+ SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
+}
+
+
+static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
+{
+ uint32_t agp_base;
+ uint32_t pause_addr_lo, pause_addr_hi;
+ uint32_t jump_addr_lo, jump_addr_hi;
+ volatile uint32_t *last_pause_ptr;
+ uint32_t dma_low_save1, dma_low_save2;
+
+ agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+ via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
+ &jump_addr_lo, 0);
+
+ dev_priv->dma_wrap = dev_priv->dma_low;
+
+
+ /*
+ * Wrap command buffer to the beginning.
+ */
+
+ dev_priv->dma_low = 0;
+ if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) {
+ DRM_ERROR("via_cmdbuf_jump failed\n");
+ }
+
+ via_dummy_bitblt(dev_priv);
+ via_dummy_bitblt(dev_priv);
+
+ last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) -1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0);
+
+ *last_pause_ptr = pause_addr_lo;
+ dma_low_save1 = dev_priv->dma_low;
+
+ /*
+ * Now, set a trap that will pause the regulator if it tries to rerun the old
+ * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
+ * and reissues the jump command over PCI, while the regulator has already taken the jump
+ * and actually paused at the current buffer end).
+ * There appears to be no other way to detect this condition, since the hw_addr_pointer
+ * does not seem to get updated immediately when a jump occurs.
+ */
+
+ last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) -1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0);
+ *last_pause_ptr = pause_addr_lo;
+
+ dma_low_save2 = dev_priv->dma_low;
+ dev_priv->dma_low = dma_low_save1;
+ via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ dev_priv->dma_low = dma_low_save2;
+ via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+}
+
+
+static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
+{
+ via_cmdbuf_jump(dev_priv);
+}
+
+static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
+{
+ uint32_t pause_addr_lo, pause_addr_hi;
+
+ via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
+ via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+}
+
+
+static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
+{
+ via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
+}
+
+static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
+{
+ via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
+ via_wait_idle(dev_priv);
+}
+
+/*
+ * User interface to the space and lag functions.
+ */
+
+int
+via_cmdbuf_size(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_cmdbuf_size_t d_siz;
+ int ret = 0;
+ uint32_t tmp_size, count;
+ drm_via_private_t *dev_priv;
+
+ DRM_DEBUG("via cmdbuf_size\n");
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
+ dev_priv = (drm_via_private_t *) dev->dev_private;
+
+ if (dev_priv->ring.virtual_start == NULL) {
+ DRM_ERROR("%s called without initializing AGP ring buffer.\n",
+ __FUNCTION__);
+ return DRM_ERR(EFAULT);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t *) data,
+ sizeof(d_siz));
+
+
+ count = 1000000;
+ tmp_size = d_siz.size;
+ switch(d_siz.func) {
+ case VIA_CMDBUF_SPACE:
+ while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) {
+ if (!d_siz.wait) {
+ break;
+ }
+ }
+ if (!count) {
+ DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
+ ret = DRM_ERR(EAGAIN);
+ }
+ break;
+ case VIA_CMDBUF_LAG:
+ while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) {
+ if (!d_siz.wait) {
+ break;
+ }
+ }
+ if (!count) {
+ DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
+ ret = DRM_ERR(EAGAIN);
+ }
+ break;
+ default:
+ ret = DRM_ERR(EFAULT);
+ }
+ d_siz.size = tmp_size;
+
+ DRM_COPY_TO_USER_IOCTL((drm_via_cmdbuf_size_t *) data, d_siz,
+ sizeof(d_siz));
+ return ret;
+}
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
new file mode 100644
index 00000000000..4588c9bd181
--- /dev/null
+++ b/drivers/char/drm/via_drm.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _VIA_DRM_H_
+#define _VIA_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _VIA_DEFINES_
+#define _VIA_DEFINES_
+
+#ifndef __KERNEL__
+#include "via_drmclient.h"
+#endif
+
+#define VIA_NR_SAREA_CLIPRECTS 8
+#define VIA_NR_XVMC_PORTS 10
+#define VIA_NR_XVMC_LOCKS 5
+#define VIA_MAX_CACHELINE_SIZE 64
+#define XVMCLOCKPTR(saPriv,lockNo) \
+ ((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
+ (VIA_MAX_CACHELINE_SIZE - 1)) & \
+ ~(VIA_MAX_CACHELINE_SIZE - 1)) + \
+ VIA_MAX_CACHELINE_SIZE*(lockNo)))
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define VIA_NR_TEX_REGIONS 64
+#define VIA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define VIA_UPLOAD_CTX 0x4
+#define VIA_UPLOAD_BUFFERS 0x8
+#define VIA_UPLOAD_TEX0 0x10
+#define VIA_UPLOAD_TEX1 0x20
+#define VIA_UPLOAD_CLIPRECTS 0x40
+#define VIA_UPLOAD_ALL 0xff
+
+/* VIA specific ioctls */
+#define DRM_VIA_ALLOCMEM 0x00
+#define DRM_VIA_FREEMEM 0x01
+#define DRM_VIA_AGP_INIT 0x02
+#define DRM_VIA_FB_INIT 0x03
+#define DRM_VIA_MAP_INIT 0x04
+#define DRM_VIA_DEC_FUTEX 0x05
+#define NOT_USED
+#define DRM_VIA_DMA_INIT 0x07
+#define DRM_VIA_CMDBUFFER 0x08
+#define DRM_VIA_FLUSH 0x09
+#define DRM_VIA_PCICMD 0x0a
+#define DRM_VIA_CMDBUF_SIZE 0x0b
+#define NOT_USED
+#define DRM_VIA_WAIT_IRQ 0x0d
+
+#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
+#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
+#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
+#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
+#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
+#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH)
+#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
+ drm_via_cmdbuf_size_t)
+#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer. These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+#define VIA_TEX_SETUP_SIZE 8
+
+/* Flags for clear ioctl
+ */
+#define VIA_FRONT 0x1
+#define VIA_BACK 0x2
+#define VIA_DEPTH 0x4
+#define VIA_STENCIL 0x8
+#define VIDEO 0
+#define AGP 1
+typedef struct {
+ uint32_t offset;
+ uint32_t size;
+} drm_via_agp_t;
+
+typedef struct {
+ uint32_t offset;
+ uint32_t size;
+} drm_via_fb_t;
+
+typedef struct {
+ uint32_t context;
+ uint32_t type;
+ uint32_t size;
+ unsigned long index;
+ unsigned long offset;
+} drm_via_mem_t;
+
+typedef struct _drm_via_init {
+ enum {
+ VIA_INIT_MAP = 0x01,
+ VIA_CLEANUP_MAP = 0x02
+ } func;
+
+ unsigned long sarea_priv_offset;
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long agpAddr;
+} drm_via_init_t;
+
+typedef struct _drm_via_futex {
+ enum {
+ VIA_FUTEX_WAIT = 0x00,
+ VIA_FUTEX_WAKE = 0X01
+ } func;
+ uint32_t ms;
+ uint32_t lock;
+ uint32_t val;
+} drm_via_futex_t;
+
+typedef struct _drm_via_dma_init {
+ enum {
+ VIA_INIT_DMA = 0x01,
+ VIA_CLEANUP_DMA = 0x02,
+ VIA_DMA_INITIALIZED = 0x03
+ } func;
+
+ unsigned long offset;
+ unsigned long size;
+ unsigned long reg_pause_addr;
+} drm_via_dma_init_t;
+
+typedef struct _drm_via_cmdbuffer {
+ char *buf;
+ unsigned long size;
+} drm_via_cmdbuffer_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_via_tex_region {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char inUse; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} drm_via_tex_region_t;
+
+typedef struct _drm_via_sarea {
+ unsigned int dirty;
+ unsigned int nbox;
+ drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS];
+ drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
+ int texAge; /* last time texture was uploaded */
+ int ctxOwner; /* last context to upload state */
+ int vertexPrim;
+
+ /*
+ * Below is for XvMC.
+ * We want the lock integers alone on, and aligned to, a cache line.
+ * Therefore this somewhat strange construct.
+ */
+
+ char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
+
+ unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
+ unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
+ unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
+
+} drm_via_sarea_t;
+
+typedef struct _drm_via_cmdbuf_size {
+ enum {
+ VIA_CMDBUF_SPACE = 0x01,
+ VIA_CMDBUF_LAG = 0x02
+ } func;
+ int wait;
+ uint32_t size;
+} drm_via_cmdbuf_size_t;
+
+typedef enum {
+ VIA_IRQ_ABSOLUTE = 0x0,
+ VIA_IRQ_RELATIVE = 0x1,
+ VIA_IRQ_SIGNAL = 0x10000000,
+ VIA_IRQ_FORCE_SEQUENCE = 0x20000000
+} via_irq_seq_type_t;
+
+#define VIA_IRQ_FLAGS_MASK 0xF0000000
+
+struct drm_via_wait_irq_request{
+ unsigned irq;
+ via_irq_seq_type_t type;
+ uint32_t sequence;
+ uint32_t signal;
+};
+
+typedef union drm_via_irqwait {
+ struct drm_via_wait_irq_request request;
+ struct drm_wait_vblank_reply reply;
+} drm_via_irqwait_t;
+
+#ifdef __KERNEL__
+
+int via_fb_init(DRM_IOCTL_ARGS);
+int via_mem_alloc(DRM_IOCTL_ARGS);
+int via_mem_free(DRM_IOCTL_ARGS);
+int via_agp_init(DRM_IOCTL_ARGS);
+int via_map_init(DRM_IOCTL_ARGS);
+int via_decoder_futex(DRM_IOCTL_ARGS);
+int via_dma_init(DRM_IOCTL_ARGS);
+int via_cmdbuffer(DRM_IOCTL_ARGS);
+int via_flush_ioctl(DRM_IOCTL_ARGS);
+int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
+int via_cmdbuf_size(DRM_IOCTL_ARGS);
+int via_wait_irq(DRM_IOCTL_ARGS);
+
+#endif
+#endif /* _VIA_DRM_H_ */
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
new file mode 100644
index 00000000000..275eefc7922
--- /dev/null
+++ b/drivers/char/drm/via_drv.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+#include "drm_pciids.h"
+
+static int postinit(struct drm_device *dev, unsigned long flags)
+{
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+ DRIVER_NAME,
+ DRIVER_MAJOR,
+ DRIVER_MINOR,
+ DRIVER_PATCHLEVEL,
+ DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+ );
+ return 0;
+}
+
+static int version(drm_version_t * version)
+{
+ int len;
+
+ version->version_major = DRIVER_MAJOR;
+ version->version_minor = DRIVER_MINOR;
+ version->version_patchlevel = DRIVER_PATCHLEVEL;
+ DRM_COPY(version->name, DRIVER_NAME);
+ DRM_COPY(version->date, DRIVER_DATE);
+ DRM_COPY(version->desc, DRIVER_DESC);
+ return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+ viadrv_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+ [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0},
+ [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0}
+};
+
+static struct drm_driver driver = {
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
+ DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ .context_ctor = via_init_context,
+ .context_dtor = via_final_context,
+ .vblank_wait = via_driver_vblank_wait,
+ .irq_preinstall = via_driver_irq_preinstall,
+ .irq_postinstall = via_driver_irq_postinstall,
+ .irq_uninstall = via_driver_irq_uninstall,
+ .irq_handler = via_driver_irq_handler,
+ .dma_quiescent = via_driver_dma_quiescent,
+ .reclaim_buffers = drm_core_reclaim_buffers,
+ .get_map_ofs = drm_core_get_map_ofs,
+ .get_reg_ofs = drm_core_get_reg_ofs,
+ .postinit = postinit,
+ .version = version,
+ .ioctls = ioctls,
+ .num_ioctls = DRM_ARRAY_SIZE(ioctls),
+ .fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
+ .pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ }
+};
+
+static int __init via_init(void)
+{
+ via_init_command_verifier();
+ return drm_init(&driver);
+}
+
+static void __exit via_exit(void)
+{
+ drm_exit(&driver);
+}
+
+module_init(via_init);
+module_exit(via_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
new file mode 100644
index 00000000000..4eaa8b7c4c9
--- /dev/null
+++ b/drivers/char/drm/via_drv.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _VIA_DRV_H_
+#define _VIA_DRV_H_
+
+#define DRIVER_AUTHOR "VIA"
+
+#define DRIVER_NAME "via"
+#define DRIVER_DESC "VIA Unichrome / Pro"
+#define DRIVER_DATE "20050523"
+
+#define DRIVER_MAJOR 2
+#define DRIVER_MINOR 6
+#define DRIVER_PATCHLEVEL 3
+
+#include "via_verifier.h"
+
+#define VIA_PCI_BUF_SIZE 60000
+#define VIA_FIRE_BUF_SIZE 1024
+#define VIA_NUM_IRQS 2
+
+
+
+typedef struct drm_via_ring_buffer {
+ drm_map_t map;
+ char *virtual_start;
+} drm_via_ring_buffer_t;
+
+typedef uint32_t maskarray_t[5];
+
+typedef struct drm_via_irq {
+ atomic_t irq_received;
+ uint32_t pending_mask;
+ uint32_t enable_mask;
+ wait_queue_head_t irq_queue;
+} drm_via_irq_t;
+
+typedef struct drm_via_private {
+ drm_via_sarea_t *sarea_priv;
+ drm_map_t *sarea;
+ drm_map_t *fb;
+ drm_map_t *mmio;
+ unsigned long agpAddr;
+ wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
+ char *dma_ptr;
+ unsigned int dma_low;
+ unsigned int dma_high;
+ unsigned int dma_offset;
+ uint32_t dma_wrap;
+ volatile uint32_t *last_pause_ptr;
+ volatile uint32_t *hw_addr_ptr;
+ drm_via_ring_buffer_t ring;
+ struct timeval last_vblank;
+ int last_vblank_valid;
+ unsigned usec_per_vblank;
+ drm_via_state_t hc_state;
+ char pci_buf[VIA_PCI_BUF_SIZE];
+ const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
+ uint32_t num_fire_offsets;
+ int pro_group_a;
+ drm_via_irq_t via_irqs[VIA_NUM_IRQS];
+ unsigned num_irqs;
+ maskarray_t *irq_masks;
+ uint32_t irq_enable_mask;
+ uint32_t irq_pending_mask;
+} drm_via_private_t;
+
+/* VIA MMIO register access */
+#define VIA_BASE ((dev_priv->mmio))
+
+#define VIA_READ(reg) DRM_READ32(VIA_BASE, reg)
+#define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val)
+#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
+#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
+
+extern int via_init_context(drm_device_t * dev, int context);
+extern int via_final_context(drm_device_t * dev, int context);
+
+extern int via_do_cleanup_map(drm_device_t * dev);
+extern int via_map_init(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+
+extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
+extern void via_driver_irq_preinstall(drm_device_t * dev);
+extern void via_driver_irq_postinstall(drm_device_t * dev);
+extern void via_driver_irq_uninstall(drm_device_t * dev);
+
+extern int via_dma_cleanup(drm_device_t * dev);
+extern void via_init_command_verifier(void);
+extern int via_driver_dma_quiescent(drm_device_t * dev);
+extern void via_init_futex(drm_via_private_t *dev_priv);
+extern void via_cleanup_futex(drm_via_private_t *dev_priv);
+extern void via_release_futex(drm_via_private_t *dev_priv, int context);
+
+
+#endif
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c
new file mode 100644
index 00000000000..daf3df75a20
--- /dev/null
+++ b/drivers/char/drm/via_ds.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#include "via_ds.h"
+extern unsigned int VIA_DEBUG;
+
+set_t *via_setInit(void)
+{
+ int i;
+ set_t *set;
+ set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+ for (i = 0; i < SET_SIZE; i++) {
+ set->list[i].free_next = i + 1;
+ set->list[i].alloc_next = -1;
+ }
+ set->list[SET_SIZE - 1].free_next = -1;
+ set->free = 0;
+ set->alloc = -1;
+ set->trace = -1;
+ return set;
+}
+
+int via_setAdd(set_t * set, ITEM_TYPE item)
+{
+ int free = set->free;
+ if (free != -1) {
+ set->list[free].val = item;
+ set->free = set->list[free].free_next;
+ } else {
+ return 0;
+ }
+ set->list[free].alloc_next = set->alloc;
+ set->alloc = free;
+ set->list[free].free_next = -1;
+ return 1;
+}
+
+int via_setDel(set_t * set, ITEM_TYPE item)
+{
+ int alloc = set->alloc;
+ int prev = -1;
+
+ while (alloc != -1) {
+ if (set->list[alloc].val == item) {
+ if (prev != -1)
+ set->list[prev].alloc_next =
+ set->list[alloc].alloc_next;
+ else
+ set->alloc = set->list[alloc].alloc_next;
+ break;
+ }
+ prev = alloc;
+ alloc = set->list[alloc].alloc_next;
+ }
+
+ if (alloc == -1)
+ return 0;
+
+ set->list[alloc].free_next = set->free;
+ set->free = alloc;
+ set->list[alloc].alloc_next = -1;
+
+ return 1;
+}
+
+/* setFirst -> setAdd -> setNext is wrong */
+
+int via_setFirst(set_t * set, ITEM_TYPE * item)
+{
+ if (set->alloc == -1)
+ return 0;
+
+ *item = set->list[set->alloc].val;
+ set->trace = set->list[set->alloc].alloc_next;
+
+ return 1;
+}
+
+int via_setNext(set_t * set, ITEM_TYPE * item)
+{
+ if (set->trace == -1)
+ return 0;
+
+ *item = set->list[set->trace].val;
+ set->trace = set->list[set->trace].alloc_next;
+
+ return 1;
+}
+
+int via_setDestroy(set_t * set)
+{
+ drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
+
+ return 1;
+}
+
+#define ISFREE(bptr) ((bptr)->free)
+
+#define fprintf(fmt, arg...) do{}while(0)
+
+memHeap_t *via_mmInit(int ofs, int size)
+{
+ PMemBlock blocks;
+
+ if (size <= 0)
+ return 0;
+
+ blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+
+ if (blocks) {
+ blocks->ofs = ofs;
+ blocks->size = size;
+ blocks->free = 1;
+ return (memHeap_t *) blocks;
+ } else
+ return 0;
+}
+
+static TMemBlock *SliceBlock(TMemBlock * p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ TMemBlock *newblock;
+
+ /* break left */
+ if (startofs > p->ofs) {
+ newblock =
+ (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+ DRM_MEM_DRIVER);
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size -= newblock->size;
+ p->next = newblock;
+ p = newblock;
+ }
+
+ /* break right */
+ if (size < p->size) {
+ newblock =
+ (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+ DRM_MEM_DRIVER);
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size = size;
+ p->next = newblock;
+ }
+
+ /* p = middle block */
+ p->align = alignment;
+ p->free = 0;
+ p->reserved = reserved;
+ return p;
+}
+
+PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
+ int startSearch)
+{
+ int mask, startofs, endofs;
+ TMemBlock *p;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+
+ mask = (1 << align2) - 1;
+ startofs = 0;
+ p = (TMemBlock *) heap;
+
+ while (p) {
+ if (ISFREE(p)) {
+ startofs = (p->ofs + mask) & ~mask;
+
+ if (startofs < startSearch)
+ startofs = startSearch;
+
+ endofs = startofs + size;
+
+ if (endofs <= (p->ofs + p->size))
+ break;
+ }
+
+ p = p->next;
+ }
+
+ if (!p)
+ return NULL;
+
+ p = SliceBlock(p, startofs, size, 0, mask + 1);
+ p->heap = heap;
+
+ return p;
+}
+
+static __inline__ int Join2Blocks(TMemBlock * p)
+{
+ if (p->free && p->next && p->next->free) {
+ TMemBlock *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int via_mmFreeMem(PMemBlock b)
+{
+ TMemBlock *p, *prev;
+
+ if (!b)
+ return 0;
+
+ if (!b->heap) {
+ fprintf(stderr, "no heap\n");
+
+ return -1;
+ }
+
+ p = b->heap;
+ prev = NULL;
+
+ while (p && p != b) {
+ prev = p;
+ p = p->next;
+ }
+
+ if (!p || p->free || p->reserved) {
+ if (!p)
+ fprintf(stderr, "block not found in heap\n");
+ else if (p->free)
+ fprintf(stderr, "block already free\n");
+ else
+ fprintf(stderr, "block is reserved\n");
+
+ return -1;
+ }
+
+ p->free = 1;
+ Join2Blocks(p);
+
+ if (prev)
+ Join2Blocks(prev);
+
+ return 0;
+}
diff --git a/drivers/char/drm/via_ds.h b/drivers/char/drm/via_ds.h
new file mode 100644
index 00000000000..be9c7f9f1ae
--- /dev/null
+++ b/drivers/char/drm/via_ds.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _via_ds_h_
+#define _via_ds_h_
+
+#include "drmP.h"
+
+/* Set Data Structure */
+#define SET_SIZE 5000
+typedef unsigned long ITEM_TYPE;
+
+typedef struct {
+ ITEM_TYPE val;
+ int alloc_next, free_next;
+} list_item_t;
+
+typedef struct {
+ int alloc;
+ int free;
+ int trace;
+ list_item_t list[SET_SIZE];
+} set_t;
+
+set_t *via_setInit(void);
+int via_setAdd(set_t * set, ITEM_TYPE item);
+int via_setDel(set_t * set, ITEM_TYPE item);
+int via_setFirst(set_t * set, ITEM_TYPE * item);
+int via_setNext(set_t * set, ITEM_TYPE * item);
+int via_setDestroy(set_t * set);
+
+#endif
+
+#ifndef MM_INC
+#define MM_INC
+
+struct mem_block_t {
+ struct mem_block_t *next;
+ struct mem_block_t *heap;
+ int ofs, size;
+ int align;
+ int free:1;
+ int reserved:1;
+};
+typedef struct mem_block_t TMemBlock;
+typedef struct mem_block_t *PMemBlock;
+
+/* a heap is just the first block in a chain */
+typedef struct mem_block_t memHeap_t;
+
+static __inline__ int mmBlockSize(PMemBlock b)
+{
+ return b->size;
+}
+
+static __inline__ int mmOffset(PMemBlock b)
+{
+ return b->ofs;
+}
+
+static __inline__ void mmMarkReserved(PMemBlock b)
+{
+ b->reserved = 1;
+}
+
+/*
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+memHeap_t *via_mmInit(int ofs, int size);
+
+PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
+ int startSearch);
+
+/*
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+int via_mmFreeMem(PMemBlock b);
+
+#endif
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
new file mode 100644
index 00000000000..e8027f3a93b
--- /dev/null
+++ b/drivers/char/drm/via_irq.c
@@ -0,0 +1,339 @@
+/* via_irq.c
+ *
+ * Copyright 2004 BEAM Ltd.
+ * Copyright 2002 Tungsten Graphics, Inc.
+ * Copyright 2005 Thomas Hellstrom.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BEAM LTD, TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Terry Barnaby <terry1@beam.ltd.uk>
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Thomas Hellstrom <unichrome@shipmail.org>
+ *
+ * This code provides standard DRM access to the Via Unichrome / Pro Vertical blank
+ * interrupt, as well as an infrastructure to handle other interrupts of the chip.
+ * The refresh rate is also calculated for video playback sync purposes.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+#define VIA_REG_INTERRUPT 0x200
+
+/* VIA_REG_INTERRUPT */
+#define VIA_IRQ_GLOBAL (1 << 31)
+#define VIA_IRQ_VBLANK_ENABLE (1 << 19)
+#define VIA_IRQ_VBLANK_PENDING (1 << 3)
+#define VIA_IRQ_HQV0_ENABLE (1 << 11)
+#define VIA_IRQ_HQV1_ENABLE (1 << 25)
+#define VIA_IRQ_HQV0_PENDING (1 << 9)
+#define VIA_IRQ_HQV1_PENDING (1 << 10)
+
+/*
+ * Device-specific IRQs go here. This type might need to be extended with
+ * the register if there are multiple IRQ control registers.
+ * Currently we activate the HQV interrupts of Unichrome Pro group A.
+ */
+
+static maskarray_t via_pro_group_a_irqs[] = {
+ {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 },
+ {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }};
+static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
+
+static maskarray_t via_unichrome_irqs[] = {};
+static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
+
+
+static unsigned time_diff(struct timeval *now,struct timeval *then)
+{
+ return (now->tv_usec >= then->tv_usec) ?
+ now->tv_usec - then->tv_usec :
+ 1000000 - (then->tv_usec - now->tv_usec);
+}
+
+irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
+{
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ u32 status;
+ int handled = 0;
+ struct timeval cur_vblank;
+ drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+ int i;
+
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ if (status & VIA_IRQ_VBLANK_PENDING) {
+ atomic_inc(&dev->vbl_received);
+ if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ do_gettimeofday(&cur_vblank);
+ if (dev_priv->last_vblank_valid) {
+ dev_priv->usec_per_vblank =
+ time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4;
+ }
+ dev_priv->last_vblank = cur_vblank;
+ dev_priv->last_vblank_valid = 1;
+ }
+ if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ DRM_DEBUG("US per vblank is: %u\n",
+ dev_priv->usec_per_vblank);
+ }
+ DRM_WAKEUP(&dev->vbl_queue);
+ drm_vbl_send_signals(dev);
+ handled = 1;
+ }
+
+
+ for (i=0; i<dev_priv->num_irqs; ++i) {
+ if (status & cur_irq->pending_mask) {
+ atomic_inc( &cur_irq->irq_received );
+ DRM_WAKEUP( &cur_irq->irq_queue );
+ handled = 1;
+ }
+ cur_irq++;
+ }
+
+ /* Acknowlege interrupts */
+ VIA_WRITE(VIA_REG_INTERRUPT, status);
+
+
+ if (handled)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
+{
+ u32 status;
+
+ if (dev_priv) {
+ /* Acknowlege interrupts */
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status |
+ dev_priv->irq_pending_mask);
+ }
+}
+
+int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ DRM_DEBUG("viadrv_vblank_wait\n");
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ viadrv_acknowledge_irqs(dev_priv);
+
+ /* Assume that the user has missed the current sequence number
+ * by about a day rather than she wants to wait for years
+ * using vertical blanks...
+ */
+
+ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ (((cur_vblank = atomic_read(&dev->vbl_received)) -
+ *sequence) <= (1 << 23)));
+
+ *sequence = cur_vblank;
+ return ret;
+}
+
+static int
+via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
+ unsigned int *sequence)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ unsigned int cur_irq_sequence;
+ drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+ int ret = 0;
+ maskarray_t *masks = dev_priv->irq_masks;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return DRM_ERR(EINVAL);
+ }
+
+ if (irq >= dev_priv->num_irqs ) {
+ DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq);
+ return DRM_ERR(EINVAL);
+ }
+
+ cur_irq += irq;
+
+ if (masks[irq][2] && !force_sequence) {
+ DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+ ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4]));
+ cur_irq_sequence = atomic_read(&cur_irq->irq_received);
+ } else {
+ DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+ (((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) -
+ *sequence) <= (1 << 23)));
+ }
+ *sequence = cur_irq_sequence;
+ return ret;
+}
+
+
+/*
+ * drm_dma.h hooks
+ */
+
+void via_driver_irq_preinstall(drm_device_t * dev)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ u32 status;
+ drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+ int i;
+
+ DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
+ if (dev_priv) {
+
+ dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
+ dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
+
+ dev_priv->irq_masks = (dev_priv->pro_group_a) ?
+ via_pro_group_a_irqs : via_unichrome_irqs;
+ dev_priv->num_irqs = (dev_priv->pro_group_a) ?
+ via_num_pro_group_a : via_num_unichrome;
+
+ for(i=0; i < dev_priv->num_irqs; ++i) {
+ atomic_set(&cur_irq->irq_received, 0);
+ cur_irq->enable_mask = dev_priv->irq_masks[i][0];
+ cur_irq->pending_mask = dev_priv->irq_masks[i][1];
+ DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
+ dev_priv->irq_enable_mask |= cur_irq->enable_mask;
+ dev_priv->irq_pending_mask |= cur_irq->pending_mask;
+ cur_irq++;
+
+ DRM_DEBUG("Initializing IRQ %d\n", i);
+ }
+
+ dev_priv->last_vblank_valid = 0;
+
+ // Clear VSync interrupt regs
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status &
+ ~(dev_priv->irq_enable_mask));
+
+ /* Clear bits if they're already high */
+ viadrv_acknowledge_irqs(dev_priv);
+ }
+}
+
+void via_driver_irq_postinstall(drm_device_t * dev)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ u32 status;
+
+ DRM_DEBUG("via_driver_irq_postinstall\n");
+ if (dev_priv) {
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
+ | dev_priv->irq_enable_mask);
+
+ /* Some magic, oh for some data sheets ! */
+
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+
+ }
+}
+
+void via_driver_irq_uninstall(drm_device_t * dev)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ u32 status;
+
+ DRM_DEBUG("driver_irq_uninstall)\n");
+ if (dev_priv) {
+
+ /* Some more magic, oh for some data sheets ! */
+
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
+
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status &
+ ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
+ }
+}
+
+int via_wait_irq(DRM_IOCTL_ARGS)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ drm_via_irqwait_t __user *argp = (void __user *)data;
+ drm_via_irqwait_t irqwait;
+ struct timeval now;
+ int ret = 0;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+ int force_sequence;
+
+ if (!dev->irq)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait));
+ if (irqwait.request.irq >= dev_priv->num_irqs) {
+ DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ irqwait.request.irq);
+ return DRM_ERR(EINVAL);
+ }
+
+ cur_irq += irqwait.request.irq;
+
+ switch (irqwait.request.type & ~VIA_IRQ_FLAGS_MASK) {
+ case VIA_IRQ_RELATIVE:
+ irqwait.request.sequence += atomic_read(&cur_irq->irq_received);
+ irqwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+ case VIA_IRQ_ABSOLUTE:
+ break;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+
+ if (irqwait.request.type & VIA_IRQ_SIGNAL) {
+ DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
+ __FUNCTION__);
+ return DRM_ERR(EINVAL);
+ }
+
+ force_sequence = (irqwait.request.type & VIA_IRQ_FORCE_SEQUENCE);
+
+ ret = via_driver_irq_wait(dev, irqwait.request.irq, force_sequence,
+ &irqwait.request.sequence);
+ do_gettimeofday(&now);
+ irqwait.reply.tval_sec = now.tv_sec;
+ irqwait.reply.tval_usec = now.tv_usec;
+
+ DRM_COPY_TO_USER_IOCTL(argp, irqwait, sizeof(irqwait));
+
+ return ret;
+}
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
new file mode 100644
index 00000000000..0be829b6ec6
--- /dev/null
+++ b/drivers/char/drm/via_map.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
+{
+ drm_via_private_t *dev_priv;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+
+ memset(dev_priv, 0, sizeof(drm_via_private_t));
+
+ DRM_GETSAREA();
+ if (!dev_priv->sarea) {
+ DRM_ERROR("could not find sarea!\n");
+ dev->dev_private = (void *)dev_priv;
+ via_do_cleanup_map(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->fb = drm_core_findmap(dev, init->fb_offset);
+ if (!dev_priv->fb) {
+ DRM_ERROR("could not find framebuffer!\n");
+ dev->dev_private = (void *)dev_priv;
+ via_do_cleanup_map(dev);
+ return -EINVAL;
+ }
+ dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
+ if (!dev_priv->mmio) {
+ DRM_ERROR("could not find mmio region!\n");
+ dev->dev_private = (void *)dev_priv;
+ via_do_cleanup_map(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->sarea_priv =
+ (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
+
+ dev_priv->agpAddr = init->agpAddr;
+
+ via_init_futex( dev_priv );
+ dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
+
+ dev->dev_private = (void *)dev_priv;
+ return 0;
+}
+
+int via_do_cleanup_map(drm_device_t * dev)
+{
+ if (dev->dev_private) {
+
+ drm_via_private_t *dev_priv = dev->dev_private;
+
+ via_dma_cleanup(dev);
+
+ drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ }
+
+ return 0;
+}
+
+int via_map_init(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_init_t init;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t *) data, sizeof(init));
+
+ switch (init.func) {
+ case VIA_INIT_MAP:
+ return via_do_init_map(dev, &init);
+ case VIA_CLEANUP_MAP:
+ return via_do_cleanup_map(dev);
+ }
+
+ return -EINVAL;
+}
+
+
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
new file mode 100644
index 00000000000..c22712f44d4
--- /dev/null
+++ b/drivers/char/drm/via_mm.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "via_ds.h"
+#include "via_mm.h"
+
+#define MAX_CONTEXT 100
+
+typedef struct {
+ int used;
+ int context;
+ set_t *sets[2]; /* 0 for frame buffer, 1 for AGP , 2 for System */
+} via_context_t;
+
+static via_context_t global_ppriv[MAX_CONTEXT];
+
+static int via_agp_alloc(drm_via_mem_t * mem);
+static int via_agp_free(drm_via_mem_t * mem);
+static int via_fb_alloc(drm_via_mem_t * mem);
+static int via_fb_free(drm_via_mem_t * mem);
+
+static int add_alloc_set(int context, int type, unsigned int val)
+{
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ retval = via_setAdd(global_ppriv[i].sets[type], val);
+ break;
+ }
+ }
+
+ return retval;
+}
+
+static int del_alloc_set(int context, int type, unsigned int val)
+{
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ retval = via_setDel(global_ppriv[i].sets[type], val);
+ break;
+ }
+
+ return retval;
+}
+
+/* agp memory management */
+static memHeap_t *AgpHeap = NULL;
+
+int via_agp_init(DRM_IOCTL_ARGS)
+{
+ drm_via_agp_t agp;
+
+ DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t *) data, sizeof(agp));
+
+ AgpHeap = via_mmInit(agp.offset, agp.size);
+
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size);
+
+ return 0;
+}
+
+/* fb memory management */
+static memHeap_t *FBHeap = NULL;
+
+int via_fb_init(DRM_IOCTL_ARGS)
+{
+ drm_via_fb_t fb;
+
+ DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t *) data, sizeof(fb));
+
+ FBHeap = via_mmInit(fb.offset, fb.size);
+
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size);
+
+ return 0;
+}
+
+int via_init_context(struct drm_device *dev, int context)
+{
+ int i;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+
+ if (i >= MAX_CONTEXT) {
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (!global_ppriv[i].used) {
+ global_ppriv[i].context = context;
+ global_ppriv[i].used = 1;
+ global_ppriv[i].sets[0] = via_setInit();
+ global_ppriv[i].sets[1] = via_setInit();
+ DRM_DEBUG("init allocation set, socket=%d,"
+ " context = %d\n", i, context);
+ break;
+ }
+ }
+
+ if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
+ (global_ppriv[i].sets[1] == NULL)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int via_final_context(struct drm_device *dev, int context)
+{
+ int i;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+
+ if (i < MAX_CONTEXT) {
+ set_t *set;
+ ITEM_TYPE item;
+ int retval;
+
+ DRM_DEBUG("find socket %d, context = %d\n", i, context);
+
+ /* Video Memory */
+ set = global_ppriv[i].sets[0];
+ retval = via_setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free video memory 0x%lx\n", item);
+ via_mmFreeMem((PMemBlock) item);
+ retval = via_setNext(set, &item);
+ }
+ via_setDestroy(set);
+
+ /* AGP Memory */
+ set = global_ppriv[i].sets[1];
+ retval = via_setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free agp memory 0x%lx\n", item);
+ via_mmFreeMem((PMemBlock) item);
+ retval = via_setNext(set, &item);
+ }
+ via_setDestroy(set);
+ global_ppriv[i].used = 0;
+ }
+ via_release_futex(dev_priv, context);
+
+
+#if defined(__linux__)
+ /* Linux specific until context tracking code gets ported to BSD */
+ /* Last context, perform cleanup */
+ if (dev->ctx_count == 1 && dev->dev_private) {
+ DRM_DEBUG("Last Context\n");
+ if (dev->irq)
+ drm_irq_uninstall(dev);
+
+ via_cleanup_futex(dev_priv);
+ via_do_cleanup_map(dev);
+ }
+#endif
+
+ return 1;
+}
+
+int via_mem_alloc(DRM_IOCTL_ARGS)
+{
+ drm_via_mem_t mem;
+
+ DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *) data, sizeof(mem));
+
+ switch (mem.type) {
+ case VIDEO:
+ if (via_fb_alloc(&mem) < 0)
+ return -EFAULT;
+ DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *) data, mem,
+ sizeof(mem));
+ return 0;
+ case AGP:
+ if (via_agp_alloc(&mem) < 0)
+ return -EFAULT;
+ DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *) data, mem,
+ sizeof(mem));
+ return 0;
+ }
+
+ return -EFAULT;
+}
+
+static int via_fb_alloc(drm_via_mem_t * mem)
+{
+ drm_via_mm_t fb;
+ PMemBlock block;
+ int retval = 0;
+
+ if (!FBHeap)
+ return -1;
+
+ fb.size = mem->size;
+ fb.context = mem->context;
+
+ block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
+ if (block) {
+ fb.offset = block->ofs;
+ fb.free = (unsigned long)block;
+ if (!add_alloc_set(fb.context, VIDEO, fb.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ via_mmFreeMem((PMemBlock) fb.free);
+ retval = -1;
+ }
+ } else {
+ fb.offset = 0;
+ fb.size = 0;
+ fb.free = 0;
+ retval = -1;
+ }
+
+ mem->offset = fb.offset;
+ mem->index = fb.free;
+
+ DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size,
+ (int)fb.offset);
+
+ return retval;
+}
+
+static int via_agp_alloc(drm_via_mem_t * mem)
+{
+ drm_via_mm_t agp;
+ PMemBlock block;
+ int retval = 0;
+
+ if (!AgpHeap)
+ return -1;
+
+ agp.size = mem->size;
+ agp.context = mem->context;
+
+ block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
+ if (block) {
+ agp.offset = block->ofs;
+ agp.free = (unsigned long)block;
+ if (!add_alloc_set(agp.context, AGP, agp.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ via_mmFreeMem((PMemBlock) agp.free);
+ retval = -1;
+ }
+ } else {
+ agp.offset = 0;
+ agp.size = 0;
+ agp.free = 0;
+ }
+
+ mem->offset = agp.offset;
+ mem->index = agp.free;
+
+ DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size,
+ (unsigned int)agp.offset);
+ return retval;
+}
+
+int via_mem_free(DRM_IOCTL_ARGS)
+{
+ drm_via_mem_t mem;
+
+ DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *) data, sizeof(mem));
+
+ switch (mem.type) {
+
+ case VIDEO:
+ if (via_fb_free(&mem) == 0)
+ return 0;
+ break;
+ case AGP:
+ if (via_agp_free(&mem) == 0)
+ return 0;
+ break;
+ }
+
+ return -EFAULT;
+}
+
+static int via_fb_free(drm_via_mem_t * mem)
+{
+ drm_via_mm_t fb;
+ int retval = 0;
+
+ if (!FBHeap) {
+ return -1;
+ }
+
+ fb.free = mem->index;
+ fb.context = mem->context;
+
+ if (!fb.free) {
+ return -1;
+
+ }
+
+ via_mmFreeMem((PMemBlock) fb.free);
+
+ if (!del_alloc_set(fb.context, VIDEO, fb.free)) {
+ retval = -1;
+ }
+
+ DRM_DEBUG("free fb, free = %ld\n", fb.free);
+
+ return retval;
+}
+
+static int via_agp_free(drm_via_mem_t * mem)
+{
+ drm_via_mm_t agp;
+
+ int retval = 0;
+
+ agp.free = mem->index;
+ agp.context = mem->context;
+
+ if (!agp.free)
+ return -1;
+
+ via_mmFreeMem((PMemBlock) agp.free);
+
+ if (!del_alloc_set(agp.context, AGP, agp.free)) {
+ retval = -1;
+ }
+
+ DRM_DEBUG("free agp, free = %ld\n", agp.free);
+
+ return retval;
+}
diff --git a/drivers/char/drm/via_mm.h b/drivers/char/drm/via_mm.h
new file mode 100644
index 00000000000..d57efda57c7
--- /dev/null
+++ b/drivers/char/drm/via_mm.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _via_drm_mm_h_
+#define _via_drm_mm_h_
+
+typedef struct {
+ unsigned int context;
+ unsigned int size;
+ unsigned long offset;
+ unsigned long free;
+} drm_via_mm_t;
+
+typedef struct {
+ unsigned int size;
+ unsigned long handle;
+ void *virtual;
+} drm_via_dma_t;
+
+#endif
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
new file mode 100644
index 00000000000..07923b0c7a9
--- /dev/null
+++ b/drivers/char/drm/via_verifier.c
@@ -0,0 +1,1061 @@
+/*
+ * Copyright 2004 The Unichrome Project. All Rights Reserved.
+ * Copyright 2005 Thomas Hellstrom. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Thomas Hellstrom 2004, 2005.
+ * This code was written using docs obtained under NDA from VIA Inc.
+ *
+ * Don't run this code directly on an AGP buffer. Due to cache problems it will
+ * be very slow.
+ */
+
+
+#include "via_3d_reg.h"
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_verifier.h"
+#include "via_drv.h"
+
+typedef enum{
+ state_command,
+ state_header2,
+ state_header1,
+ state_vheader5,
+ state_vheader6,
+ state_error
+} verifier_state_t;
+
+
+typedef enum{
+ no_check = 0,
+ check_for_header2,
+ check_for_header1,
+ check_for_header2_err,
+ check_for_header1_err,
+ check_for_fire,
+ check_z_buffer_addr0,
+ check_z_buffer_addr1,
+ check_z_buffer_addr_mode,
+ check_destination_addr0,
+ check_destination_addr1,
+ check_destination_addr_mode,
+ check_for_dummy,
+ check_for_dd,
+ check_texture_addr0,
+ check_texture_addr1,
+ check_texture_addr2,
+ check_texture_addr3,
+ check_texture_addr4,
+ check_texture_addr5,
+ check_texture_addr6,
+ check_texture_addr7,
+ check_texture_addr8,
+ check_texture_addr_mode,
+ check_for_vertex_count,
+ check_number_texunits,
+ forbidden_command
+}hazard_t;
+
+/*
+ * Associates each hazard above with a possible multi-command
+ * sequence. For example an address that is split over multiple
+ * commands and that needs to be checked at the first command
+ * that does not include any part of the address.
+ */
+
+static drm_via_sequence_t seqs[] = {
+ no_sequence,
+ no_sequence,
+ no_sequence,
+ no_sequence,
+ no_sequence,
+ no_sequence,
+ z_address,
+ z_address,
+ z_address,
+ dest_address,
+ dest_address,
+ dest_address,
+ no_sequence,
+ no_sequence,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ tex_address,
+ no_sequence
+};
+
+typedef struct{
+ unsigned int code;
+ hazard_t hz;
+} hz_init_t;
+
+
+
+static hz_init_t init_table1[] = {
+ {0xf2, check_for_header2_err},
+ {0xf0, check_for_header1_err},
+ {0xee, check_for_fire},
+ {0xcc, check_for_dummy},
+ {0xdd, check_for_dd},
+ {0x00, no_check},
+ {0x10, check_z_buffer_addr0},
+ {0x11, check_z_buffer_addr1},
+ {0x12, check_z_buffer_addr_mode},
+ {0x13, no_check},
+ {0x14, no_check},
+ {0x15, no_check},
+ {0x23, no_check},
+ {0x24, no_check},
+ {0x33, no_check},
+ {0x34, no_check},
+ {0x35, no_check},
+ {0x36, no_check},
+ {0x37, no_check},
+ {0x38, no_check},
+ {0x39, no_check},
+ {0x3A, no_check},
+ {0x3B, no_check},
+ {0x3C, no_check},
+ {0x3D, no_check},
+ {0x3E, no_check},
+ {0x40, check_destination_addr0},
+ {0x41, check_destination_addr1},
+ {0x42, check_destination_addr_mode},
+ {0x43, no_check},
+ {0x44, no_check},
+ {0x50, no_check},
+ {0x51, no_check},
+ {0x52, no_check},
+ {0x53, no_check},
+ {0x54, no_check},
+ {0x55, no_check},
+ {0x56, no_check},
+ {0x57, no_check},
+ {0x58, no_check},
+ {0x70, no_check},
+ {0x71, no_check},
+ {0x78, no_check},
+ {0x79, no_check},
+ {0x7A, no_check},
+ {0x7B, no_check},
+ {0x7C, no_check},
+ {0x7D, check_for_vertex_count}
+};
+
+
+
+static hz_init_t init_table2[] = {
+ {0xf2, check_for_header2_err},
+ {0xf0, check_for_header1_err},
+ {0xee, check_for_fire},
+ {0xcc, check_for_dummy},
+ {0x00, check_texture_addr0},
+ {0x01, check_texture_addr0},
+ {0x02, check_texture_addr0},
+ {0x03, check_texture_addr0},
+ {0x04, check_texture_addr0},
+ {0x05, check_texture_addr0},
+ {0x06, check_texture_addr0},
+ {0x07, check_texture_addr0},
+ {0x08, check_texture_addr0},
+ {0x09, check_texture_addr0},
+ {0x20, check_texture_addr1},
+ {0x21, check_texture_addr1},
+ {0x22, check_texture_addr1},
+ {0x23, check_texture_addr4},
+ {0x2B, check_texture_addr3},
+ {0x2C, check_texture_addr3},
+ {0x2D, check_texture_addr3},
+ {0x2E, check_texture_addr3},
+ {0x2F, check_texture_addr3},
+ {0x30, check_texture_addr3},
+ {0x31, check_texture_addr3},
+ {0x32, check_texture_addr3},
+ {0x33, check_texture_addr3},
+ {0x34, check_texture_addr3},
+ {0x4B, check_texture_addr5},
+ {0x4C, check_texture_addr6},
+ {0x51, check_texture_addr7},
+ {0x52, check_texture_addr8},
+ {0x77, check_texture_addr2},
+ {0x78, no_check},
+ {0x79, no_check},
+ {0x7A, no_check},
+ {0x7B, check_texture_addr_mode},
+ {0x7C, no_check},
+ {0x7D, no_check},
+ {0x7E, no_check},
+ {0x7F, no_check},
+ {0x80, no_check},
+ {0x81, no_check},
+ {0x82, no_check},
+ {0x83, no_check},
+ {0x85, no_check},
+ {0x86, no_check},
+ {0x87, no_check},
+ {0x88, no_check},
+ {0x89, no_check},
+ {0x8A, no_check},
+ {0x90, no_check},
+ {0x91, no_check},
+ {0x92, no_check},
+ {0x93, no_check}
+};
+
+static hz_init_t init_table3[] = {
+ {0xf2, check_for_header2_err},
+ {0xf0, check_for_header1_err},
+ {0xcc, check_for_dummy},
+ {0x00, check_number_texunits}
+};
+
+
+static hazard_t table1[256];
+static hazard_t table2[256];
+static hazard_t table3[256];
+
+
+
+static __inline__ int
+eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
+{
+ if ((*buf - buf_end) >= num_words) {
+ *buf += num_words;
+ return 0;
+ }
+ DRM_ERROR("Illegal termination of DMA command buffer\n");
+ return 1;
+}
+
+
+/*
+ * Partially stolen from drm_memory.h
+ */
+
+static __inline__ drm_map_t *
+via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size,
+ drm_device_t *dev)
+{
+ struct list_head *list;
+ drm_map_list_t *r_list;
+ drm_map_t *map = seq->map_cache;
+
+ if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) {
+ return map;
+ }
+
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *) list;
+ map = r_list->map;
+ if (!map)
+ continue;
+ if (map->offset <= offset && (offset + size) <= (map->offset + map->size) &&
+ !(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) {
+ seq->map_cache = map;
+ return map;
+ }
+ }
+ return NULL;
+}
+
+
+/*
+ * Require that all AGP texture levels reside in the same AGP map which should
+ * be mappable by the client. This is not a big restriction.
+ * FIXME: To actually enforce this security policy strictly, drm_rmmap
+ * would have to wait for dma quiescent before removing an AGP map.
+ * The via_drm_lookup_agp_map call in reality seems to take
+ * very little CPU time.
+ */
+
+
+static __inline__ int
+finish_current_sequence(drm_via_state_t *cur_seq)
+{
+ switch(cur_seq->unfinished) {
+ case z_address:
+ DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
+ break;
+ case dest_address:
+ DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr);
+ break;
+ case tex_address:
+ if (cur_seq->agp_texture) {
+ unsigned start = cur_seq->tex_level_lo[cur_seq->texture];
+ unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
+ unsigned long lo=~0, hi=0, tmp;
+ uint32_t *addr, *pitch, *height, tex;
+ unsigned i;
+
+ if (end > 9) end = 9;
+ if (start > 9) start = 9;
+
+ addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]);
+ pitch = &(cur_seq->pitch[tex][start]);
+ height = &(cur_seq->height[tex][start]);
+
+ for (i=start; i<= end; ++i) {
+ tmp = *addr++;
+ if (tmp < lo) lo = tmp;
+ tmp += (*height++ << *pitch++);
+ if (tmp > hi) hi = tmp;
+ }
+
+ if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) {
+ DRM_ERROR("AGP texture is not in allowed map\n");
+ return 2;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ cur_seq->unfinished = no_sequence;
+ return 0;
+}
+
+static __inline__ int
+investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
+{
+ register uint32_t tmp, *tmp_addr;
+
+ if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
+ int ret;
+ if ((ret = finish_current_sequence(cur_seq))) return ret;
+ }
+
+ switch(hz) {
+ case check_for_header2:
+ if (cmd == HALCYON_HEADER2) return 1;
+ return 0;
+ case check_for_header1:
+ if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+ return 0;
+ case check_for_header2_err:
+ if (cmd == HALCYON_HEADER2) return 1;
+ DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
+ break;
+ case check_for_header1_err:
+ if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+ DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
+ break;
+ case check_for_fire:
+ if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1;
+ DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
+ break;
+ case check_for_dummy:
+ if (HC_DUMMY == cmd) return 0;
+ DRM_ERROR("Illegal DMA HC_DUMMY command\n");
+ break;
+ case check_for_dd:
+ if (0xdddddddd == cmd) return 0;
+ DRM_ERROR("Illegal DMA 0xdddddddd command\n");
+ break;
+ case check_z_buffer_addr0:
+ cur_seq->unfinished = z_address;
+ cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
+ (cmd & 0x00FFFFFF);
+ return 0;
+ case check_z_buffer_addr1:
+ cur_seq->unfinished = z_address;
+ cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
+ ((cmd & 0xFF) << 24);
+ return 0;
+ case check_z_buffer_addr_mode:
+ cur_seq->unfinished = z_address;
+ if ((cmd & 0x0000C000) == 0) return 0;
+ DRM_ERROR("Attempt to place Z buffer in system memory\n");
+ return 2;
+ case check_destination_addr0:
+ cur_seq->unfinished = dest_address;
+ cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
+ (cmd & 0x00FFFFFF);
+ return 0;
+ case check_destination_addr1:
+ cur_seq->unfinished = dest_address;
+ cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
+ ((cmd & 0xFF) << 24);
+ return 0;
+ case check_destination_addr_mode:
+ cur_seq->unfinished = dest_address;
+ if ((cmd & 0x0000C000) == 0) return 0;
+ DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n");
+ return 2;
+ case check_texture_addr0:
+ cur_seq->unfinished = tex_address;
+ tmp = (cmd >> 24);
+ tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
+ *tmp_addr = (*tmp_addr & 0xFF000000) | (cmd & 0x00FFFFFF);
+ return 0;
+ case check_texture_addr1:
+ cur_seq->unfinished = tex_address;
+ tmp = ((cmd >> 24) - 0x20);
+ tmp += tmp << 1;
+ tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
+ *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
+ tmp_addr++;
+ *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF00) << 16);
+ tmp_addr++;
+ *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF0000) << 8);
+ return 0;
+ case check_texture_addr2:
+ cur_seq->unfinished = tex_address;
+ cur_seq->tex_level_lo[tmp = cur_seq->texture] = cmd & 0x3F;
+ cur_seq->tex_level_hi[tmp] = (cmd & 0xFC0) >> 6;
+ return 0;
+ case check_texture_addr3:
+ cur_seq->unfinished = tex_address;
+ tmp = ((cmd >> 24) - 0x2B);
+ cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20;
+ if (!tmp && (cmd & 0x000FFFFF)) {
+ DRM_ERROR("Unimplemented texture level 0 pitch mode.\n");
+ return 2;
+ }
+ return 0;
+ case check_texture_addr4:
+ cur_seq->unfinished = tex_address;
+ tmp_addr = &cur_seq->t_addr[cur_seq->texture][9];
+ *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
+ return 0;
+ case check_texture_addr5:
+ case check_texture_addr6:
+ cur_seq->unfinished = tex_address;
+ /*
+ * Texture width. We don't care since we have the pitch.
+ */
+ return 0;
+ case check_texture_addr7:
+ cur_seq->unfinished = tex_address;
+ tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
+ tmp_addr[5] = 1 << ((cmd & 0x00F00000) >> 20);
+ tmp_addr[4] = 1 << ((cmd & 0x000F0000) >> 16);
+ tmp_addr[3] = 1 << ((cmd & 0x0000F000) >> 12);
+ tmp_addr[2] = 1 << ((cmd & 0x00000F00) >> 8);
+ tmp_addr[1] = 1 << ((cmd & 0x000000F0) >> 4);
+ tmp_addr[0] = 1 << (cmd & 0x0000000F);
+ return 0;
+ case check_texture_addr8:
+ cur_seq->unfinished = tex_address;
+ tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
+ tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
+ tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
+ tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
+ tmp_addr[6] = 1 << (cmd & 0x0000000F);
+ return 0;
+ case check_texture_addr_mode:
+ cur_seq->unfinished = tex_address;
+ if ( 2 == (tmp = cmd & 0x00000003)) {
+ DRM_ERROR("Attempt to fetch texture from system memory.\n");
+ return 2;
+ }
+ cur_seq->agp_texture = (tmp == 3);
+ cur_seq->tex_palette_size[cur_seq->texture] =
+ (cmd >> 16) & 0x000000007;
+ return 0;
+ case check_for_vertex_count:
+ cur_seq->vertex_count = cmd & 0x0000FFFF;
+ return 0;
+ case check_number_texunits:
+ cur_seq->multitex = (cmd >> 3) & 1;
+ return 0;
+ default:
+ DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
+ return 2;
+ }
+ return 2;
+}
+
+
+static __inline__ int
+via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
+ drm_via_state_t *cur_seq)
+{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private;
+ uint32_t a_fire, bcmd , dw_count;
+ int ret = 0;
+ int have_fire;
+ const uint32_t *buf = *buffer;
+
+ while(buf < buf_end) {
+ have_fire = 0;
+ if ((buf_end - buf) < 2) {
+ DRM_ERROR("Unexpected termination of primitive list.\n");
+ ret = 1;
+ break;
+ }
+ if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break;
+ bcmd = *buf++;
+ if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
+ DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
+ *buf);
+ ret = 1;
+ break;
+ }
+ a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;
+
+ /*
+ * How many dwords per vertex ?
+ */
+
+ if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
+ DRM_ERROR("Illegal B command vertex data for AGP.\n");
+ ret = 1;
+ break;
+ }
+
+ dw_count = 0;
+ if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1;
+ if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1;
+ if (bcmd & (1 << 9)) dw_count++;
+ if (bcmd & (1 << 10)) dw_count++;
+ if (bcmd & (1 << 11)) dw_count++;
+ if (bcmd & (1 << 12)) dw_count++;
+ if (bcmd & (1 << 13)) dw_count++;
+ if (bcmd & (1 << 14)) dw_count++;
+
+ while(buf < buf_end) {
+ if (*buf == a_fire) {
+ if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) {
+ DRM_ERROR("Fire offset buffer full.\n");
+ ret = 1;
+ break;
+ }
+ dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf;
+ have_fire = 1;
+ buf++;
+ if (buf < buf_end && *buf == a_fire)
+ buf++;
+ break;
+ }
+ if ((*buf == HALCYON_HEADER2) ||
+ ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
+ DRM_ERROR("Missing Vertex Fire command, "
+ "Stray Vertex Fire command or verifier "
+ "lost sync.\n");
+ ret = 1;
+ break;
+ }
+ if ((ret = eat_words(&buf, buf_end, dw_count)))
+ break;
+ }
+ if (buf >= buf_end && !have_fire) {
+ DRM_ERROR("Missing Vertex Fire command or verifier "
+ "lost sync.\n");
+ ret = 1;
+ break;
+ }
+ if (cur_seq->agp && ((buf - cur_seq->buf_start) & 0x01)) {
+ DRM_ERROR("AGP Primitive list end misaligned.\n");
+ ret = 1;
+ break;
+ }
+ }
+ *buffer = buf;
+ return ret;
+}
+
+
+
+
+
+static __inline__ verifier_state_t
+via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
+ drm_via_state_t *hc_state)
+{
+ uint32_t cmd;
+ int hz_mode;
+ hazard_t hz;
+ const uint32_t *buf = *buffer;
+ const hazard_t *hz_table;
+
+
+ if ((buf_end - buf) < 2) {
+ DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
+ return state_error;
+ }
+ buf++;
+ cmd = (*buf++ & 0xFFFF0000) >> 16;
+
+ switch(cmd) {
+ case HC_ParaType_CmdVdata:
+ if (via_check_prim_list(&buf, buf_end, hc_state ))
+ return state_error;
+ *buffer = buf;
+ return state_command;
+ case HC_ParaType_NotTex:
+ hz_table = table1;
+ break;
+ case HC_ParaType_Tex:
+ hc_state->texture = 0;
+ hz_table = table2;
+ break;
+ case (HC_ParaType_Tex | (HC_SubType_Tex1 << 8)):
+ hc_state->texture = 1;
+ hz_table = table2;
+ break;
+ case (HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)):
+ hz_table = table3;
+ break;
+ case HC_ParaType_Auto:
+ if (eat_words(&buf, buf_end, 2))
+ return state_error;
+ *buffer = buf;
+ return state_command;
+ case (HC_ParaType_Palette | (HC_SubType_Stipple << 8)):
+ if (eat_words(&buf, buf_end, 32))
+ return state_error;
+ *buffer = buf;
+ return state_command;
+ case (HC_ParaType_Palette | (HC_SubType_TexPalette0 << 8)):
+ case (HC_ParaType_Palette | (HC_SubType_TexPalette1 << 8)):
+ DRM_ERROR("Texture palettes are rejected because of "
+ "lack of info how to determine their size.\n");
+ return state_error;
+ case (HC_ParaType_Palette | (HC_SubType_FogTable << 8)):
+ DRM_ERROR("Fog factor palettes are rejected because of "
+ "lack of info how to determine their size.\n");
+ return state_error;
+ default:
+
+ /*
+ * There are some unimplemented HC_ParaTypes here, that
+ * need to be implemented if the Mesa driver is extended.
+ */
+
+ DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
+ "DMA subcommand: 0x%x. Previous dword: 0x%x\n",
+ cmd, *(buf -2));
+ *buffer = buf;
+ return state_error;
+ }
+
+ while(buf < buf_end) {
+ cmd = *buf++;
+ if ((hz = hz_table[cmd >> 24])) {
+ if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
+ if (hz_mode == 1) {
+ buf--;
+ break;
+ }
+ return state_error;
+ }
+ } else if (hc_state->unfinished &&
+ finish_current_sequence(hc_state)) {
+ return state_error;
+ }
+ }
+ if (hc_state->unfinished && finish_current_sequence(hc_state)) {
+ return state_error;
+ }
+ *buffer = buf;
+ return state_command;
+}
+
+static __inline__ verifier_state_t
+via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end,
+ int *fire_count)
+{
+ uint32_t cmd;
+ const uint32_t *buf = *buffer;
+ const uint32_t *next_fire;
+ int burst = 0;
+
+ next_fire = dev_priv->fire_offsets[*fire_count];
+ buf++;
+ cmd = (*buf & 0xFFFF0000) >> 16;
+ VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
+ switch(cmd) {
+ case HC_ParaType_CmdVdata:
+ while ((buf < buf_end) &&
+ (*fire_count < dev_priv->num_fire_offsets) &&
+ (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) {
+ while(buf <= next_fire) {
+ VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+ burst += 4;
+ }
+ if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
+ buf++;
+
+ if (++(*fire_count) < dev_priv->num_fire_offsets)
+ next_fire = dev_priv->fire_offsets[*fire_count];
+ }
+ break;
+ default:
+ while(buf < buf_end) {
+
+ if ( *buf == HC_HEADER2 ||
+ (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
+ (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
+ (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break;
+
+ VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+ burst +=4;
+ }
+ }
+ *buffer = buf;
+ return state_command;
+}
+
+
+
+static __inline__ int
+verify_mmio_address( uint32_t address)
+{
+ if ((address > 0x3FF) && (address < 0xC00 )) {
+ DRM_ERROR("Invalid VIDEO DMA command. "
+ "Attempt to access 3D- or command burst area.\n");
+ return 1;
+ } else if ((address > 0xCFF) && (address < 0x1300)) {
+ DRM_ERROR("Invalid VIDEO DMA command. "
+ "Attempt to access PCI DMA area.\n");
+ return 1;
+ } else if (address > 0x13FF ) {
+ DRM_ERROR("Invalid VIDEO DMA command. "
+ "Attempt to access VGA registers.\n");
+ return 1;
+ }
+ return 0;
+}
+
+static __inline__ int
+verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords)
+{
+ const uint32_t *buf = *buffer;
+
+ if (buf_end - buf < dwords) {
+ DRM_ERROR("Illegal termination of video command.\n");
+ return 1;
+ }
+ while (dwords--) {
+ if (*buf++) {
+ DRM_ERROR("Illegal video command tail.\n");
+ return 1;
+ }
+ }
+ *buffer = buf;
+ return 0;
+}
+
+
+static __inline__ verifier_state_t
+via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
+{
+ uint32_t cmd;
+ const uint32_t *buf = *buffer;
+ verifier_state_t ret = state_command;
+
+ while (buf < buf_end) {
+ cmd = *buf;
+ if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
+ (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ break;
+ DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+ "Attempt to access 3D- or command burst area.\n");
+ ret = state_error;
+ break;
+ } else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
+ break;
+ DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+ "Attempt to access VGA registers.\n");
+ ret = state_error;
+ break;
+ } else {
+ buf += 2;
+ }
+ }
+ *buffer = buf;
+ return ret;
+}
+
+static __inline__ verifier_state_t
+via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+ register uint32_t cmd;
+ const uint32_t *buf = *buffer;
+
+ while (buf < buf_end) {
+ cmd = *buf;
+ if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break;
+ VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
+ buf++;
+ }
+ *buffer = buf;
+ return state_command;
+}
+
+static __inline__ verifier_state_t
+via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
+{
+ uint32_t data;
+ const uint32_t *buf = *buffer;
+
+ if (buf_end - buf < 4) {
+ DRM_ERROR("Illegal termination of video header5 command\n");
+ return state_error;
+ }
+
+ data = *buf++ & ~VIA_VIDEOMASK;
+ if (verify_mmio_address(data))
+ return state_error;
+
+ data = *buf++;
+ if (*buf++ != 0x00F50000) {
+ DRM_ERROR("Illegal header5 header data\n");
+ return state_error;
+ }
+ if (*buf++ != 0x00000000) {
+ DRM_ERROR("Illegal header5 header data\n");
+ return state_error;
+ }
+ if (eat_words(&buf, buf_end, data))
+ return state_error;
+ if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
+ return state_error;
+ *buffer = buf;
+ return state_command;
+
+}
+
+static __inline__ verifier_state_t
+via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+ uint32_t addr, count, i;
+ const uint32_t *buf = *buffer;
+
+ addr = *buf++ & ~VIA_VIDEOMASK;
+ i = count = *buf;
+ buf += 3;
+ while(i--) {
+ VIA_WRITE(addr, *buf++);
+ }
+ if (count & 3) buf += 4 - (count & 3);
+ *buffer = buf;
+ return state_command;
+}
+
+
+static __inline__ verifier_state_t
+via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
+{
+ uint32_t data;
+ const uint32_t *buf = *buffer;
+ uint32_t i;
+
+
+ if (buf_end - buf < 4) {
+ DRM_ERROR("Illegal termination of video header6 command\n");
+ return state_error;
+ }
+ buf++;
+ data = *buf++;
+ if (*buf++ != 0x00F60000) {
+ DRM_ERROR("Illegal header6 header data\n");
+ return state_error;
+ }
+ if (*buf++ != 0x00000000) {
+ DRM_ERROR("Illegal header6 header data\n");
+ return state_error;
+ }
+ if ((buf_end - buf) < (data << 1)) {
+ DRM_ERROR("Illegal termination of video header6 command\n");
+ return state_error;
+ }
+ for (i=0; i<data; ++i) {
+ if (verify_mmio_address(*buf++))
+ return state_error;
+ buf++;
+ }
+ data <<= 1;
+ if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
+ return state_error;
+ *buffer = buf;
+ return state_command;
+}
+
+static __inline__ verifier_state_t
+via_parse_vheader6( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+
+ uint32_t addr, count, i;
+ const uint32_t *buf = *buffer;
+
+ i = count = *++buf;
+ buf += 3;
+ while(i--) {
+ addr = *buf++;
+ VIA_WRITE(addr, *buf++);
+ }
+ count <<= 1;
+ if (count & 3) buf += 4 - (count & 3);
+ *buffer = buf;
+ return state_command;
+}
+
+
+
+int
+via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
+ int agp)
+{
+
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_state_t *hc_state = &dev_priv->hc_state;
+ drm_via_state_t saved_state = *hc_state;
+ uint32_t cmd;
+ const uint32_t *buf_end = buf + ( size >> 2 );
+ verifier_state_t state = state_command;
+ int pro_group_a = dev_priv->pro_group_a;
+
+ hc_state->dev = dev;
+ hc_state->unfinished = no_sequence;
+ hc_state->map_cache = NULL;
+ hc_state->agp = agp;
+ hc_state->buf_start = buf;
+ dev_priv->num_fire_offsets = 0;
+
+ while (buf < buf_end) {
+
+ switch (state) {
+ case state_header2:
+ state = via_check_header2( &buf, buf_end, hc_state );
+ break;
+ case state_header1:
+ state = via_check_header1( &buf, buf_end );
+ break;
+ case state_vheader5:
+ state = via_check_vheader5( &buf, buf_end );
+ break;
+ case state_vheader6:
+ state = via_check_vheader6( &buf, buf_end );
+ break;
+ case state_command:
+ if (HALCYON_HEADER2 == (cmd = *buf))
+ state = state_header2;
+ else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ state = state_header1;
+ else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+ state = state_vheader5;
+ else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ state = state_vheader6;
+ else {
+ DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+ cmd);
+ state = state_error;
+ }
+ break;
+ case state_error:
+ default:
+ *hc_state = saved_state;
+ return DRM_ERR(EINVAL);
+ }
+ }
+ if (state == state_error) {
+ *hc_state = saved_state;
+ return DRM_ERR(EINVAL);
+ }
+ return 0;
+}
+
+int
+via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size)
+{
+
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ uint32_t cmd;
+ const uint32_t *buf_end = buf + ( size >> 2 );
+ verifier_state_t state = state_command;
+ int fire_count = 0;
+
+ while (buf < buf_end) {
+
+ switch (state) {
+ case state_header2:
+ state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count );
+ break;
+ case state_header1:
+ state = via_parse_header1( dev_priv, &buf, buf_end );
+ break;
+ case state_vheader5:
+ state = via_parse_vheader5( dev_priv, &buf, buf_end );
+ break;
+ case state_vheader6:
+ state = via_parse_vheader6( dev_priv, &buf, buf_end );
+ break;
+ case state_command:
+ if (HALCYON_HEADER2 == (cmd = *buf))
+ state = state_header2;
+ else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
+ state = state_header1;
+ else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+ state = state_vheader5;
+ else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+ state = state_vheader6;
+ else {
+ DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+ cmd);
+ state = state_error;
+ }
+ break;
+ case state_error:
+ default:
+ return DRM_ERR(EINVAL);
+ }
+ }
+ if (state == state_error) {
+ return DRM_ERR(EINVAL);
+ }
+ return 0;
+}
+
+
+
+static void
+setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
+{
+ int i;
+
+ for(i=0; i<256; ++i) {
+ table[i] = forbidden_command;
+ }
+
+ for(i=0; i<size; ++i) {
+ table[init_table[i].code] = init_table[i].hz;
+ }
+}
+
+void
+via_init_command_verifier( void )
+{
+ setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
+ setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
+ setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
+}
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
new file mode 100644
index 00000000000..a8e13592620
--- /dev/null
+++ b/drivers/char/drm/via_verifier.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004 The Unichrome Project. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE UNICHROME PROJECT, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Thomas Hellström 2004.
+ */
+
+#ifndef _VIA_VERIFIER_H_
+#define _VIA_VERIFIER_H_
+
+typedef enum{
+ no_sequence = 0,
+ z_address,
+ dest_address,
+ tex_address
+}drm_via_sequence_t;
+
+
+
+typedef struct{
+ unsigned texture;
+ uint32_t z_addr;
+ uint32_t d_addr;
+ uint32_t t_addr[2][10];
+ uint32_t pitch[2][10];
+ uint32_t height[2][10];
+ uint32_t tex_level_lo[2];
+ uint32_t tex_level_hi[2];
+ uint32_t tex_palette_size[2];
+ drm_via_sequence_t unfinished;
+ int agp_texture;
+ int multitex;
+ drm_device_t *dev;
+ drm_map_t *map_cache;
+ uint32_t vertex_count;
+ int agp;
+ const uint32_t *buf_start;
+} drm_via_state_t;
+
+extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
+ drm_device_t *dev, int agp);
+
+#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
new file mode 100644
index 00000000000..37a61c67b29
--- /dev/null
+++ b/drivers/char/drm/via_video.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2005 Thomas Hellstrom. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Thomas Hellstrom 2005.
+ *
+ * Video and XvMC related functions.
+ */
+
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+void
+via_init_futex(drm_via_private_t *dev_priv)
+{
+ unsigned int i;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+ DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
+ XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
+ }
+}
+
+void
+via_cleanup_futex(drm_via_private_t *dev_priv)
+{
+}
+
+void
+via_release_futex(drm_via_private_t *dev_priv, int context)
+{
+ unsigned int i;
+ volatile int *lock;
+
+ for (i=0; i < VIA_NR_XVMC_LOCKS; ++i) {
+ lock = (int *) XVMCLOCKPTR(dev_priv->sarea_priv, i);
+ if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) {
+ if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) {
+ DRM_WAKEUP( &(dev_priv->decoder_queue[i]));
+ }
+ *lock = 0;
+ }
+ }
+}
+
+int
+via_decoder_futex(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_via_futex_t fx;
+ volatile int *lock;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
+ int ret = 0;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t *) data, sizeof(fx));
+
+ if (fx.lock > VIA_NR_XVMC_LOCKS)
+ return -EFAULT;
+
+ lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock);
+
+ switch (fx.func) {
+ case VIA_FUTEX_WAIT:
+ DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock],
+ (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val);
+ return ret;
+ case VIA_FUTEX_WAKE:
+ DRM_WAKEUP(&(dev_priv->decoder_queue[fx.lock]));
+ return 0;
+ }
+ return 0;
+}
+
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 88cd858f74d..cddb789902d 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -22,6 +22,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/config.h>
#include <linux/console.h>
#include <linux/cpumask.h>
#include <linux/init.h>
@@ -40,7 +41,6 @@
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/hvconsole.h>
-#include <asm/vio.h>
#define HVC_MAJOR 229
#define HVC_MINOR 0
@@ -61,16 +61,21 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8
-static struct tty_driver *hvc_driver;
-#ifdef CONFIG_MAGIC_SYSRQ
-static int sysrq_pressed;
-#endif
-
#define N_OUTBUF 16
#define N_INBUF 16
#define __ALIGNED__ __attribute__((__aligned__(8)))
+static struct tty_driver *hvc_driver;
+static struct task_struct *hvc_task;
+
+/* Picks up late kicks after list walk but before schedule() */
+static int hvc_kicked;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static int sysrq_pressed;
+#endif
+
struct hvc_struct {
spinlock_t lock;
int index;
@@ -80,11 +85,11 @@ struct hvc_struct {
char outbuf[N_OUTBUF] __ALIGNED__;
int n_outbuf;
uint32_t vtermno;
+ struct hv_ops *ops;
int irq_requested;
int irq;
struct list_head next;
struct kobject kobj; /* ref count & hvc_struct lifetime */
- struct vio_dev *vdev;
};
/* dynamic list of hvc_struct instances */
@@ -97,26 +102,185 @@ static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);
static DEFINE_SPINLOCK(hvc_structs_lock);
/*
+ * This value is used to assign a tty->index value to a hvc_struct based
+ * upon order of exposure via hvc_probe(), when we can not match it to
+ * a console canidate registered with hvc_instantiate().
+ */
+static int last_hvc = -1;
+
+/*
+ * Do not call this function with either the hvc_strucst_lock or the hvc_struct
+ * lock held. If successful, this function increments the kobject reference
+ * count against the target hvc_struct so it should be released when finished.
+ */
+struct hvc_struct *hvc_get_by_index(int index)
+{
+ struct hvc_struct *hp;
+ unsigned long flags;
+
+ spin_lock(&hvc_structs_lock);
+
+ list_for_each_entry(hp, &hvc_structs, next) {
+ spin_lock_irqsave(&hp->lock, flags);
+ if (hp->index == index) {
+ kobject_get(&hp->kobj);
+ spin_unlock_irqrestore(&hp->lock, flags);
+ spin_unlock(&hvc_structs_lock);
+ return hp;
+ }
+ spin_unlock_irqrestore(&hp->lock, flags);
+ }
+ hp = NULL;
+
+ spin_unlock(&hvc_structs_lock);
+ return hp;
+}
+
+
+/*
* Initial console vtermnos for console API usage prior to full console
* initialization. Any vty adapter outside this range will not have usable
* console interfaces but can still be used as a tty device. This has to be
* static because kmalloc will not work during early console init.
*/
-static uint32_t vtermnos[MAX_NR_HVC_CONSOLES];
+static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
+static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
+ {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
-/* Used for accounting purposes */
-static int num_vterms = 0;
+/*
+ * Console APIs, NOT TTY. These APIs are available immediately when
+ * hvc_console_setup() finds adapters.
+ */
-static struct task_struct *hvc_task;
+void hvc_console_print(struct console *co, const char *b, unsigned count)
+{
+ char c[16] __ALIGNED__;
+ unsigned i = 0, n = 0;
+ int r, donecr = 0, index = co->index;
+
+ /* Console access attempt outside of acceptable console range. */
+ if (index >= MAX_NR_HVC_CONSOLES)
+ return;
+
+ /* This console adapter was removed so it is not useable. */
+ if (vtermnos[index] < 0)
+ return;
+
+ while (count > 0 || i > 0) {
+ if (count > 0 && i < sizeof(c)) {
+ if (b[n] == '\n' && !donecr) {
+ c[i++] = '\r';
+ donecr = 1;
+ } else {
+ c[i++] = b[n++];
+ donecr = 0;
+ --count;
+ }
+ } else {
+ r = cons_ops[index]->put_chars(vtermnos[index], c, i);
+ if (r < 0) {
+ /* throw away chars on error */
+ i = 0;
+ } else if (r > 0) {
+ i -= r;
+ if (i > 0)
+ memmove(c, c+r, i);
+ }
+ }
+ }
+}
+
+static struct tty_driver *hvc_console_device(struct console *c, int *index)
+{
+ if (vtermnos[c->index] == -1)
+ return NULL;
+
+ *index = c->index;
+ return hvc_driver;
+}
+
+static int __init hvc_console_setup(struct console *co, char *options)
+{
+ if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
+ return -ENODEV;
+
+ if (vtermnos[co->index] == -1)
+ return -ENODEV;
+
+ return 0;
+}
+
+struct console hvc_con_driver = {
+ .name = "hvc",
+ .write = hvc_console_print,
+ .device = hvc_console_device,
+ .setup = hvc_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
/*
- * This value is used to associate a tty->index value to a hvc_struct based
- * upon order of exposure via hvc_probe().
+ * Early console initialization. Preceeds driver initialization.
+ *
+ * (1) we are first, and the user specified another driver
+ * -- index will remain -1
+ * (2) we are first and the user specified no driver
+ * -- index will be set to 0, then we will fail setup.
+ * (3) we are first and the user specified our driver
+ * -- index will be set to user specified driver, and we will fail
+ * (4) we are after driver, and this initcall will register us
+ * -- if the user didn't specify a driver then the console will match
+ *
+ * Note that for cases 2 and 3, we will match later when the io driver
+ * calls hvc_instantiate() and call register again.
*/
-static int hvc_count = -1;
+static int __init hvc_console_init(void)
+{
+ register_console(&hvc_con_driver);
+ return 0;
+}
+console_initcall(hvc_console_init);
-/* Picks up late kicks after list walk but before schedule() */
-static int hvc_kicked;
+/*
+ * hvc_instantiate() is an early console discovery method which locates
+ * consoles * prior to the vio subsystem discovering them. Hotplugged
+ * vty adapters do NOT get an hvc_instantiate() callback since they
+ * appear after early console init.
+ */
+int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
+{
+ struct hvc_struct *hp;
+
+ if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
+ return -1;
+
+ if (vtermnos[index] != -1)
+ return -1;
+
+ /* make sure no no tty has been registerd in this index */
+ hp = hvc_get_by_index(index);
+ if (hp) {
+ kobject_put(&hp->kobj);
+ return -1;
+ }
+
+ vtermnos[index] = vtermno;
+ cons_ops[index] = ops;
+
+ /* reserve all indices upto and including this index */
+ if (last_hvc < index)
+ last_hvc = index;
+
+ /* if this index is what the user requested, then register
+ * now (setup won't fail at this point). It's ok to just
+ * call register again if previously .setup failed.
+ */
+ if (index == hvc_con_driver.index)
+ register_console(&hvc_con_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL(hvc_instantiate);
/* Wake the sleeping khvcd */
static void hvc_kick(void)
@@ -125,13 +289,17 @@ static void hvc_kick(void)
wake_up_process(hvc_task);
}
+static int hvc_poll(struct hvc_struct *hp);
+
/*
* NOTE: This API isn't used if the console adapter doesn't support interrupts.
* In this case the console is poll driven.
*/
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
- hvc_kick();
+ /* if hvc_poll request a repoll, then kick the hvcd thread */
+ if (hvc_poll(dev_instance))
+ hvc_kick();
return IRQ_HANDLED;
}
@@ -141,34 +309,6 @@ static void hvc_unthrottle(struct tty_struct *tty)
}
/*
- * Do not call this function with either the hvc_strucst_lock or the hvc_struct
- * lock held. If successful, this function increments the kobject reference
- * count against the target hvc_struct so it should be released when finished.
- */
-struct hvc_struct *hvc_get_by_index(int index)
-{
- struct hvc_struct *hp;
- unsigned long flags;
-
- spin_lock(&hvc_structs_lock);
-
- list_for_each_entry(hp, &hvc_structs, next) {
- spin_lock_irqsave(&hp->lock, flags);
- if (hp->index == index) {
- kobject_get(&hp->kobj);
- spin_unlock_irqrestore(&hp->lock, flags);
- spin_unlock(&hvc_structs_lock);
- return hp;
- }
- spin_unlock_irqrestore(&hp->lock, flags);
- }
- hp = NULL;
-
- spin_unlock(&hvc_structs_lock);
- return hp;
-}
-
-/*
* The TTY interface won't be used until after the vio layer has exposed the vty
* adapter to the kernel.
*/
@@ -329,7 +469,7 @@ static void hvc_push(struct hvc_struct *hp)
{
int n;
- n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
+ n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
if (n <= 0) {
if (n == 0)
return;
@@ -467,7 +607,7 @@ static int hvc_poll(struct hvc_struct *hp)
break;
}
- n = hvc_get_chars(hp->vtermno, buf, count);
+ n = hp->ops->get_chars(hp->vtermno, buf, count);
if (n <= 0) {
/* Hangup the tty when disconnected from host */
if (n == -EPIPE) {
@@ -479,14 +619,17 @@ static int hvc_poll(struct hvc_struct *hp)
}
for (i = 0; i < n; ++i) {
#ifdef CONFIG_MAGIC_SYSRQ
- /* Handle the SysRq Hack */
- if (buf[i] == '\x0f') { /* ^O -- should support a sequence */
- sysrq_pressed = 1;
- continue;
- } else if (sysrq_pressed) {
- handle_sysrq(buf[i], NULL, tty);
- sysrq_pressed = 0;
- continue;
+ if (hp->index == hvc_con_driver.index) {
+ /* Handle the SysRq Hack */
+ /* XXX should support a sequence */
+ if (buf[i] == '\x0f') { /* ^O */
+ sysrq_pressed = 1;
+ continue;
+ } else if (sysrq_pressed) {
+ handle_sysrq(buf[i], NULL, tty);
+ sysrq_pressed = 0;
+ continue;
+ }
}
#endif /* CONFIG_MAGIC_SYSRQ */
tty_insert_flip_char(tty, buf[i], 0);
@@ -497,8 +640,8 @@ static int hvc_poll(struct hvc_struct *hp)
/*
* Account for the total amount read in one loop, and if above
- * 64 bytes, we do a quick schedule loop to let the tty grok the
- * data and eventually throttle us.
+ * 64 bytes, we do a quick schedule loop to let the tty grok
+ * the data and eventually throttle us.
*/
read_total += n;
if (read_total >= 64) {
@@ -542,7 +685,6 @@ int khvcd(void *unused)
if (cpus_empty(cpus_in_xmon)) {
spin_lock(&hvc_structs_lock);
list_for_each_entry(hp, &hvc_structs, next) {
- /*hp = list_entry(node, struct hvc_struct, * next); */
poll_mask |= hvc_poll(hp);
}
spin_unlock(&hvc_structs_lock);
@@ -577,14 +719,6 @@ static struct tty_operations hvc_ops = {
.chars_in_buffer = hvc_chars_in_buffer,
};
-char hvc_driver_name[] = "hvc_console";
-
-static struct vio_device_id hvc_driver_table[] __devinitdata= {
- {"serial", "hvterm1"},
- { NULL, }
-};
-MODULE_DEVICE_TABLE(vio, hvc_driver_table);
-
/* callback when the kboject ref count reaches zero. */
static void destroy_hvc_struct(struct kobject *kobj)
{
@@ -606,41 +740,51 @@ static struct kobj_type hvc_kobj_type = {
.release = destroy_hvc_struct,
};
-static int __devinit hvc_probe(
- struct vio_dev *dev,
- const struct vio_device_id *id)
+struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
+ struct hv_ops *ops)
{
struct hvc_struct *hp;
-
- /* probed with invalid parameters. */
- if (!dev || !id)
- return -EPERM;
+ int i;
hp = kmalloc(sizeof(*hp), GFP_KERNEL);
if (!hp)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
memset(hp, 0x00, sizeof(*hp));
- hp->vtermno = dev->unit_address;
- hp->vdev = dev;
- hp->vdev->dev.driver_data = hp;
- hp->irq = dev->irq;
+
+ hp->vtermno = vtermno;
+ hp->irq = irq;
+ hp->ops = ops;
kobject_init(&hp->kobj);
hp->kobj.ktype = &hvc_kobj_type;
spin_lock_init(&hp->lock);
spin_lock(&hvc_structs_lock);
- hp->index = ++hvc_count;
+
+ /*
+ * find index to use:
+ * see if this vterm id matches one registered for console.
+ */
+ for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
+ if (vtermnos[i] == hp->vtermno)
+ break;
+
+ /* no matching slot, just use a counter */
+ if (i >= MAX_NR_HVC_CONSOLES)
+ i = ++last_hvc;
+
+ hp->index = i;
+
list_add_tail(&(hp->next), &hvc_structs);
spin_unlock(&hvc_structs_lock);
- return 0;
+ return hp;
}
+EXPORT_SYMBOL(hvc_alloc);
-static int __devexit hvc_remove(struct vio_dev *dev)
+int __devexit hvc_remove(struct hvc_struct *hp)
{
- struct hvc_struct *hp = dev->dev.driver_data;
unsigned long flags;
struct kobject *kobjp;
struct tty_struct *tty;
@@ -673,23 +817,14 @@ static int __devexit hvc_remove(struct vio_dev *dev)
tty_hangup(tty);
return 0;
}
-
-static struct vio_driver hvc_vio_driver = {
- .name = hvc_driver_name,
- .id_table = hvc_driver_table,
- .probe = hvc_probe,
- .remove = hvc_remove,
-};
+EXPORT_SYMBOL(hvc_remove);
/* Driver initialization. Follow console initialization. This is where the TTY
* interfaces start to become available. */
int __init hvc_init(void)
{
- int rc;
-
- /* We need more than num_vterms adapters due to hotplug additions. */
+ /* We need more than hvc_count adapters due to hotplug additions. */
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
- /* hvc_driver = alloc_tty_driver(num_vterms); */
if (!hvc_driver)
return -ENOMEM;
@@ -716,116 +851,20 @@ int __init hvc_init(void)
return -EIO;
}
- /* Register as a vio device to receive callbacks */
- rc = vio_register_driver(&hvc_vio_driver);
-
- return rc;
+ return 0;
}
+module_init(hvc_init);
-/* This isn't particularily necessary due to this being a console driver but it
- * is nice to be thorough */
+/* This isn't particularily necessary due to this being a console driver
+ * but it is nice to be thorough.
+ */
static void __exit hvc_exit(void)
{
kthread_stop(hvc_task);
- vio_unregister_driver(&hvc_vio_driver);
tty_unregister_driver(hvc_driver);
/* return tty_struct instances allocated in hvc_init(). */
put_tty_driver(hvc_driver);
+ unregister_console(&hvc_con_driver);
}
-
-/*
- * Console APIs, NOT TTY. These APIs are available immediately when
- * hvc_console_setup() finds adapters.
- */
-
-/*
- * hvc_instantiate() is an early console discovery method which locates consoles
- * prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT
- * get an hvc_instantiate() callback since the appear after early console init.
- */
-int hvc_instantiate(uint32_t vtermno, int index)
-{
- if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
- return -1;
-
- if (vtermnos[index] != -1)
- return -1;
-
- vtermnos[index] = vtermno;
- return 0;
-}
-
-void hvc_console_print(struct console *co, const char *b, unsigned count)
-{
- char c[16] __ALIGNED__;
- unsigned i = 0, n = 0;
- int r, donecr = 0;
-
- /* Console access attempt outside of acceptable console range. */
- if (co->index >= MAX_NR_HVC_CONSOLES)
- return;
-
- /* This console adapter was removed so it is not useable. */
- if (vtermnos[co->index] < 0)
- return;
-
- while (count > 0 || i > 0) {
- if (count > 0 && i < sizeof(c)) {
- if (b[n] == '\n' && !donecr) {
- c[i++] = '\r';
- donecr = 1;
- } else {
- c[i++] = b[n++];
- donecr = 0;
- --count;
- }
- } else {
- r = hvc_put_chars(vtermnos[co->index], c, i);
- if (r < 0) {
- /* throw away chars on error */
- i = 0;
- } else if (r > 0) {
- i -= r;
- if (i > 0)
- memmove(c, c+r, i);
- }
- }
- }
-}
-
-static struct tty_driver *hvc_console_device(struct console *c, int *index)
-{
- *index = c->index;
- return hvc_driver;
-}
-
-static int __init hvc_console_setup(struct console *co, char *options)
-{
- return 0;
-}
-
-struct console hvc_con_driver = {
- .name = "hvc",
- .write = hvc_console_print,
- .device = hvc_console_device,
- .setup = hvc_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-/* Early console initialization. Preceeds driver initialization. */
-static int __init hvc_console_init(void)
-{
- int i;
-
- for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
- vtermnos[i] = -1;
- num_vterms = hvc_find_vtys();
- register_console(&hvc_con_driver);
- return 0;
-}
-console_initcall(hvc_console_init);
-
-module_init(hvc_init);
module_exit(hvc_exit);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
new file mode 100644
index 00000000000..60bb9152b83
--- /dev/null
+++ b/drivers/char/hvc_vio.c
@@ -0,0 +1,152 @@
+/*
+ * vio driver interface to hvc_console.c
+ *
+ * This code was moved here to allow the remaing code to be reused as a
+ * generic polling mode with semi-reliable transport driver core to the
+ * console and tty subsystems.
+ *
+ *
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
+ * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Additional Author(s):
+ * Ryan S. Arnold <rsa@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <asm/hvconsole.h>
+#include <asm/vio.h>
+#include <asm/prom.h>
+
+char hvc_driver_name[] = "hvc_console";
+
+static struct vio_device_id hvc_driver_table[] __devinitdata = {
+ {"serial", "hvterm1"},
+ { NULL, }
+};
+MODULE_DEVICE_TABLE(vio, hvc_driver_table);
+
+static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
+{
+ unsigned long got;
+ int i;
+
+ got = hvc_get_chars(vtermno, buf, count);
+
+ /*
+ * Work around a HV bug where it gives us a null
+ * after every \r. -- paulus
+ */
+ for (i = 1; i < got; ++i) {
+ if (buf[i] == 0 && buf[i-1] == '\r') {
+ --got;
+ if (i < got)
+ memmove(&buf[i], &buf[i+1],
+ got - i);
+ }
+ }
+ return got;
+}
+
+static struct hv_ops hvc_get_put_ops = {
+ .get_chars = filtered_get_chars,
+ .put_chars = hvc_put_chars,
+};
+
+static int __devinit hvc_vio_probe(struct vio_dev *vdev,
+ const struct vio_device_id *id)
+{
+ struct hvc_struct *hp;
+
+ /* probed with invalid parameters. */
+ if (!vdev || !id)
+ return -EPERM;
+
+ hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops);
+ if (IS_ERR(hp))
+ return PTR_ERR(hp);
+ dev_set_drvdata(&vdev->dev, hp);
+
+ return 0;
+}
+
+static int __devexit hvc_vio_remove(struct vio_dev *vdev)
+{
+ struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
+
+ return hvc_remove(hp);
+}
+
+static struct vio_driver hvc_vio_driver = {
+ .name = hvc_driver_name,
+ .id_table = hvc_driver_table,
+ .probe = hvc_vio_probe,
+ .remove = hvc_vio_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ }
+};
+
+static int hvc_vio_init(void)
+{
+ int rc;
+
+ /* Register as a vio device to receive callbacks */
+ rc = vio_register_driver(&hvc_vio_driver);
+
+ return rc;
+}
+module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
+
+static void hvc_vio_exit(void)
+{
+ vio_unregister_driver(&hvc_vio_driver);
+}
+module_exit(hvc_vio_exit);
+
+/* the device tree order defines our numbering */
+static int hvc_find_vtys(void)
+{
+ struct device_node *vty;
+ int num_found = 0;
+
+ for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
+ vty = of_find_node_by_name(vty, "vty")) {
+ uint32_t *vtermno;
+
+ /* We have statically defined space for only a certain number
+ * of console adapters.
+ */
+ if (num_found >= MAX_NR_HVC_CONSOLES)
+ break;
+
+ vtermno = (uint32_t *)get_property(vty, "reg", NULL);
+ if (!vtermno)
+ continue;
+
+ if (device_is_compatible(vty, "hvterm1")) {
+ hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
+ ++num_found;
+ }
+ }
+
+ return num_found;
+}
+console_initcall(hvc_find_vtys);
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index f1f1192ba2b..a22aa940e01 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -291,15 +291,13 @@ static void dump_packet(uint8_t *packet)
dump_hex(packet, header->len);
}
-/* can't use hvc_get_chars because that strips CRs */
static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
{
unsigned long got;
- if (plpar_hcall(H_GET_TERM_CHAR, hp->vtermno, 0, 0, 0, &got,
- (unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
- return got;
- return 0;
+ got = hvc_get_chars(hp->vtermno, buf, count);
+
+ return got;
}
static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 7e6ac14c245..3480535a09c 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -579,7 +579,7 @@ static int __init rng_init (void)
/* Probe for Intel, AMD RNGs */
for_each_pci_dev(pdev) {
- ent = pci_match_device (rng_pci_tbl, pdev);
+ ent = pci_match_id(rng_pci_tbl, pdev);
if (ent) {
rng_ops = &rng_vendor_ops[ent->driver_data];
goto match;
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index edba5a35bf2..09103b3d8f0 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -770,10 +770,8 @@ send_signal:
}
if (c == '\n') {
if (L_ECHO(tty) || L_ECHONL(tty)) {
- if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+ if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
put_char('\a', tty);
- return;
- }
opost('\n', tty);
}
goto handle_newline;
@@ -790,10 +788,8 @@ send_signal:
* XXX are EOL_CHAR and EOL2_CHAR echoed?!?
*/
if (L_ECHO(tty)) {
- if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+ if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
put_char('\a', tty);
- return;
- }
/* Record the column of first canon char. */
if (tty->canon_head == tty->read_head)
tty->canon_column = tty->column;
@@ -862,12 +858,9 @@ static int n_tty_receive_room(struct tty_struct *tty)
* that erase characters will be handled. Other excess
* characters will be beeped.
*/
- if (tty->icanon && !tty->canon_data)
- return N_TTY_BUF_SIZE;
-
- if (left > 0)
- return left;
- return 0;
+ if (left <= 0)
+ left = tty->icanon && !tty->canon_data;
+ return left;
}
/**
@@ -1473,13 +1466,17 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
if (tty->driver->flush_chars)
tty->driver->flush_chars(tty);
} else {
- c = tty->driver->write(tty, b, nr);
- if (c < 0) {
- retval = c;
- goto break_out;
+ while (nr > 0) {
+ c = tty->driver->write(tty, b, nr);
+ if (c < 0) {
+ retval = c;
+ goto break_out;
+ }
+ if (!c)
+ break;
+ b += c;
+ nr -= c;
}
- b += c;
- nr -= c;
}
if (!nr)
break;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 8f36b1758eb..7a0c7464812 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -71,7 +71,6 @@
#include <linux/workqueue.h>
#include <linux/hdlc.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -593,11 +592,6 @@ static dev_link_t *mgslpc_attach(void)
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &mgslpc_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -3093,6 +3087,7 @@ static struct pcmcia_driver mgslpc_driver = {
.name = "synclink_cs",
},
.attach = mgslpc_attach,
+ .event = mgslpc_event,
.detach = mgslpc_detach,
.id_table = mgslpc_ids,
};
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 460b5d475ed..6b11d6b2129 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -271,7 +271,7 @@ static int random_write_wakeup_thresh = 128;
* samples to avoid wasting CPU time and reduce lock contention.
*/
-static int trickle_thresh = INPUT_POOL_WORDS * 28;
+static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
static DEFINE_PER_CPU(int, trickle_count) = 0;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index af79805b557..12d563c648f 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -228,7 +228,7 @@ static struct sysrq_key_op sysrq_term_op = {
static void moom_callback(void *ignored)
{
- out_of_memory(GFP_KERNEL);
+ out_of_memory(GFP_KERNEL, 0);
}
static DECLARE_WORK(moom_work, moom_callback, NULL);
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index 5413f290885..eb7058cbf01 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -24,6 +24,8 @@
#include <asm/io.h>
#include <asm/reboot.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/tb0219.h>
MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
MODULE_DESCRIPTION("TANBAC TB0219 base board driver");
@@ -266,6 +268,21 @@ static void tb0219_restart(char *command)
tb0219_write(TB0219_RESET, 0);
}
+static void tb0219_pci_irq_init(void)
+{
+ /* PCI Slot 1 */
+ vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, IRQ_LEVEL_LOW);
+
+ /* PCI Slot 2 */
+ vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, IRQ_LEVEL_LOW);
+
+ /* PCI Slot 3 */
+ vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW);
+}
+
static int tb0219_probe(struct device *dev)
{
int retval;
@@ -292,6 +309,8 @@ static int tb0219_probe(struct device *dev)
old_machine_restart = _machine_restart;
_machine_restart = tb0219_restart;
+ tb0219_pci_irq_init();
+
if (major == 0) {
major = retval;
printk(KERN_INFO "TB0219: major number %d\n", major);
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index b14d642439e..5d07ee59679 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -401,7 +401,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
*/
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (pci_match_device(i8xx_tco_pci_tbl, dev)) {
+ if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
i8xx_tco_pci = dev;
break;
}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index bf62dfe4976..7a7859dd0d9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -869,7 +869,7 @@ EXPORT_SYMBOL(cpufreq_get);
* cpufreq_suspend - let the low level driver prepare for suspend
*/
-static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
+static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
{
int cpu = sysdev->id;
unsigned int ret = 0;
@@ -897,7 +897,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
}
if (cpufreq_driver->suspend) {
- ret = cpufreq_driver->suspend(cpu_policy, state);
+ ret = cpufreq_driver->suspend(cpu_policy, pmsg);
if (ret) {
printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
"step on CPU %u\n", cpu_policy->cpu);
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index ed708b4427b..71407c578af 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -49,6 +49,7 @@
#include <linux/errno.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <asm/byteorder.h>
#include "padlock.h"
@@ -59,8 +60,12 @@
#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
struct aes_ctx {
- uint32_t e_data[AES_EXTENDED_KEY_SIZE+4];
- uint32_t d_data[AES_EXTENDED_KEY_SIZE+4];
+ uint32_t e_data[AES_EXTENDED_KEY_SIZE];
+ uint32_t d_data[AES_EXTENDED_KEY_SIZE];
+ struct {
+ struct cword encrypt;
+ struct cword decrypt;
+ } cword;
uint32_t *E;
uint32_t *D;
int key_length;
@@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len)
return 0;
}
+static inline struct aes_ctx *aes_ctx(void *ctx)
+{
+ return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT);
+}
+
static int
aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
{
- struct aes_ctx *ctx = ctx_arg;
+ struct aes_ctx *ctx = aes_ctx(ctx_arg);
uint32_t i, t, u, v, w;
uint32_t P[AES_EXTENDED_KEY_SIZE];
uint32_t rounds;
@@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t
ctx->key_length = key_len;
+ /*
+ * If the hardware is capable of generating the extended key
+ * itself we must supply the plain key for both encryption
+ * and decryption.
+ */
ctx->E = ctx->e_data;
- ctx->D = ctx->d_data;
-
- /* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */
- if ((int)(ctx->e_data) & 0x0F)
- ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0]));
-
- if ((int)(ctx->d_data) & 0x0F)
- ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0]));
+ ctx->D = ctx->e_data;
E_KEY[0] = uint32_t_in (in_key);
E_KEY[1] = uint32_t_in (in_key + 4);
E_KEY[2] = uint32_t_in (in_key + 8);
E_KEY[3] = uint32_t_in (in_key + 12);
+ /* Prepare control words. */
+ memset(&ctx->cword, 0, sizeof(ctx->cword));
+
+ ctx->cword.decrypt.encdec = 1;
+ ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4;
+ ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds;
+ ctx->cword.encrypt.ksize = (key_len - 16) / 8;
+ ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;
+
/* Don't generate extended keys if the hardware can do it. */
if (aes_hw_extkey_available(key_len))
return 0;
+ ctx->D = ctx->d_data;
+ ctx->cword.encrypt.keygen = 1;
+ ctx->cword.decrypt.keygen = 1;
+
switch (key_len) {
case 16:
t = E_KEY[3];
@@ -369,10 +390,9 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t
/* ====== Encryption/decryption routines ====== */
-/* This is the real call to PadLock. */
-static inline void
-padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
- void *control_word, uint32_t count)
+/* These are the real call to PadLock. */
+static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
+ void *control_word, u32 count)
{
asm volatile ("pushfl; popfl"); /* enforce key reload. */
asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
@@ -380,60 +400,70 @@ padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
: "d"(control_word), "b"(key), "c"(count));
}
-static void
-aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec)
+static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
+ u8 *iv, void *control_word, u32 count)
{
- /* Don't blindly modify this structure - the items must
- fit on 16-Bytes boundaries! */
- struct padlock_xcrypt_data {
- uint8_t buf[AES_BLOCK_SIZE];
- union cword cword;
- };
-
- struct aes_ctx *ctx = ctx_arg;
- char bigbuf[sizeof(struct padlock_xcrypt_data) + 16];
- struct padlock_xcrypt_data *data;
- void *key;
-
- /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */
- if (((long)bigbuf) & 0x0F)
- data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F));
- else
- data = (void*)bigbuf;
-
- /* Prepare Control word. */
- memset (data, 0, sizeof(struct padlock_xcrypt_data));
- data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */
- data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4;
- data->cword.b.ksize = (ctx->key_length - 16) / 8;
-
- /* Is the hardware capable to generate the extended key? */
- if (!aes_hw_extkey_available(ctx->key_length))
- data->cword.b.keygen = 1;
-
- /* ctx->E starts with a plain key - if the hardware is capable
- to generate the extended key itself we must supply
- the plain key for both Encryption and Decryption. */
- if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0)
- key = ctx->E;
- else
- key = ctx->D;
-
- memcpy(data->buf, in_arg, AES_BLOCK_SIZE);
- padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1);
- memcpy(out_arg, data->buf, AES_BLOCK_SIZE);
+ /* Enforce key reload. */
+ asm volatile ("pushfl; popfl");
+ /* rep xcryptcbc */
+ asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
+ : "+S" (input), "+D" (output), "+a" (iv)
+ : "d" (control_word), "b" (key), "c" (count));
+ return iv;
}
static void
aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
{
- aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT);
+ struct aes_ctx *ctx = aes_ctx(ctx_arg);
+ padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1);
}
static void
aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
{
- aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT);
+ struct aes_ctx *ctx = aes_ctx(ctx_arg);
+ padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
+}
+
+static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+ padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt,
+ nbytes / AES_BLOCK_SIZE);
+ return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+ padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt,
+ nbytes / AES_BLOCK_SIZE);
+ return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+ u8 *iv;
+
+ iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info,
+ &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE);
+ memcpy(desc->info, iv, AES_BLOCK_SIZE);
+
+ return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+ padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt,
+ nbytes / AES_BLOCK_SIZE);
+ return nbytes & ~(AES_BLOCK_SIZE - 1);
}
static struct crypto_alg aes_alg = {
@@ -441,6 +471,7 @@ static struct crypto_alg aes_alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_alignmask = PADLOCK_ALIGNMENT - 1,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
@@ -449,7 +480,11 @@ static struct crypto_alg aes_alg = {
.cia_max_keysize = AES_MAX_KEY_SIZE,
.cia_setkey = aes_set_key,
.cia_encrypt = aes_encrypt,
- .cia_decrypt = aes_decrypt
+ .cia_decrypt = aes_decrypt,
+ .cia_encrypt_ecb = aes_encrypt_ecb,
+ .cia_decrypt_ecb = aes_decrypt_ecb,
+ .cia_encrypt_cbc = aes_encrypt_cbc,
+ .cia_decrypt_cbc = aes_decrypt_cbc,
}
}
};
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
index 7a500605e44..3cf2b7a1234 100644
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -13,18 +13,18 @@
#ifndef _CRYPTO_PADLOCK_H
#define _CRYPTO_PADLOCK_H
+#define PADLOCK_ALIGNMENT 16
+
/* Control word. */
-union cword {
- uint32_t cword[4];
- struct {
- int rounds:4;
- int algo:3;
- int keygen:1;
- int interm:1;
- int encdec:1;
- int ksize:2;
- } b;
-};
+struct cword {
+ int __attribute__ ((__packed__))
+ rounds:4,
+ algo:3,
+ keygen:1,
+ interm:1,
+ encdec:1,
+ ksize:2;
+} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
#define PFX "padlock: "
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
new file mode 100644
index 00000000000..140d5f851a5
--- /dev/null
+++ b/drivers/hwmon/Kconfig
@@ -0,0 +1,420 @@
+#
+# I2C Sensor chip drivers configuration
+#
+
+menu "Hardware Monitoring support"
+
+config HWMON
+ tristate "Hardware Monitoring support"
+ default y
+ help
+ Hardware monitoring devices let you monitor the hardware health
+ of a system. Most modern motherboards include such a device. It
+ can include temperature sensors, voltage sensors, fan speed
+ sensors and various additional features such as the ability to
+ control the speed of the fans.
+
+config SENSORS_ADM1021
+ tristate "Analog Devices ADM1021 and compatibles"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Analog Devices ADM1021
+ and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
+ Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
+ and the XEON processor built-in sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called adm1021.
+
+config SENSORS_ADM1025
+ tristate "Analog Devices ADM1025 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Analog Devices ADM1025
+ and Philips NE1619 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called adm1025.
+
+config SENSORS_ADM1026
+ tristate "Analog Devices ADM1026 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Analog Devices ADM1026
+ sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called adm1026.
+
+config SENSORS_ADM1031
+ tristate "Analog Devices ADM1031 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Analog Devices ADM1031
+ and ADM1030 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called adm1031.
+
+config SENSORS_ADM9240
+ tristate "Analog Devices ADM9240 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Analog Devices ADM9240,
+ Dallas DS1780, National Semiconductor LM81 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called adm9240.
+
+config SENSORS_ASB100
+ tristate "Asus ASB100 Bach"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the ASB100 Bach sensor
+ chip found on some Asus mainboards.
+
+ This driver can also be built as a module. If so, the module
+ will be called asb100.
+
+config SENSORS_ATXP1
+ tristate "Attansic ATXP1 VID controller"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the Attansic ATXP1 VID
+ controller.
+
+ If your board have such a chip, you are able to control your CPU
+ core and other voltages.
+
+ This driver can also be built as a module. If so, the module
+ will be called atxp1.
+
+config SENSORS_DS1621
+ tristate "Dallas Semiconductor DS1621 and DS1625"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Dallas Semiconductor
+ DS1621 and DS1625 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called ds1621.
+
+config SENSORS_FSCHER
+ tristate "FSC Hermes"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Fujitsu Siemens
+ Computers Hermes sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called fscher.
+
+config SENSORS_FSCPOS
+ tristate "FSC Poseidon"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Fujitsu Siemens
+ Computers Poseidon sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called fscpos.
+
+config SENSORS_GL518SM
+ tristate "Genesys Logic GL518SM"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Genesys Logic GL518SM
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called gl518sm.
+
+config SENSORS_GL520SM
+ tristate "Genesys Logic GL520SM"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for Genesys Logic GL520SM
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called gl520sm.
+
+config SENSORS_IT87
+ tristate "ITE IT87xx and compatibles"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for ITE IT87xx sensor chips
+ and clones: SiS960.
+
+ This driver can also be built as a module. If so, the module
+ will be called it87.
+
+config SENSORS_LM63
+ tristate "National Semiconductor LM63"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the National Semiconductor
+ LM63 remote diode digital temperature sensor with integrated fan
+ control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro)
+ motherboard, among others.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm63.
+
+config SENSORS_LM75
+ tristate "National Semiconductor LM75 and compatibles"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM75
+ sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
+ 9-bit precision mode), and TelCom (now Microchip) TCN75.
+
+ The DS75 and DS1775 in 10- to 12-bit precision modes will require
+ a force module parameter. The driver will not handle the extra
+ precision anyhow.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm75.
+
+config SENSORS_LM77
+ tristate "National Semiconductor LM77"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM77
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm77.
+
+config SENSORS_LM78
+ tristate "National Semiconductor LM78 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM78,
+ LM78-J and LM79.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm78.
+
+config SENSORS_LM80
+ tristate "National Semiconductor LM80"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor
+ LM80 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm80.
+
+config SENSORS_LM83
+ tristate "National Semiconductor LM83"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor
+ LM83 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm83.
+
+config SENSORS_LM85
+ tristate "National Semiconductor LM85 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM85
+ sensor chips and clones: ADT7463, EMC6D100, EMC6D102 and ADM1027.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm85.
+
+config SENSORS_LM87
+ tristate "National Semiconductor LM87"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM87
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm87.
+
+config SENSORS_LM90
+ tristate "National Semiconductor LM90 and compatibles"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM90,
+ LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
+ MAX6658 sensor chips.
+
+ The Analog Devices ADT7461 sensor chip is also supported, but only
+ if found in ADM1032 compatibility mode.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm90.
+
+config SENSORS_LM92
+ tristate "National Semiconductor LM92 and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM92
+ and Maxim MAX6635 sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm92.
+
+config SENSORS_MAX1619
+ tristate "Maxim MAX1619 sensor chip"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for MAX1619 sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called max1619.
+
+config SENSORS_PC87360
+ tristate "National Semiconductor PC87360 family"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get access to the hardware monitoring
+ functions of the National Semiconductor PC8736x Super-I/O chips.
+ The PC87360, PC87363 and PC87364 only have fan monitoring and
+ control. The PC87365 and PC87366 additionally have voltage and
+ temperature monitoring.
+
+ This driver can also be built as a module. If so, the module
+ will be called pc87360.
+
+config SENSORS_SIS5595
+ tristate "Silicon Integrated Systems Corp. SiS5595"
+ depends on HWMON && I2C && PCI && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get support for the integrated sensors in
+ SiS5595 South Bridges.
+
+ This driver can also be built as a module. If so, the module
+ will be called sis5595.
+
+config SENSORS_SMSC47M1
+ tristate "SMSC LPC47M10x and compatibles"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get support for the integrated fan
+ monitoring and control capabilities of the SMSC LPC47B27x,
+ LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called smsc47m1.
+
+config SENSORS_SMSC47B397
+ tristate "SMSC LPC47B397-NC"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get support for the SMSC LPC47B397-NC
+ sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called smsc47b397.
+
+config SENSORS_VIA686A
+ tristate "VIA686A"
+ depends on HWMON && I2C && PCI
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get support for the integrated sensors in
+ Via 686A/B South Bridges.
+
+ This driver can also be built as a module. If so, the module
+ will be called via686a.
+
+config SENSORS_W83781D
+ tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
+ depends on HWMON && I2C
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the Winbond W8378x series
+ of sensor chips: the W83781D, W83782D, W83783S and W83627HF,
+ and the similar Asus AS99127F.
+
+ This driver can also be built as a module. If so, the module
+ will be called w83781d.
+
+config SENSORS_W83L785TS
+ tristate "Winbond W83L785TS-S"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the Winbond W83L785TS-S
+ sensor chip, which is used on the Asus A7N8X, among other
+ motherboards.
+
+ This driver can also be built as a module. If so, the module
+ will be called w83l785ts.
+
+config SENSORS_W83627HF
+ tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get support for the Winbond W836X7 series
+ of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF
+
+ This driver can also be built as a module. If so, the module
+ will be called w83627hf.
+
+config SENSORS_W83627EHF
+ tristate "Winbond W83627EHF"
+ depends on HWMON && I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ select I2C_ISA
+ help
+ If you say yes here you get preliminary support for the hardware
+ monitoring functionality of the Winbond W83627EHF Super-I/O chip.
+ Only fan and temperature inputs are supported at the moment, while
+ the chip does much more than that.
+
+ This driver can also be built as a module. If so, the module
+ will be called w83627ehf.
+
+config HWMON_DEBUG_CHIP
+ bool "Hardware Monitoring Chip debugging messages"
+ depends on HWMON
+ default n
+ help
+ Say Y here if you want the I2C chip drivers to produce a bunch of
+ debug messages to the system log. Select this if you are having
+ a problem with I2C support and want to see more of what is going
+ on.
+
+endmenu
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
new file mode 100644
index 00000000000..2781403a023
--- /dev/null
+++ b/drivers/hwmon/Makefile
@@ -0,0 +1,44 @@
+#
+# Makefile for sensor chip drivers.
+#
+
+# asb100, then w83781d go first, as they can override other drivers' addresses.
+obj-$(CONFIG_SENSORS_ASB100) += asb100.o
+obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
+obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
+
+obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
+obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
+obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
+obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
+obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
+obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
+obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
+obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
+obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
+obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
+obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
+obj-$(CONFIG_SENSORS_IT87) += it87.o
+obj-$(CONFIG_SENSORS_LM63) += lm63.o
+obj-$(CONFIG_SENSORS_LM75) += lm75.o
+obj-$(CONFIG_SENSORS_LM77) += lm77.o
+obj-$(CONFIG_SENSORS_LM78) += lm78.o
+obj-$(CONFIG_SENSORS_LM80) += lm80.o
+obj-$(CONFIG_SENSORS_LM83) += lm83.o
+obj-$(CONFIG_SENSORS_LM85) += lm85.o
+obj-$(CONFIG_SENSORS_LM87) += lm87.o
+obj-$(CONFIG_SENSORS_LM90) += lm90.o
+obj-$(CONFIG_SENSORS_LM92) += lm92.o
+obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
+obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
+obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
+obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
+obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
+obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
+obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
+obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
+
+ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
diff --git a/drivers/i2c/chips/adm1021.c b/drivers/hwmon/adm1021.c
index d2c774c32f4..d2c774c32f4 100644
--- a/drivers/i2c/chips/adm1021.c
+++ b/drivers/hwmon/adm1021.c
diff --git a/drivers/i2c/chips/adm1025.c b/drivers/hwmon/adm1025.c
index e452d0daf90..e452d0daf90 100644
--- a/drivers/i2c/chips/adm1025.c
+++ b/drivers/hwmon/adm1025.c
diff --git a/drivers/i2c/chips/adm1026.c b/drivers/hwmon/adm1026.c
index 3c85fe150cd..3c85fe150cd 100644
--- a/drivers/i2c/chips/adm1026.c
+++ b/drivers/hwmon/adm1026.c
diff --git a/drivers/i2c/chips/adm1031.c b/drivers/hwmon/adm1031.c
index 9168e983ca1..9168e983ca1 100644
--- a/drivers/i2c/chips/adm1031.c
+++ b/drivers/hwmon/adm1031.c
diff --git a/drivers/i2c/chips/adm9240.c b/drivers/hwmon/adm9240.c
index 5c68e9c311a..5c68e9c311a 100644
--- a/drivers/i2c/chips/adm9240.c
+++ b/drivers/hwmon/adm9240.c
diff --git a/drivers/i2c/chips/asb100.c b/drivers/hwmon/asb100.c
index 70d996d6fe0..70d996d6fe0 100644
--- a/drivers/i2c/chips/asb100.c
+++ b/drivers/hwmon/asb100.c
diff --git a/drivers/i2c/chips/atxp1.c b/drivers/hwmon/atxp1.c
index 0bcf82b4c07..0bcf82b4c07 100644
--- a/drivers/i2c/chips/atxp1.c
+++ b/drivers/hwmon/atxp1.c
diff --git a/drivers/i2c/chips/ds1621.c b/drivers/hwmon/ds1621.c
index 5360d58804f..5360d58804f 100644
--- a/drivers/i2c/chips/ds1621.c
+++ b/drivers/hwmon/ds1621.c
diff --git a/drivers/i2c/chips/fscher.c b/drivers/hwmon/fscher.c
index da411741c2c..da411741c2c 100644
--- a/drivers/i2c/chips/fscher.c
+++ b/drivers/hwmon/fscher.c
diff --git a/drivers/i2c/chips/fscpos.c b/drivers/hwmon/fscpos.c
index 3beaa6191ef..3beaa6191ef 100644
--- a/drivers/i2c/chips/fscpos.c
+++ b/drivers/hwmon/fscpos.c
diff --git a/drivers/i2c/chips/gl518sm.c b/drivers/hwmon/gl518sm.c
index 6bedf729dcf..6bedf729dcf 100644
--- a/drivers/i2c/chips/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
diff --git a/drivers/i2c/chips/gl520sm.c b/drivers/hwmon/gl520sm.c
index a13a504f5bf..a13a504f5bf 100644
--- a/drivers/i2c/chips/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
diff --git a/drivers/i2c/chips/it87.c b/drivers/hwmon/it87.c
index db20c9e4739..db20c9e4739 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/hwmon/it87.c
diff --git a/drivers/i2c/chips/lm63.c b/drivers/hwmon/lm63.c
index 7c6f9ea5a25..7c6f9ea5a25 100644
--- a/drivers/i2c/chips/lm63.c
+++ b/drivers/hwmon/lm63.c
diff --git a/drivers/i2c/chips/lm75.c b/drivers/hwmon/lm75.c
index 5be164ed278..5be164ed278 100644
--- a/drivers/i2c/chips/lm75.c
+++ b/drivers/hwmon/lm75.c
diff --git a/drivers/i2c/chips/lm75.h b/drivers/hwmon/lm75.h
index 63e3f2fb4c2..63e3f2fb4c2 100644
--- a/drivers/i2c/chips/lm75.h
+++ b/drivers/hwmon/lm75.h
diff --git a/drivers/i2c/chips/lm77.c b/drivers/hwmon/lm77.c
index b98f4495299..b98f4495299 100644
--- a/drivers/i2c/chips/lm77.c
+++ b/drivers/hwmon/lm77.c
diff --git a/drivers/i2c/chips/lm78.c b/drivers/hwmon/lm78.c
index 29241469dcb..29241469dcb 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/hwmon/lm78.c
diff --git a/drivers/i2c/chips/lm80.c b/drivers/hwmon/lm80.c
index 8100595feb4..8100595feb4 100644
--- a/drivers/i2c/chips/lm80.c
+++ b/drivers/hwmon/lm80.c
diff --git a/drivers/i2c/chips/lm83.c b/drivers/hwmon/lm83.c
index a49008b444c..a49008b444c 100644
--- a/drivers/i2c/chips/lm83.c
+++ b/drivers/hwmon/lm83.c
diff --git a/drivers/i2c/chips/lm85.c b/drivers/hwmon/lm85.c
index b4d7fd41826..b4d7fd41826 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/hwmon/lm85.c
diff --git a/drivers/i2c/chips/lm87.c b/drivers/hwmon/lm87.c
index 1921ed1af18..1921ed1af18 100644
--- a/drivers/i2c/chips/lm87.c
+++ b/drivers/hwmon/lm87.c
diff --git a/drivers/i2c/chips/lm90.c b/drivers/hwmon/lm90.c
index a67dcadf7cb..a67dcadf7cb 100644
--- a/drivers/i2c/chips/lm90.c
+++ b/drivers/hwmon/lm90.c
diff --git a/drivers/i2c/chips/lm92.c b/drivers/hwmon/lm92.c
index 215c8e40ffd..215c8e40ffd 100644
--- a/drivers/i2c/chips/lm92.c
+++ b/drivers/hwmon/lm92.c
diff --git a/drivers/i2c/chips/max1619.c b/drivers/hwmon/max1619.c
index bf553dcd97d..bf553dcd97d 100644
--- a/drivers/i2c/chips/max1619.c
+++ b/drivers/hwmon/max1619.c
diff --git a/drivers/i2c/chips/pc87360.c b/drivers/hwmon/pc87360.c
index 876c68f3af3..876c68f3af3 100644
--- a/drivers/i2c/chips/pc87360.c
+++ b/drivers/hwmon/pc87360.c
diff --git a/drivers/i2c/chips/sis5595.c b/drivers/hwmon/sis5595.c
index 6bbfc8fb4f1..6bbfc8fb4f1 100644
--- a/drivers/i2c/chips/sis5595.c
+++ b/drivers/hwmon/sis5595.c
diff --git a/drivers/i2c/chips/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 251ac265955..251ac265955 100644
--- a/drivers/i2c/chips/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
diff --git a/drivers/i2c/chips/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 897117a7213..897117a7213 100644
--- a/drivers/i2c/chips/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
diff --git a/drivers/i2c/chips/via686a.c b/drivers/hwmon/via686a.c
index 137d9b7cacd..164d4794839 100644
--- a/drivers/i2c/chips/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -1,9 +1,9 @@
/*
via686a.c - Part of lm_sensors, Linux kernel modules
- for hardware monitoring
+ for hardware monitoring
Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
- Kyösti Mälkki <kmalkki@cc.hut.fi>,
+ Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark Studebaker <mdsxyz123@yahoo.com>,
and Bob Dougherty <bobd@stanford.edu>
(Some conversion-factor data were contributed by Jonathan Teh Soon Yew
@@ -171,18 +171,18 @@ static inline u8 FAN_TO_REG(long rpm, int div)
/******** TEMP CONVERSIONS (Bob Dougherty) *********/
/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
if(temp<169)
- return double(temp)*0.427-32.08;
+ return double(temp)*0.427-32.08;
else if(temp>=169 && temp<=202)
- return double(temp)*0.582-58.16;
+ return double(temp)*0.582-58.16;
else
- return double(temp)*0.924-127.33;
+ return double(temp)*0.924-127.33;
A fifth-order polynomial fits the unofficial data (provided by Alex van
Kaam <darkside@chello.nl>) a bit better. It also give more reasonable
numbers on my machine (ie. they agree with what my BIOS tells me).
Here's the fifth-order fit to the 8-bit data:
temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
- 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
+ 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
(2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
finding my typos in this formula!)
diff --git a/drivers/i2c/chips/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 8a40b6976e1..8a40b6976e1 100644
--- a/drivers/i2c/chips/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/hwmon/w83627hf.c
index bd87a42e068..bd87a42e068 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/hwmon/w83781d.c
index 0bb131ce09e..0bb131ce09e 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/hwmon/w83781d.c
diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index 4469d52aba4..4469d52aba4 100644
--- a/drivers/i2c/chips/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
index 68e9e6832ca..e6cae39f47a 100644
--- a/drivers/i2c/algos/i2c-algo-ite.c
+++ b/drivers/i2c/algos/i2c-algo-ite.c
@@ -208,7 +208,7 @@ static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
goto bailout;
}
sdalo(adap);
- printk("test_bus:1 scl: %d sda: %d \n",getscl(adap),
+ printk("test_bus:1 scl: %d sda: %d\n", getscl(adap),
getsda(adap));
if ( 0 != getsda(adap) ) {
printk("test_bus: %s SDA stuck high!\n",name);
@@ -221,7 +221,7 @@ static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
goto bailout;
}
sdahi(adap);
- printk("test_bus:2 scl: %d sda: %d \n",getscl(adap),
+ printk("test_bus:2 scl: %d sda: %d\n", getscl(adap),
getsda(adap));
if ( 0 == getsda(adap) ) {
printk("test_bus: %s SDA stuck low!\n",name);
@@ -234,7 +234,7 @@ static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
goto bailout;
}
scllo(adap);
- printk("test_bus:3 scl: %d sda: %d \n",getscl(adap),
+ printk("test_bus:3 scl: %d sda: %d\n", getscl(adap),
getsda(adap));
if ( 0 != getscl(adap) ) {
@@ -247,7 +247,7 @@ static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
goto bailout;
}
sclhi(adap);
- printk("test_bus:4 scl: %d sda: %d \n",getscl(adap),
+ printk("test_bus:4 scl: %d sda: %d\n", getscl(adap),
getsda(adap));
if ( 0 == getscl(adap) ) {
printk("test_bus: %s SCL stuck low!\n",name);
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 45e6efb1dcd..0ab7e37f5b0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -194,7 +194,7 @@ static int i801_transaction(void)
/* Make sure the SMBus host is ready to start transmitting */
/* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
- dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n",
+ dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n",
temp);
outb_p(temp, SMBHSTSTS);
if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
@@ -315,7 +315,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
}
if (temp & errmask) {
dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
- "Resetting... \n", temp);
+ "Resetting...\n", temp);
outb_p(temp, SMBHSTSTS);
if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
dev_err(&I801_dev->dev,
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index 363e545fc01..94ae808314f 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -698,7 +698,7 @@ dispose_iface(struct device *dev)
}
static int
-create_iface_macio(struct macio_dev* dev, const struct of_match *match)
+create_iface_macio(struct macio_dev* dev, const struct of_device_id *match)
{
return create_iface(dev->ofdev.node, &dev->ofdev.dev);
}
@@ -710,7 +710,7 @@ dispose_iface_macio(struct macio_dev* dev)
}
static int
-create_iface_of_platform(struct of_device* dev, const struct of_match *match)
+create_iface_of_platform(struct of_device* dev, const struct of_device_id *match)
{
return create_iface(dev->node, &dev->dev);
}
@@ -721,10 +721,9 @@ dispose_iface_of_platform(struct of_device* dev)
return dispose_iface(&dev->dev);
}
-static struct of_match i2c_keywest_match[] =
+static struct of_device_id i2c_keywest_match[] =
{
{
- .name = OF_ANY_MATCH,
.type = "i2c",
.compatible = "keywest"
},
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 1f80ba9da6f..6d34ee381ce 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -243,7 +243,7 @@ static int piix4_transaction(void)
/* Make sure the SMBus host is ready to start transmitting */
if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). "
- "Resetting... \n", temp);
+ "Resetting...\n", temp);
outb_p(temp, SMBHSTSTS);
if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 2b5911cfb7b..bbd5e4e52f0 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -228,7 +228,7 @@ static int sis5595_transaction(struct i2c_adapter *adap)
/* Make sure the SMBus host is ready to start transmitting */
temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
if (temp != 0x00) {
- dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting... \n", temp);
+ dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
sis5595_write(SMB_STS_LO, temp & 0xff);
sis5595_write(SMB_STS_HI, temp >> 8);
if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index a0982da0980..43f70dbfc03 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -1,409 +1,12 @@
#
-# I2C Sensor and "other" chip configuration
+# Miscellaneous I2C chip drivers configuration
#
-menu "Hardware Sensors Chip support"
- depends on I2C
-
config I2C_SENSOR
tristate
default n
-config SENSORS_ADM1021
- tristate "Analog Devices ADM1021 and compatibles"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for Analog Devices ADM1021
- and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
- Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
- and the XEON processor built-in sensor.
-
- This driver can also be built as a module. If so, the module
- will be called adm1021.
-
-config SENSORS_ADM1025
- tristate "Analog Devices ADM1025 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Analog Devices ADM1025
- and Philips NE1619 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called adm1025.
-
-config SENSORS_ADM1026
- tristate "Analog Devices ADM1026 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Analog Devices ADM1026
- sensor chip.
-
- This driver can also be built as a module. If so, the module
- will be called adm1026.
-
-config SENSORS_ADM1031
- tristate "Analog Devices ADM1031 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Analog Devices ADM1031
- and ADM1030 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called adm1031.
-
-config SENSORS_ADM9240
- tristate "Analog Devices ADM9240 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Analog Devices ADM9240,
- Dallas DS1780, National Semiconductor LM81 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called adm9240.
-
-config SENSORS_ASB100
- tristate "Asus ASB100 Bach"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for the ASB100 Bach sensor
- chip found on some Asus mainboards.
-
- This driver can also be built as a module. If so, the module
- will be called asb100.
-
-config SENSORS_ATXP1
- tristate "Attansic ATXP1 VID controller"
- depends on I2C && EXPERIMENTAL
- help
- If you say yes here you get support for the Attansic ATXP1 VID
- controller.
-
- If your board have such a chip, you are able to control your CPU
- core and other voltages.
-
- This driver can also be built as a module. If so, the module
- will be called atxp1.
-
-config SENSORS_DS1621
- tristate "Dallas Semiconductor DS1621 and DS1625"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Dallas Semiconductor
- DS1621 and DS1625 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called ds1621.
-
-config SENSORS_FSCHER
- tristate "FSC Hermes"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Fujitsu Siemens
- Computers Hermes sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called fscher.
-
-config SENSORS_FSCPOS
- tristate "FSC Poseidon"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Fujitsu Siemens
- Computers Poseidon sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called fscpos.
-
-config SENSORS_GL518SM
- tristate "Genesys Logic GL518SM"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for Genesys Logic GL518SM
- sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called gl518sm.
-
-config SENSORS_GL520SM
- tristate "Genesys Logic GL520SM"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for Genesys Logic GL520SM
- sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called gl520sm.
-
-config SENSORS_IT87
- tristate "ITE IT87xx and compatibles"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for ITE IT87xx sensor chips
- and clones: SiS960.
-
- This driver can also be built as a module. If so, the module
- will be called it87.
-
-config SENSORS_LM63
- tristate "National Semiconductor LM63"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for the National Semiconductor
- LM63 remote diode digital temperature sensor with integrated fan
- control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro)
- motherboard, among others.
-
- This driver can also be built as a module. If so, the module
- will be called lm63.
-
-config SENSORS_LM75
- tristate "National Semiconductor LM75 and compatibles"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM75
- sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
- 9-bit precision mode), and TelCom (now Microchip) TCN75.
-
- The DS75 and DS1775 in 10- to 12-bit precision modes will require
- a force module parameter. The driver will not handle the extra
- precision anyhow.
-
- This driver can also be built as a module. If so, the module
- will be called lm75.
-
-config SENSORS_LM77
- tristate "National Semiconductor LM77"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM77
- sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called lm77.
-
-config SENSORS_LM78
- tristate "National Semiconductor LM78 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM78,
- LM78-J and LM79.
-
- This driver can also be built as a module. If so, the module
- will be called lm78.
-
-config SENSORS_LM80
- tristate "National Semiconductor LM80"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor
- LM80 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called lm80.
-
-config SENSORS_LM83
- tristate "National Semiconductor LM83"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor
- LM83 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called lm83.
-
-config SENSORS_LM85
- tristate "National Semiconductor LM85 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM85
- sensor chips and clones: ADT7463, EMC6D100, EMC6D102 and ADM1027.
-
- This driver can also be built as a module. If so, the module
- will be called lm85.
-
-config SENSORS_LM87
- tristate "National Semiconductor LM87"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM87
- sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called lm87.
-
-config SENSORS_LM90
- tristate "National Semiconductor LM90 and compatibles"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM90,
- LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
- MAX6658 sensor chips.
-
- The Analog Devices ADT7461 sensor chip is also supported, but only
- if found in ADM1032 compatibility mode.
-
- This driver can also be built as a module. If so, the module
- will be called lm90.
-
-config SENSORS_LM92
- tristate "National Semiconductor LM92 and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for National Semiconductor LM92
- and Maxim MAX6635 sensor chips.
-
- This driver can also be built as a module. If so, the module
- will be called lm92.
-
-config SENSORS_MAX1619
- tristate "Maxim MAX1619 sensor chip"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for MAX1619 sensor chip.
-
- This driver can also be built as a module. If so, the module
- will be called max1619.
-
-config SENSORS_PC87360
- tristate "National Semiconductor PC87360 family"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get access to the hardware monitoring
- functions of the National Semiconductor PC8736x Super-I/O chips.
- The PC87360, PC87363 and PC87364 only have fan monitoring and
- control. The PC87365 and PC87366 additionally have voltage and
- temperature monitoring.
-
- This driver can also be built as a module. If so, the module
- will be called pc87360.
-
-config SENSORS_SMSC47B397
- tristate "SMSC LPC47B397-NC"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get support for the SMSC LPC47B397-NC
- sensor chip.
-
- This driver can also be built as a module. If so, the module
- will be called smsc47b397.
-
-config SENSORS_SIS5595
- tristate "Silicon Integrated Systems Corp. SiS5595"
- depends on I2C && PCI && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get support for the integrated sensors in
- SiS5595 South Bridges.
-
- This driver can also be built as a module. If so, the module
- will be called sis5595.
-
-config SENSORS_SMSC47M1
- tristate "SMSC LPC47M10x and compatibles"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get support for the integrated fan
- monitoring and control capabilities of the SMSC LPC47B27x,
- LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips.
-
- This driver can also be built as a module. If so, the module
- will be called smsc47m1.
-
-config SENSORS_VIA686A
- tristate "VIA686A"
- depends on I2C && PCI
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get support for the integrated sensors in
- Via 686A/B South Bridges.
-
- This driver can also be built as a module. If so, the module
- will be called via686a.
-
-config SENSORS_W83781D
- tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
- depends on I2C
- select I2C_SENSOR
- help
- If you say yes here you get support for the Winbond W8378x series
- of sensor chips: the W83781D, W83782D, W83783S and W83627HF,
- and the similar Asus AS99127F.
-
- This driver can also be built as a module. If so, the module
- will be called w83781d.
-
-config SENSORS_W83L785TS
- tristate "Winbond W83L785TS-S"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- help
- If you say yes here you get support for the Winbond W83L785TS-S
- sensor chip, which is used on the Asus A7N8X, among other
- motherboards.
-
- This driver can also be built as a module. If so, the module
- will be called w83l785ts.
-
-config SENSORS_W83627HF
- tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get support for the Winbond W836X7 series
- of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF
-
- This driver can also be built as a module. If so, the module
- will be called w83627hf.
-
-config SENSORS_W83627EHF
- tristate "Winbond W83627EHF"
- depends on I2C && EXPERIMENTAL
- select I2C_SENSOR
- select I2C_ISA
- help
- If you say yes here you get preliminary support for the hardware
- monitoring functionality of the Winbond W83627EHF Super-I/O chip.
- Only fan and temperature inputs are supported at the moment, while
- the chip does much more than that.
-
- This driver can also be built as a module. If so, the module
- will be called w83627ehf.
-
-endmenu
-
-menu "Other I2C Chip support"
+menu "Miscellaneous I2C Chip support"
depends on I2C
config SENSORS_DS1337
@@ -509,7 +112,6 @@ config TPS65010
This driver can also be built as a module. If so, the module
will be called tps65010.
-
config SENSORS_M41T00
tristate "ST M41T00 RTC chip"
depends on I2C && PPC32
@@ -520,13 +122,16 @@ config SENSORS_M41T00
will be called m41t00.
config SENSORS_MAX6875
- tristate "MAXIM MAX6875 Power supply supervisor"
+ tristate "Maxim MAX6875 Power supply supervisor"
depends on I2C && EXPERIMENTAL
help
- If you say yes here you get support for the MAX6875
- EEPROM-Programmable, Hex/Quad, Power-Suppy Sequencers/Supervisors.
+ If you say yes here you get support for the Maxim MAX6875
+ EEPROM-programmable, quad power-supply sequencer/supervisor.
+
+ This provides an interface to program the EEPROM and reset the chip.
- This provides a interface to program the EEPROM and reset the chip.
+ This driver also supports the Maxim MAX6874 hex power-supply
+ sequencer/supervisor if found at a compatible address.
This driver can also be built as a module. If so, the module
will be called max6875.
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index b5e6d2f84f9..a876dd42b86 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -1,52 +1,16 @@
#
-# Makefile for sensor and "other" I2C chip drivers.
+# Makefile for miscellaneous I2C chip drivers.
#
-# asb100, then w83781d go first, as they can override other drivers' addresses.
-obj-$(CONFIG_SENSORS_ASB100) += asb100.o
-obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
-obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
-
-obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
-obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
-obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
-obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
-obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
-obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_DS1337) += ds1337.o
obj-$(CONFIG_SENSORS_DS1374) += ds1374.o
-obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
-obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
-obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
-obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
-obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
-obj-$(CONFIG_SENSORS_IT87) += it87.o
-obj-$(CONFIG_SENSORS_LM63) += lm63.o
-obj-$(CONFIG_SENSORS_LM75) += lm75.o
-obj-$(CONFIG_SENSORS_LM77) += lm77.o
-obj-$(CONFIG_SENSORS_LM78) += lm78.o
-obj-$(CONFIG_SENSORS_LM80) += lm80.o
-obj-$(CONFIG_SENSORS_LM83) += lm83.o
-obj-$(CONFIG_SENSORS_LM85) += lm85.o
-obj-$(CONFIG_SENSORS_LM87) += lm87.o
-obj-$(CONFIG_SENSORS_LM90) += lm90.o
-obj-$(CONFIG_SENSORS_LM92) += lm92.o
-obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
-obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
-obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
-obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
-obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
-obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
-obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
-obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
-
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
obj-$(CONFIG_TPS65010) += tps65010.o
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index addf0adc24d..6ea413f6d5e 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -173,9 +173,6 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
| I2C_FUNC_SMBUS_BYTE))
goto exit;
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access eeprom_{read,write}_value. */
if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index 5e463c47bfb..778d7e12859 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -207,7 +207,7 @@ m41t00_detach(struct i2c_client *client)
int rc;
if ((rc = i2c_detach_client(client)) == 0) {
- kfree(i2c_get_clientdata(client));
+ kfree(client);
tasklet_kill(&m41t00_tasklet);
}
return rc;
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
index fe6b150ec4c..c4f14d9623c 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/i2c/chips/max6875.c
@@ -37,7 +37,8 @@
#include <linux/i2c-sensor.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x50, 0x52, I2C_CLIENT_END};
+/* No address scanned by default, as this could corrupt standard EEPROMS. */
+static unsigned short normal_i2c[] = {I2C_CLIENT_END};
static unsigned int normal_isa[] = {I2C_CLIENT_ISA_END};
/* Insmod parameters */
@@ -369,6 +370,9 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
new_client->driver = &max6875_driver;
new_client->flags = 0;
+ /* Prevent 24RF08 corruption */
+ i2c_smbus_write_quick(new_client, 0);
+
/* Setup the user section */
data->blocks[max6875_eeprom_user].type = max6875_eeprom_user;
data->blocks[max6875_eeprom_user].slices = USER_EEPROM_SLICES;
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index c0ac01b6003..280e9638c0f 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -18,7 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#undef DEBUG
#include <linux/config.h>
#include <linux/kernel.h>
@@ -49,11 +48,7 @@
MODULE_DESCRIPTION("TPS6501x Power Management Driver");
MODULE_LICENSE("GPL");
-/* only two addresses possible */
-#define TPS_BASE 0x48
-static unsigned short normal_i2c[] = {
- TPS_BASE,
- I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x48, /* 0x49, */ I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
@@ -102,7 +97,7 @@ struct tps65010 {
u8 chgstatus, regstatus, chgconf;
u8 nmask1, nmask2;
- /* plus four GPIOs, probably used to switch power */
+ /* not currently tracking GPIO state */
};
#define POWER_POLL_DELAY msecs_to_jiffies(800)
@@ -135,7 +130,7 @@ static void dbg_regstat(char *buf, size_t len, u8 regstatus)
(regstatus & TPS_REG_COVER) ? " uncover" : "",
(regstatus & TPS_REG_UVLO) ? " UVLO" : "",
(regstatus & TPS_REG_NO_CHG) ? " NO_CHG" : "",
- (regstatus & TPS_REG_PG_LD02) ? " ld01_bad" : "",
+ (regstatus & TPS_REG_PG_LD02) ? " ld02_bad" : "",
(regstatus & TPS_REG_PG_LD01) ? " ld01_bad" : "",
(regstatus & TPS_REG_PG_MAIN) ? " main_bad" : "",
(regstatus & TPS_REG_PG_CORE) ? " core_bad" : "");
@@ -143,7 +138,7 @@ static void dbg_regstat(char *buf, size_t len, u8 regstatus)
static void dbg_chgconf(int por, char *buf, size_t len, u8 chgconfig)
{
- char *hibit;
+ const char *hibit;
if (por)
hibit = (chgconfig & TPS_CHARGE_POR)
@@ -295,7 +290,7 @@ static int dbg_show(struct seq_file *s, void *_)
seq_printf(s, "defgpio %02x mask3 %02x\n", value, v2);
for (i = 0; i < 4; i++) {
- if (value & (1 << (4 +i)))
+ if (value & (1 << (4 + i)))
seq_printf(s, " gpio%d-out %s\n", i + 1,
(value & (1 << i)) ? "low" : "hi ");
else
@@ -481,7 +476,7 @@ static int __exit tps65010_detach_client(struct i2c_client *client)
debugfs_remove(tps->file);
if (i2c_detach_client(client) == 0)
kfree(tps);
- the_tps = 0;
+ the_tps = NULL;
return 0;
}
@@ -514,7 +509,6 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
INIT_WORK(&tps->work, tps65010_work, tps);
tps->irq = -1;
tps->client.addr = address;
- i2c_set_clientdata(&tps->client, tps);
tps->client.adapter = bus;
tps->client.driver = &tps65010_driver;
strlcpy(tps->client.name, DRIVER_NAME, I2C_NAME_SIZE);
@@ -523,9 +517,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
if (status < 0) {
dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n",
DRIVER_NAME, address, status);
-fail1:
- kfree(tps);
- return 0;
+ goto fail1;
}
#ifdef CONFIG_ARM
@@ -535,7 +527,7 @@ fail1:
tps->irq = OMAP_GPIO_IRQ(58);
omap_request_gpio(58);
omap_set_gpio_direction(58, 1);
- omap_set_gpio_edge_ctrl(58, OMAP_GPIO_FALLING_EDGE);
+ set_irq_type(tps->irq, IRQT_FALLING);
}
if (machine_is_omap_osk()) {
tps->model = TPS65010;
@@ -543,7 +535,7 @@ fail1:
tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1));
omap_request_gpio(OMAP_MPUIO(1));
omap_set_gpio_direction(OMAP_MPUIO(1), 1);
- omap_set_gpio_edge_ctrl(OMAP_MPUIO(1), OMAP_GPIO_FALLING_EDGE);
+ set_irq_type(tps->irq, IRQT_FALLING);
}
if (machine_is_omap_h3()) {
tps->model = TPS65013;
@@ -633,6 +625,9 @@ fail1:
tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
tps, DEBUG_FOPS);
return 0;
+fail1:
+ kfree(tps);
+ return 0;
}
static int __init tps65010_scan_bus(struct i2c_adapter *bus)
@@ -645,7 +640,6 @@ static int __init tps65010_scan_bus(struct i2c_adapter *bus)
static struct i2c_driver tps65010_driver = {
.owner = THIS_MODULE,
.name = "tps65010",
- .id = 888, /* FIXME assign "official" value */
.flags = I2C_DF_NOTIFY,
.attach_adapter = tps65010_scan_bus,
.detach_client = __exit_p(tps65010_detach_client),
@@ -744,7 +738,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
if (!the_tps)
return -ENODEV;
- if(led == LED1)
+ if (led == LED1)
offs = 0;
else {
offs = 2;
@@ -753,11 +747,13 @@ int tps65010_set_led(unsigned led, unsigned mode)
down(&the_tps->lock);
- dev_dbg (&the_tps->client.dev, "led%i_on 0x%02x\n", led,
- i2c_smbus_read_byte_data(&the_tps->client, TPS_LED1_ON + offs));
+ pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led,
+ i2c_smbus_read_byte_data(&the_tps->client,
+ TPS_LED1_ON + offs));
- dev_dbg (&the_tps->client.dev, "led%i_per 0x%02x\n", led,
- i2c_smbus_read_byte_data(&the_tps->client, TPS_LED1_PER + offs));
+ pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led,
+ i2c_smbus_read_byte_data(&the_tps->client,
+ TPS_LED1_PER + offs));
switch (mode) {
case OFF:
@@ -773,7 +769,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
led_per = 0x08 | (1 << 7);
break;
default:
- printk(KERN_ERR "%s: Wrong mode parameter for tps65010_set_led()\n",
+ printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n",
DRIVER_NAME);
up(&the_tps->lock);
return -EINVAL;
@@ -789,7 +785,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
return status;
}
- dev_dbg (&the_tps->client.dev, "led%i_on 0x%02x\n", led,
+ pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led,
i2c_smbus_read_byte_data(&the_tps->client, TPS_LED1_ON + offs));
status = i2c_smbus_write_byte_data(&the_tps->client,
@@ -802,8 +798,9 @@ int tps65010_set_led(unsigned led, unsigned mode)
return status;
}
- dev_dbg (&the_tps->client.dev, "led%i_per 0x%02x\n", led,
- i2c_smbus_read_byte_data(&the_tps->client, TPS_LED1_PER + offs));
+ pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led,
+ i2c_smbus_read_byte_data(&the_tps->client,
+ TPS_LED1_PER + offs));
up(&the_tps->lock);
@@ -874,7 +871,7 @@ int tps65010_set_low_pwr(unsigned mode)
if (status != 0)
printk(KERN_ERR "%s: Failed to write vdcdc1 register\n",
- DRIVER_NAME);
+ DRIVER_NAME);
else
pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
@@ -900,14 +897,14 @@ int tps65010_config_vregs1(unsigned value)
down(&the_tps->lock);
pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
+ i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
status = i2c_smbus_write_byte_data(&the_tps->client,
TPS_VREGS1, value);
if (status != 0)
printk(KERN_ERR "%s: Failed to write vregs1 register\n",
- DRIVER_NAME);
+ DRIVER_NAME);
else
pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
@@ -1009,7 +1006,7 @@ static int __init tps_init(void)
msleep(10);
}
-#if defined(CONFIG_ARM)
+#ifdef CONFIG_ARM
if (machine_is_omap_osk()) {
// FIXME: More should be placed in the initialization code
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 51ce268998c..4fd4f52c8e9 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -156,7 +156,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
goto out_unlock;
}
- res = idr_get_new(&i2c_adapter_idr, NULL, &id);
+ res = idr_get_new(&i2c_adapter_idr, adap, &id);
if (res < 0) {
if (res == -EAGAIN)
res = -ENOMEM;
@@ -765,20 +765,15 @@ int i2c_adapter_id(struct i2c_adapter *adap)
struct i2c_adapter* i2c_get_adapter(int id)
{
- struct list_head *item;
struct i2c_adapter *adapter;
down(&core_lists);
- list_for_each(item,&adapters) {
- adapter = list_entry(item, struct i2c_adapter, list);
- if (id == adapter->nr &&
- try_module_get(adapter->owner)) {
- up(&core_lists);
- return adapter;
- }
- }
+ adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+ if (adapter && !try_module_get(adapter->owner))
+ adapter = NULL;
+
up(&core_lists);
- return NULL;
+ return adapter;
}
void i2c_put_adapter(struct i2c_adapter *adap)
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 5be8ad6dc9e..cca9c075966 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -20,7 +20,6 @@ ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o
# Core IDE code - must come before legacy
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
-ide-core-$(CONFIG_BLK_DEV_IDE_TCQ) += ide-tcq.o
ide-core-$(CONFIG_PROC_FS) += ide-proc.o
ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 0a31cfda08a..74af7e07486 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -431,7 +431,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
#if VERBOSE_IDE_CD_ERRORS
{
int i;
- const char *s;
+ const char *s = "bad sense key!";
char buf[80];
printk ("ATAPI device %s:\n", drive->name);
@@ -446,8 +446,6 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
if (sense->sense_key < ARY_LEN(sense_key_texts))
s = sense_key_texts[sense->sense_key];
- else
- s = "bad sense key!";
printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 6806d407e9c..b09a6537c7a 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -487,8 +487,7 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
u8 err = 0;
local_irq_set(flags);
- printk("%s: %s: status=0x%02x", drive->name, msg, stat);
- printk(" { ");
+ printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
if (stat & BUSY_STAT)
printk("Busy ");
else {
@@ -500,15 +499,13 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
if (stat & INDEX_STAT) printk("Index ");
if (stat & ERR_STAT) printk("Error ");
}
- printk("}");
- printk("\n");
+ printk("}\n");
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = hwif->INB(IDE_ERROR_REG);
- printk("%s: %s: error=0x%02x", drive->name, msg, err);
- printk(" { ");
+ printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
if (err & ABRT_ERR) printk("DriveStatusError ");
if (err & ICRC_ERR)
- printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
+ printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
if (err & ECC_ERR) printk("UncorrectableError ");
if (err & ID_ERR) printk("SectorIdNotFound ");
if (err & TRK0_ERR) printk("TrackZeroNotFound ");
@@ -546,8 +543,8 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
printk(", sector=%llu",
(unsigned long long)HWGROUP(drive)->rq->sector);
}
+ printk("\n");
}
- printk("\n");
ide_dump_opcode(drive);
local_irq_restore(flags);
return err;
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 978d27d6452..aac59751e1b 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -46,7 +46,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *ide_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &ide_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -497,6 +491,7 @@ static struct pcmcia_driver ide_cs_driver = {
.name = "ide-cs",
},
.attach = ide_attach,
+ .event = ide_event,
.detach = ide_detach,
.id_table = ide_ids,
};
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 67efb38a9f6..6cf49394a80 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -583,7 +583,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive)
* appropriate also sets up the 1533 southbridge.
*/
-static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
{
unsigned long flags;
u8 tmpbyte;
@@ -677,7 +677,7 @@ static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char
* FIXME: frobs bits that are not defined on newer ALi devicea
*/
-static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
unsigned int ata66 = 0;
@@ -748,7 +748,7 @@ static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
* Initialize the IDE structure side of the ALi 15x3 driver.
*/
-static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->tuneproc = &ali15x3_tune_drive;
@@ -794,7 +794,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
* Sparc systems
*/
-static void __init init_hwif_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
{
u8 ideic, inmir;
s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
@@ -847,7 +847,7 @@ static void __init init_hwif_ali15x3 (ide_hwif_t *hwif)
* the actual work.
*/
-static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
{
if (m5229_revision < 0x20)
return;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 4e0f13d1d06..844a6c9fb94 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -73,6 +73,7 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
{ 0 }
};
@@ -309,7 +310,7 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive)
* and initialize its drive independent registers.
*/
-static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name)
{
unsigned char t;
unsigned int u;
@@ -413,7 +414,7 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char
return dev->irq;
}
-static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
+static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
{
int i;
@@ -489,6 +490,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
/* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
/* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
+ /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -524,6 +526,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 0381961db26..09269e574b3 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -217,7 +217,7 @@ static int cs5530_config_dma (ide_drive_t *drive)
* Initialize the cs5530 bridge for reliable IDE DMA operation.
*/
-static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
unsigned long flags;
@@ -308,7 +308,7 @@ static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char
* performs channel-specific pre-initialization before drive probing.
*/
-static void __init init_hwif_cs5530 (ide_hwif_t *hwif)
+static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
{
unsigned long basereg;
u32 d0_timings;
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 80d67e99ccb..5a33513f3dd 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -391,7 +391,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
/*
* this function is called during init and is used to setup the cy82c693 chip
*/
-static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name)
{
if (PCI_FUNC(dev->devfn) != 1)
return 0;
@@ -443,7 +443,7 @@ static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char
/*
* the init function - called for each ide channel once
*/
-static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
{
hwif->autodma = 0;
@@ -467,9 +467,9 @@ static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
hwif->drives[1].autodma = hwif->autodma;
}
-static __initdata ide_hwif_t *primary;
+static __devinitdata ide_hwif_t *primary;
-void __init init_iops_cy82c693(ide_hwif_t *hwif)
+void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
{
if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
primary = hwif;
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
index 631927cf17d..93462926b9d 100644
--- a/drivers/ide/pci/it8172.c
+++ b/drivers/ide/pci/it8172.c
@@ -216,7 +216,7 @@ fast_ata_pio:
return 0;
}
-static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name)
{
unsigned char progif;
@@ -230,7 +230,7 @@ static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char
}
-static void __init init_hwif_it8172 (ide_hwif_t *hwif)
+static void __devinit init_hwif_it8172 (ide_hwif_t *hwif)
{
struct pci_dev* dev = hwif->pci_dev;
unsigned long cmdBase, ctrlBase;
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 205a32fbc2f..fcd5142f5cf 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -195,7 +195,7 @@ static int ns87415_ide_dma_check (ide_drive_t *drive)
return __ide_dma_check(drive);
}
-static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
unsigned int ctrl, using_inta;
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index cf4fd91d396..7a7c2ef78ac 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -326,7 +326,7 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio)
/*
* init_hwif_opti621() is called once for each hwif found at boot.
*/
-static void __init init_hwif_opti621 (ide_hwif_t *hwif)
+static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->drives[0].drive_data = PIO_DONT_KNOW;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 3bc3bf1be49..10592cec6c4 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -459,7 +459,7 @@ printk("%s: SC1200: resume\n", hwif->name);
* This gets invoked by the IDE driver once for each channel,
* and performs channel-specific pre-initialization before drive probing.
*/
-static void __init init_hwif_sc1200 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
{
if (hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 1d970a0de21..ea0806c82be 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -386,7 +386,7 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
* channel 0 here at least, but channel 1 has to be enabled by
* firmware or arch code. We still set both to 16 bits mode.
*/
-static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
+static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
{
u32 val;
@@ -399,7 +399,7 @@ static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char
return dev->irq;
}
-static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
+static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
{
unsigned int rev;
u8 dma_state;
@@ -431,7 +431,7 @@ static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
* Initialise the chip
*/
-static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
+static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
u32 val;
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 7fbf36342f7..5112c726633 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -196,7 +196,7 @@ fast_ata_pio:
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
-static void __init init_hwif_slc90e66 (ide_hwif_t *hwif)
+static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
{
u8 reg47 = 0;
u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index a1df2bfe363..f96b56838f3 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -130,7 +130,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
return hwif->ide_dma_off_quietly(drive);
}
-static void __init init_hwif_triflex(ide_hwif_t *hwif)
+static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
{
hwif->tuneproc = &triflex_tune_drive;
hwif->speedproc = &triflex_tune_chipset;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 069dbffe211..a4d099c937f 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -415,7 +415,7 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
* and initialize its drive independent registers.
*/
-static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
{
struct pci_dev *isa = NULL;
u8 t, v;
@@ -576,7 +576,7 @@ static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const cha
return 0;
}
-static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
+static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
{
int i;
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 818380b5fd2..be0fcc8f4b1 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1419,7 +1419,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
* Attach to a macio probed interface
*/
static int __devinit
-pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match)
+pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
void __iomem *base;
unsigned long regbase;
@@ -1637,27 +1637,19 @@ pmac_ide_pci_resume(struct pci_dev *pdev)
return rc;
}
-static struct of_match pmac_ide_macio_match[] =
+static struct of_device_id pmac_ide_macio_match[] =
{
{
.name = "IDE",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
.name = "ATA",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
- .name = OF_ANY_MATCH,
.type = "ide",
- .compatible = OF_ANY_MATCH
},
{
- .name = OF_ANY_MATCH,
.type = "ata",
- .compatible = OF_ANY_MATCH
},
{},
};
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index e501675ad72..77da827b289 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -847,7 +847,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev)
d = list_entry(l, struct pci_driver, node);
if(d->id_table)
{
- const struct pci_device_id *id = pci_match_device(d->id_table, dev);
+ const struct pci_device_id *id = pci_match_id(d->id_table, dev);
if(id != NULL)
{
if(d->probe(dev, id) >= 0)
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 7d58af1ae30..25103a0ef9b 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -66,6 +66,18 @@ config IEEE1394_CONFIG_ROM_IP1394
with MacOSX and WinXP IP-over-1394), enable this option and the
eth1394 option below.
+config IEEE1394_EXPORT_FULL_API
+ bool "Export all symbols of ieee1394's API"
+ depends on IEEE1394
+ default n
+ help
+ Export all symbols of ieee1394's driver programming interface, even
+ those that are not currently used by the standard IEEE 1394 drivers.
+
+ This option does not affect the interface to userspace applications.
+ Say Y here if you want to compile externally developed drivers that
+ make extended use of ieee1394's API. It is otherwise safe to say N.
+
comment "Device Drivers"
depends on IEEE1394
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
index 1b98684aebc..149573db91c 100644
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -28,6 +28,7 @@
#include "hosts.h"
#include "ieee1394.h"
#include "highlevel.h"
+#include "ieee1394_core.h"
/* Module Parameters */
/* this module parameter can be used to disable mapping of the FCP registers */
@@ -232,7 +233,7 @@ static void add_host(struct hpsb_host *host)
host->csr.generation = 2;
bus_info[1] = __constant_cpu_to_be32(0x31333934);
- bus_info[2] = cpu_to_be32((1 << CSR_IRMC_SHIFT) |
+ bus_info[2] = cpu_to_be32((hpsb_disable_irm ? 0 : 1 << CSR_IRMC_SHIFT) |
(1 << CSR_CMC_SHIFT) |
(1 << CSR_ISC_SHIFT) |
(0 << CSR_BMC_SHIFT) |
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index 7c4330e2e87..61ddd5d37ef 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -209,7 +209,15 @@ void csr1212_init_local_csr(struct csr1212_csr *csr,
{
static const int mr_map[] = { 4, 64, 1024, 0 };
+#ifdef __KERNEL__
+ BUG_ON(max_rom & ~0x3);
csr->max_rom = mr_map[max_rom];
+#else
+ if (max_rom & ~0x3) /* caller supplied invalid argument */
+ csr->max_rom = 0;
+ else
+ csr->max_rom = mr_map[max_rom];
+#endif
memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
}
@@ -533,12 +541,15 @@ struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
static const int pd[4] = { 0, 4, 16, 256 };
static const int cs[16] = { 4, 2 };
struct csr1212_keyval *kv;
- int palette_size = pd[palette_depth] * cs[color_space];
+ int palette_size;
int pixel_size = (hscan * vscan + 3) & ~0x3;
- if ((palette_depth && !palette) || !pixels)
+ if (!pixels || (!palette && palette_depth) ||
+ (palette_depth & ~0x3) || (color_space & ~0xf))
return NULL;
+ palette_size = pd[palette_depth] * cs[color_space];
+
kv = csr1212_new_descriptor_leaf(1, 0, NULL,
palette_size + pixel_size +
CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
@@ -760,9 +771,9 @@ static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
struct csr1212_csr_rom_cache *cache;
u_int64_t csr_addr;
- if (!csr || !csr->ops->allocate_addr_range ||
- !csr->ops->release_addr)
- return CSR1212_ENOMEM;
+ if (!csr || !csr->ops || !csr->ops->allocate_addr_range ||
+ !csr->ops->release_addr || csr->max_rom < 1)
+ return CSR1212_EINVAL;
/* ROM size must be a multiple of csr->max_rom */
romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
@@ -1145,6 +1156,8 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
/* Make sure the Extended ROM leaf is a multiple of
* max_rom in size. */
+ if (csr->max_rom < 1)
+ return CSR1212_EINVAL;
leaf_size = (cache->len + (csr->max_rom - 1)) &
~(csr->max_rom - 1);
@@ -1409,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
u_int32_t *cache_ptr;
u_int16_t kv_len = 0;
- if (!csr || !kv)
+ if (!csr || !kv || csr->max_rom < 1)
return CSR1212_EINVAL;
/* First find which cache the data should be in (or go in if not read
@@ -1572,7 +1585,7 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
struct csr1212_dentry *dentry;
int ret;
- if (!csr || !csr->ops->bus_read)
+ if (!csr || !csr->ops || !csr->ops->bus_read)
return CSR1212_EINVAL;
ret = csr1212_parse_bus_info_block(csr);
@@ -1581,9 +1594,13 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
if (!csr->ops->get_max_rom)
csr->max_rom = mr_map[0]; /* default value */
- else
- csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
- csr->private)];
+ else {
+ int i = csr->ops->get_max_rom(csr->bus_info_data,
+ csr->private);
+ if (i & ~0x3)
+ return CSR1212_EINVAL;
+ csr->max_rom = mr_map[i];
+ }
csr->cache_head->layout_head = csr->root_kv;
csr->cache_head->layout_tail = csr->root_kv;
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 758819d1999..b79ddb43e74 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -158,7 +158,7 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
{
- unsigned long rem;
+ unsigned long rem = 0;
struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
return sg_dma_address(sg) + rem;
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 654da76bf81..cd53c174ced 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata =
- "$Rev: 1247 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1264 $ Ben Collins <bcollins@debian.org>";
struct fragment_info {
struct list_head list;
@@ -706,7 +706,7 @@ static void ether1394_host_reset (struct hpsb_host *host)
return;
dev = hi->dev;
- priv = netdev_priv(dev);
+ priv = (struct eth1394_priv *)netdev_priv(dev);
/* Reset our private host data, but not our mtu */
netif_stop_queue (dev);
@@ -1770,7 +1770,7 @@ fail:
static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strcpy (info->driver, driver_name);
- strcpy (info->version, "$Rev: 1247 $");
+ strcpy (info->version, "$Rev: 1264 $");
/* FIXME XXX provide sane businfo */
strcpy (info->bus_info, "ieee1394");
}
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 629070b83a3..b248d89de8b 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -52,7 +52,7 @@
/*
* Disable the nodemgr detection and config rom reading functionality.
*/
-static int disable_nodemgr = 0;
+static int disable_nodemgr;
module_param(disable_nodemgr, int, 0444);
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
@@ -520,6 +520,9 @@ int hpsb_send_packet(struct hpsb_packet *packet)
if (!packet->no_waiter || packet->expect_response) {
atomic_inc(&packet->refcnt);
+ /* Set the initial "sendtime" to 10 seconds from now, to
+ prevent premature expiry. If a packet takes more than
+ 10 seconds to hit the wire, we have bigger problems :) */
packet->sendtime = jiffies + 10 * HZ;
skb_queue_tail(&host->pending_packet_queue, packet->skb);
}
@@ -1223,9 +1226,7 @@ EXPORT_SYMBOL(hpsb_protocol_class);
EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(hpsb_alloc_packet);
EXPORT_SYMBOL(hpsb_free_packet);
-EXPORT_SYMBOL(hpsb_send_phy_config);
EXPORT_SYMBOL(hpsb_send_packet);
-EXPORT_SYMBOL(hpsb_send_packet_and_wait);
EXPORT_SYMBOL(hpsb_reset_bus);
EXPORT_SYMBOL(hpsb_bus_reset);
EXPORT_SYMBOL(hpsb_selfid_received);
@@ -1233,6 +1234,10 @@ EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL_GPL(hpsb_disable_irm);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(hpsb_send_phy_config);
+EXPORT_SYMBOL(hpsb_send_packet_and_wait);
+#endif
/** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel);
@@ -1262,9 +1267,11 @@ EXPORT_SYMBOL(hpsb_destroy_hostinfo);
EXPORT_SYMBOL(hpsb_set_hostinfo_key);
EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
EXPORT_SYMBOL(hpsb_set_hostinfo);
+EXPORT_SYMBOL(highlevel_host_reset);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
EXPORT_SYMBOL(highlevel_add_host);
EXPORT_SYMBOL(highlevel_remove_host);
-EXPORT_SYMBOL(highlevel_host_reset);
+#endif
/** nodemgr.c **/
EXPORT_SYMBOL(hpsb_node_fill_packet);
@@ -1272,7 +1279,9 @@ EXPORT_SYMBOL(hpsb_node_write);
EXPORT_SYMBOL(hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol);
EXPORT_SYMBOL(ieee1394_bus_type);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
EXPORT_SYMBOL(nodemgr_for_each_host);
+#endif
/** csr.c **/
EXPORT_SYMBOL(hpsb_update_config_rom);
@@ -1309,19 +1318,21 @@ EXPORT_SYMBOL(hpsb_iso_wake);
EXPORT_SYMBOL(hpsb_iso_recv_flush);
/** csr1212.c **/
-EXPORT_SYMBOL(csr1212_create_csr);
-EXPORT_SYMBOL(csr1212_init_local_csr);
-EXPORT_SYMBOL(csr1212_new_immediate);
EXPORT_SYMBOL(csr1212_new_directory);
-EXPORT_SYMBOL(csr1212_associate_keyval);
EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
-EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
EXPORT_SYMBOL(csr1212_release_keyval);
-EXPORT_SYMBOL(csr1212_destroy_csr);
EXPORT_SYMBOL(csr1212_read);
-EXPORT_SYMBOL(csr1212_generate_csr_image);
EXPORT_SYMBOL(csr1212_parse_keyval);
-EXPORT_SYMBOL(csr1212_parse_csr);
EXPORT_SYMBOL(_csr1212_read_keyval);
EXPORT_SYMBOL(_csr1212_destroy_keyval);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(csr1212_create_csr);
+EXPORT_SYMBOL(csr1212_init_local_csr);
+EXPORT_SYMBOL(csr1212_new_immediate);
+EXPORT_SYMBOL(csr1212_associate_keyval);
+EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
+EXPORT_SYMBOL(csr1212_destroy_csr);
+EXPORT_SYMBOL(csr1212_generate_csr_image);
+EXPORT_SYMBOL(csr1212_parse_csr);
+#endif
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 73bd8efd2b6..0b31429d0a6 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -38,8 +38,8 @@ struct hpsb_packet {
/* These are core internal. */
signed char tlabel;
- char ack_code;
- char tcode;
+ signed char ack_code;
+ unsigned char tcode;
unsigned expect_response:1;
unsigned no_waiter:1;
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index f05759107f7..615541b8b90 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -62,10 +62,10 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
dma_mode=HPSB_ISO_DMA_DEFAULT;
+ if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
+ irq_interval = buf_packets / 4;
if (irq_interval == 0) /* really interrupt for each packet*/
irq_interval = 1;
- else if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
- irq_interval = buf_packets / 4;
if (channel < -1 || channel >= 64)
return NULL;
@@ -106,6 +106,7 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
}
atomic_set(&iso->overflows, 0);
+ iso->bytes_discarded = 0;
iso->flags = 0;
iso->prebuffer = 0;
@@ -241,12 +242,12 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
iso->xmit_cycle = cycle;
if (prebuffer < 0)
- prebuffer = iso->buf_packets;
+ prebuffer = iso->buf_packets - 1;
else if (prebuffer == 0)
prebuffer = 1;
- if (prebuffer > iso->buf_packets)
- prebuffer = iso->buf_packets;
+ if (prebuffer >= iso->buf_packets)
+ prebuffer = iso->buf_packets - 1;
iso->prebuffer = prebuffer;
@@ -395,7 +396,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
}
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 cycle, u8 channel, u8 tag, u8 sy)
+ u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
{
unsigned long flags;
spin_lock_irqsave(&iso->lock, flags);
@@ -403,10 +404,13 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
if (iso->n_ready_packets == iso->buf_packets) {
/* overflow! */
atomic_inc(&iso->overflows);
+ /* Record size of this discarded packet */
+ iso->bytes_discarded += total_len;
} else {
struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
info->offset = offset;
info->len = len;
+ info->total_len = total_len;
info->cycle = cycle;
info->channel = channel;
info->tag = tag;
@@ -437,6 +441,17 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
iso->n_ready_packets--;
+
+ /* release memory from packets discarded when queue was full */
+ if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+ if (iso->bytes_discarded != 0) {
+ struct hpsb_iso_packet_info inf;
+ inf.total_len = iso->bytes_discarded;
+ iso->host->driver->isoctl(iso, RECV_RELEASE,
+ (unsigned long) &inf);
+ iso->bytes_discarded = 0;
+ }
+ }
}
spin_unlock_irqrestore(&iso->lock, flags);
return rv;
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index fb654d9639a..3efc60b33a8 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -47,6 +47,14 @@ struct hpsb_iso_packet_info {
/* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
__u8 tag;
__u8 sy;
+
+ /*
+ * length in bytes of the packet including header/trailer.
+ * MUST be at structure end, since the first part of this structure is also
+ * defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to
+ * userspace and is accessed there through libraw1394.
+ */
+ __u16 total_len;
};
enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
@@ -111,6 +119,9 @@ struct hpsb_iso {
/* how many times the buffer has overflowed or underflowed */
atomic_t overflows;
+ /* Current number of bytes lost in discarded packets */
+ int bytes_discarded;
+
/* private flags to track initialization progress */
#define HPSB_ISO_DRIVER_INIT (1<<0)
#define HPSB_ISO_DRIVER_STARTED (1<<1)
@@ -193,7 +204,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
/* call after a packet has been received (interrupt context OK) */
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 cycle, u8 channel, u8 tag, u8 sy);
+ u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy);
/* call to wake waiting processes after buffer space has opened up. */
void hpsb_iso_wake(struct hpsb_iso *iso);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 9a46c3b44bf..bebcc47ab06 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -30,7 +30,7 @@
#include "csr.h"
#include "nodemgr.h"
-static int ignore_drivers = 0;
+static int ignore_drivers;
module_param(ignore_drivers, int, 0444);
MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index b3d3d22fde6..a485f47bb21 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
static char version[] __devinitdata =
- "$Rev: 1250 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1299 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
@@ -483,7 +483,9 @@ static void ohci_initialize(struct ti_ohci *ohci)
/* Put some defaults to these undefined bus options */
buf = reg_read(ohci, OHCI1394_BusOptions);
buf |= 0x60000000; /* Enable CMC and ISC */
- if (!hpsb_disable_irm)
+ if (hpsb_disable_irm)
+ buf &= ~0x80000000;
+ else
buf |= 0x80000000; /* Enable IRMC */
buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
buf &= ~0x18000000; /* Disable PMC and BMC */
@@ -503,8 +505,12 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_LinkControlSet,
OHCI1394_LinkControl_CycleTimerEnable |
OHCI1394_LinkControl_CycleMaster);
- set_phy_reg_mask(ohci, 4, PHY_04_LCTRL |
- (hpsb_disable_irm ? 0 : PHY_04_CONTENDER));
+ i = get_phy_reg(ohci, 4) | PHY_04_LCTRL;
+ if (hpsb_disable_irm)
+ i &= ~PHY_04_CONTENDER;
+ else
+ i |= PHY_04_CONTENDER;
+ set_phy_reg(ohci, 4, i);
/* Set up self-id dma buffer */
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
@@ -1566,6 +1572,10 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
struct dma_cmd *next = &recv->block[next_i];
struct dma_cmd *prev = &recv->block[prev_i];
+
+ /* ignore out-of-range requests */
+ if ((block < 0) || (block > recv->nblocks))
+ return;
/* 'next' becomes the new end of the DMA chain,
so disable branch and enable interrupt */
@@ -1593,19 +1603,8 @@ static void ohci_iso_recv_release_block(struct ohci_iso_recv *recv, int block)
static void ohci_iso_recv_bufferfill_release(struct ohci_iso_recv *recv,
struct hpsb_iso_packet_info *info)
{
- int len;
-
/* release the memory where the packet was */
- len = info->len;
-
- /* add the wasted space for padding to 4 bytes */
- if (len % 4)
- len += 4 - (len % 4);
-
- /* add 8 bytes for the OHCI DMA data format overhead */
- len += 8;
-
- recv->released_bytes += len;
+ recv->released_bytes += info->total_len;
/* have we released enough memory for one block? */
while (recv->released_bytes > recv->buf_stride) {
@@ -1637,7 +1636,7 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
/* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */
unsigned int offset;
- unsigned short len, cycle;
+ unsigned short len, cycle, total_len;
unsigned char channel, tag, sy;
unsigned char *p = iso->data_buf.kvirt;
@@ -1688,9 +1687,11 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
/* advance to xferStatus/timeStamp */
recv->dma_offset += len;
+ total_len = len + 8; /* 8 bytes header+trailer in OHCI packet */
/* payload is padded to 4 bytes */
if (len % 4) {
recv->dma_offset += 4 - (len%4);
+ total_len += 4 - (len%4);
}
/* check for wrap-around */
@@ -1724,7 +1725,7 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
recv->dma_offset -= recv->buf_stride*recv->nblocks;
}
- hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy);
+ hpsb_iso_packet_received(iso, offset, len, total_len, cycle, channel, tag, sy);
}
if (wake)
@@ -1850,7 +1851,8 @@ static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_is
tag = hdr[5] >> 6;
sy = hdr[4] & 0xF;
- hpsb_iso_packet_received(iso, offset, packet_len, cycle, channel, tag, sy);
+ hpsb_iso_packet_received(iso, offset, packet_len,
+ recv->buf_stride, cycle, channel, tag, sy);
}
/* reset the DMA descriptor */
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index bdb3a85cafa..36074e6eeeb 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -76,7 +76,7 @@
/* Module Parameters */
-static int skip_eeprom = 0;
+static int skip_eeprom;
module_param(skip_eeprom, int, 0444);
MODULE_PARM_DESC(skip_eeprom, "Use generic bus info block instead of serial eeprom (default = 0).");
@@ -1422,7 +1422,7 @@ static int __devinit add_card(struct pci_dev *dev,
i = get_phy_reg(lynx, 4);
i |= PHY_04_LCTRL;
if (hpsb_disable_irm)
- i &= !PHY_04_CONTENDER;
+ i &= ~PHY_04_CONTENDER;
else
i |= PHY_04_CONTENDER;
if (i != -1) set_phy_reg(lynx, 4, i);
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 7419af450bd..b4fa14793fe 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -98,7 +98,7 @@ static struct hpsb_address_ops arm_ops = {
static void queue_complete_cb(struct pending_request *req);
-static struct pending_request *__alloc_pending_request(int flags)
+static struct pending_request *__alloc_pending_request(unsigned int __nocast flags)
{
struct pending_request *req;
@@ -2506,9 +2506,12 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user * uaddr)
if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
return -EFAULT;
- if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
+ if (upackets.n_packets >= fi->iso_handle->buf_packets)
return -EINVAL;
+ if (upackets.n_packets >= hpsb_iso_n_ready(fi->iso_handle))
+ return -EAGAIN;
+
/* ensure user-supplied buffer is accessible and big enough */
if (!access_ok(VERIFY_READ, upackets.infos,
upackets.n_packets *
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 32368f3428e..fe3e1703fa6 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -81,7 +81,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
- "$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1306 $ Ben Collins <bcollins@debian.org>";
/*
* Module load parameter definitions
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 =
* down to us at a time (debugging). This might be necessary for very
* badly behaved sbp2 devices.
*/
-static int serialize_io = 0;
+static int serialize_io;
module_param(serialize_io, int, 0444);
MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)"
* please submit the logged sbp2_firmware_revision value of this device to
* the linux1394-devel mailing list.
*/
-static int force_inquiry_hack = 0;
+static int force_inquiry_hack;
module_param(force_inquiry_hack, int, 0444);
MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
@@ -2112,6 +2112,102 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
{
+ unchar new_cmd[16];
+ u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
+
+ SBP2_DEBUG("sbp2_check_sbp2_command");
+
+ switch (*cmd) {
+
+ case READ_6:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert READ_6 to READ_10");
+
+ /*
+ * Need to turn read_6 into read_10
+ */
+ new_cmd[0] = 0x28;
+ new_cmd[1] = (cmd[1] & 0xe0);
+ new_cmd[2] = 0x0;
+ new_cmd[3] = (cmd[1] & 0x1f);
+ new_cmd[4] = cmd[2];
+ new_cmd[5] = cmd[3];
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case WRITE_6:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
+
+ /*
+ * Need to turn write_6 into write_10
+ */
+ new_cmd[0] = 0x2a;
+ new_cmd[1] = (cmd[1] & 0xe0);
+ new_cmd[2] = 0x0;
+ new_cmd[3] = (cmd[1] & 0x1f);
+ new_cmd[4] = cmd[2];
+ new_cmd[5] = cmd[3];
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case MODE_SENSE:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
+
+ /*
+ * Need to turn mode_sense_6 into mode_sense_10
+ */
+ new_cmd[0] = 0x5a;
+ new_cmd[1] = cmd[1];
+ new_cmd[2] = cmd[2];
+ new_cmd[3] = 0x0;
+ new_cmd[4] = 0x0;
+ new_cmd[5] = 0x0;
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case MODE_SELECT:
+
+ /*
+ * TODO. Probably need to change mode select to 10 byte version
+ */
+
+ default:
+ break;
+ }
+
+ return;
}
/*
@@ -2152,6 +2248,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt)
{
u8 *scsi_buf = SCpnt->request_buffer;
+ u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_response");
@@ -2176,6 +2273,14 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
}
/*
+ * Check for Simple Direct Access Device and change it to TYPE_DISK
+ */
+ if ((scsi_buf[0] & 0x1f) == TYPE_RBC) {
+ SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK");
+ scsi_buf[0] &= 0xe0;
+ }
+
+ /*
* Fix ansi revision and response data format
*/
scsi_buf[2] |= 2;
@@ -2183,6 +2288,27 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
break;
+ case MODE_SENSE:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Modify mode sense response (10 byte version)");
+
+ scsi_buf[0] = scsi_buf[1]; /* Mode data length */
+ scsi_buf[1] = scsi_buf[2]; /* Medium type */
+ scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */
+ scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */
+ memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
+ }
+
+ break;
+
+ case MODE_SELECT:
+
+ /*
+ * TODO. Probably need to change mode select to 10 byte version
+ */
+
default:
break;
}
@@ -2559,8 +2685,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static int sbp2scsi_slave_configure (struct scsi_device *sdev)
{
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
- sdev->use_10_for_rw = 1;
- sdev->use_10_for_ms = 1;
+
return 0;
}
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 3cc3ff0cccb..79c8e2dd9c3 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -7,6 +7,16 @@ config INFINIBAND
any protocols you wish to use as well as drivers for your
InfiniBand hardware.
+config INFINIBAND_USER_VERBS
+ tristate "InfiniBand userspace verbs support"
+ depends on INFINIBAND
+ ---help---
+ Userspace InfiniBand verbs support. This is the kernel side
+ of userspace verbs, which allows userspace processes to
+ directly access InfiniBand hardware for fast-path
+ operations. You will also need libibverbs and a hardware
+ driver library from <http://www.openib.org>.
+
source "drivers/infiniband/hw/mthca/Kconfig"
source "drivers/infiniband/ulp/ipoib/Kconfig"
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index d2dbfb52c0a..e1a7cf3e863 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,6 +1,7 @@
EXTRA_CFLAGS += -Idrivers/infiniband/include
-obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o ib_umad.o
+obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o ib_umad.o
+obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o
ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
device.o fmr_pool.o cache.o
@@ -10,3 +11,5 @@ ib_mad-y := mad.o smi.o agent.o
ib_sa-y := sa_query.o
ib_umad-y := user_mad.o
+
+ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
new file mode 100644
index 00000000000..57347f1e82c
--- /dev/null
+++ b/drivers/infiniband/core/uverbs.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: uverbs.h 2559 2005-06-06 19:43:16Z roland $
+ */
+
+#ifndef UVERBS_H
+#define UVERBS_H
+
+/* Include device.h and fs.h until cdev.h is self-sufficient */
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/kref.h>
+#include <linux/idr.h>
+
+#include <ib_verbs.h>
+#include <ib_user_verbs.h>
+
+struct ib_uverbs_device {
+ int devnum;
+ struct cdev dev;
+ struct class_device class_dev;
+ struct ib_device *ib_dev;
+ int num_comp;
+};
+
+struct ib_uverbs_event_file {
+ struct kref ref;
+ struct ib_uverbs_file *uverbs_file;
+ spinlock_t lock;
+ int fd;
+ int is_async;
+ wait_queue_head_t poll_wait;
+ struct list_head event_list;
+};
+
+struct ib_uverbs_file {
+ struct kref ref;
+ struct ib_uverbs_device *device;
+ struct ib_ucontext *ucontext;
+ struct ib_event_handler event_handler;
+ struct ib_uverbs_event_file async_file;
+ struct ib_uverbs_event_file comp_file[1];
+};
+
+struct ib_uverbs_async_event {
+ struct ib_uverbs_async_event_desc desc;
+ struct list_head list;
+};
+
+struct ib_uverbs_comp_event {
+ struct ib_uverbs_comp_event_desc desc;
+ struct list_head list;
+};
+
+struct ib_uobject_mr {
+ struct ib_uobject uobj;
+ struct page *page_list;
+ struct scatterlist *sg_list;
+};
+
+extern struct semaphore ib_uverbs_idr_mutex;
+extern struct idr ib_uverbs_pd_idr;
+extern struct idr ib_uverbs_mr_idr;
+extern struct idr ib_uverbs_mw_idr;
+extern struct idr ib_uverbs_ah_idr;
+extern struct idr ib_uverbs_cq_idr;
+extern struct idr ib_uverbs_qp_idr;
+
+void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
+void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
+void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
+
+int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
+ void *addr, size_t size, int write);
+void ib_umem_release(struct ib_device *dev, struct ib_umem *umem);
+void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem);
+
+#define IB_UVERBS_DECLARE_CMD(name) \
+ ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \
+ const char __user *buf, int in_len, \
+ int out_len)
+
+IB_UVERBS_DECLARE_CMD(query_params);
+IB_UVERBS_DECLARE_CMD(get_context);
+IB_UVERBS_DECLARE_CMD(query_device);
+IB_UVERBS_DECLARE_CMD(query_port);
+IB_UVERBS_DECLARE_CMD(query_gid);
+IB_UVERBS_DECLARE_CMD(query_pkey);
+IB_UVERBS_DECLARE_CMD(alloc_pd);
+IB_UVERBS_DECLARE_CMD(dealloc_pd);
+IB_UVERBS_DECLARE_CMD(reg_mr);
+IB_UVERBS_DECLARE_CMD(dereg_mr);
+IB_UVERBS_DECLARE_CMD(create_cq);
+IB_UVERBS_DECLARE_CMD(destroy_cq);
+IB_UVERBS_DECLARE_CMD(create_qp);
+IB_UVERBS_DECLARE_CMD(modify_qp);
+IB_UVERBS_DECLARE_CMD(destroy_qp);
+IB_UVERBS_DECLARE_CMD(attach_mcast);
+IB_UVERBS_DECLARE_CMD(detach_mcast);
+
+#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
new file mode 100644
index 00000000000..5f2bbcda4c7
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
+ */
+
+#include <asm/uaccess.h>
+
+#include "uverbs.h"
+
+#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
+ do { \
+ (udata)->inbuf = (void __user *) (ibuf); \
+ (udata)->outbuf = (void __user *) (obuf); \
+ (udata)->inlen = (ilen); \
+ (udata)->outlen = (olen); \
+ } while (0)
+
+ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_query_params cmd;
+ struct ib_uverbs_query_params_resp resp;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ memset(&resp, 0, sizeof resp);
+
+ resp.num_cq_events = file->device->num_comp;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
+ return -EFAULT;
+
+ return in_len;
+}
+
+ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_get_context cmd;
+ struct ib_uverbs_get_context_resp resp;
+ struct ib_udata udata;
+ struct ib_device *ibdev = file->device->ib_dev;
+ int i;
+ int ret = in_len;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ INIT_UDATA(&udata, buf + sizeof cmd,
+ (unsigned long) cmd.response + sizeof resp,
+ in_len - sizeof cmd, out_len - sizeof resp);
+
+ file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
+ if (IS_ERR(file->ucontext)) {
+ ret = PTR_ERR(file->ucontext);
+ file->ucontext = NULL;
+ return ret;
+ }
+
+ file->ucontext->device = ibdev;
+ INIT_LIST_HEAD(&file->ucontext->pd_list);
+ INIT_LIST_HEAD(&file->ucontext->mr_list);
+ INIT_LIST_HEAD(&file->ucontext->mw_list);
+ INIT_LIST_HEAD(&file->ucontext->cq_list);
+ INIT_LIST_HEAD(&file->ucontext->qp_list);
+ INIT_LIST_HEAD(&file->ucontext->srq_list);
+ INIT_LIST_HEAD(&file->ucontext->ah_list);
+ spin_lock_init(&file->ucontext->lock);
+
+ resp.async_fd = file->async_file.fd;
+ for (i = 0; i < file->device->num_comp; ++i)
+ if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
+ i * sizeof (__u32),
+ &file->comp_file[i].fd, sizeof (__u32)))
+ goto err;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ goto err;
+
+ return in_len;
+
+err:
+ ibdev->dealloc_ucontext(file->ucontext);
+ file->ucontext = NULL;
+
+ return -EFAULT;
+}
+
+ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_query_device cmd;
+ struct ib_uverbs_query_device_resp resp;
+ struct ib_device_attr attr;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ ret = ib_query_device(file->device->ib_dev, &attr);
+ if (ret)
+ return ret;
+
+ memset(&resp, 0, sizeof resp);
+
+ resp.fw_ver = attr.fw_ver;
+ resp.node_guid = attr.node_guid;
+ resp.sys_image_guid = attr.sys_image_guid;
+ resp.max_mr_size = attr.max_mr_size;
+ resp.page_size_cap = attr.page_size_cap;
+ resp.vendor_id = attr.vendor_id;
+ resp.vendor_part_id = attr.vendor_part_id;
+ resp.hw_ver = attr.hw_ver;
+ resp.max_qp = attr.max_qp;
+ resp.max_qp_wr = attr.max_qp_wr;
+ resp.device_cap_flags = attr.device_cap_flags;
+ resp.max_sge = attr.max_sge;
+ resp.max_sge_rd = attr.max_sge_rd;
+ resp.max_cq = attr.max_cq;
+ resp.max_cqe = attr.max_cqe;
+ resp.max_mr = attr.max_mr;
+ resp.max_pd = attr.max_pd;
+ resp.max_qp_rd_atom = attr.max_qp_rd_atom;
+ resp.max_ee_rd_atom = attr.max_ee_rd_atom;
+ resp.max_res_rd_atom = attr.max_res_rd_atom;
+ resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom;
+ resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom;
+ resp.atomic_cap = attr.atomic_cap;
+ resp.max_ee = attr.max_ee;
+ resp.max_rdd = attr.max_rdd;
+ resp.max_mw = attr.max_mw;
+ resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp;
+ resp.max_raw_ethy_qp = attr.max_raw_ethy_qp;
+ resp.max_mcast_grp = attr.max_mcast_grp;
+ resp.max_mcast_qp_attach = attr.max_mcast_qp_attach;
+ resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
+ resp.max_ah = attr.max_ah;
+ resp.max_fmr = attr.max_fmr;
+ resp.max_map_per_fmr = attr.max_map_per_fmr;
+ resp.max_srq = attr.max_srq;
+ resp.max_srq_wr = attr.max_srq_wr;
+ resp.max_srq_sge = attr.max_srq_sge;
+ resp.max_pkeys = attr.max_pkeys;
+ resp.local_ca_ack_delay = attr.local_ca_ack_delay;
+ resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ return -EFAULT;
+
+ return in_len;
+}
+
+ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_query_port cmd;
+ struct ib_uverbs_query_port_resp resp;
+ struct ib_port_attr attr;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr);
+ if (ret)
+ return ret;
+
+ memset(&resp, 0, sizeof resp);
+
+ resp.state = attr.state;
+ resp.max_mtu = attr.max_mtu;
+ resp.active_mtu = attr.active_mtu;
+ resp.gid_tbl_len = attr.gid_tbl_len;
+ resp.port_cap_flags = attr.port_cap_flags;
+ resp.max_msg_sz = attr.max_msg_sz;
+ resp.bad_pkey_cntr = attr.bad_pkey_cntr;
+ resp.qkey_viol_cntr = attr.qkey_viol_cntr;
+ resp.pkey_tbl_len = attr.pkey_tbl_len;
+ resp.lid = attr.lid;
+ resp.sm_lid = attr.sm_lid;
+ resp.lmc = attr.lmc;
+ resp.max_vl_num = attr.max_vl_num;
+ resp.sm_sl = attr.sm_sl;
+ resp.subnet_timeout = attr.subnet_timeout;
+ resp.init_type_reply = attr.init_type_reply;
+ resp.active_width = attr.active_width;
+ resp.active_speed = attr.active_speed;
+ resp.phys_state = attr.phys_state;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ return -EFAULT;
+
+ return in_len;
+}
+
+ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_query_gid cmd;
+ struct ib_uverbs_query_gid_resp resp;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ memset(&resp, 0, sizeof resp);
+
+ ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
+ (union ib_gid *) resp.gid);
+ if (ret)
+ return ret;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ return -EFAULT;
+
+ return in_len;
+}
+
+ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_query_pkey cmd;
+ struct ib_uverbs_query_pkey_resp resp;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ memset(&resp, 0, sizeof resp);
+
+ ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
+ &resp.pkey);
+ if (ret)
+ return ret;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ return -EFAULT;
+
+ return in_len;
+}
+
+ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_alloc_pd cmd;
+ struct ib_uverbs_alloc_pd_resp resp;
+ struct ib_udata udata;
+ struct ib_uobject *uobj;
+ struct ib_pd *pd;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ INIT_UDATA(&udata, buf + sizeof cmd,
+ (unsigned long) cmd.response + sizeof resp,
+ in_len - sizeof cmd, out_len - sizeof resp);
+
+ uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+ if (!uobj)
+ return -ENOMEM;
+
+ uobj->context = file->ucontext;
+
+ pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
+ file->ucontext, &udata);
+ if (IS_ERR(pd)) {
+ ret = PTR_ERR(pd);
+ goto err;
+ }
+
+ pd->device = file->device->ib_dev;
+ pd->uobject = uobj;
+ atomic_set(&pd->usecnt, 0);
+
+retry:
+ if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto err_pd;
+ }
+
+ down(&ib_uverbs_idr_mutex);
+ ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
+ up(&ib_uverbs_idr_mutex);
+
+ if (ret == -EAGAIN)
+ goto retry;
+ if (ret)
+ goto err_pd;
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_add_tail(&uobj->list, &file->ucontext->pd_list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ memset(&resp, 0, sizeof resp);
+ resp.pd_handle = uobj->id;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_list;
+ }
+
+ return in_len;
+
+err_list:
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ down(&ib_uverbs_idr_mutex);
+ idr_remove(&ib_uverbs_pd_idr, uobj->id);
+ up(&ib_uverbs_idr_mutex);
+
+err_pd:
+ ib_dealloc_pd(pd);
+
+err:
+ kfree(uobj);
+ return ret;
+}
+
+ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
+ const char __user *buf,
+ int in_len, int out_len)
+{
+ struct ib_uverbs_dealloc_pd cmd;
+ struct ib_pd *pd;
+ struct ib_uobject *uobj;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+ if (!pd || pd->uobject->context != file->ucontext)
+ goto out;
+
+ uobj = pd->uobject;
+
+ ret = ib_dealloc_pd(pd);
+ if (ret)
+ goto out;
+
+ idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ kfree(uobj);
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_reg_mr cmd;
+ struct ib_uverbs_reg_mr_resp resp;
+ struct ib_udata udata;
+ struct ib_umem_object *obj;
+ struct ib_pd *pd;
+ struct ib_mr *mr;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ INIT_UDATA(&udata, buf + sizeof cmd,
+ (unsigned long) cmd.response + sizeof resp,
+ in_len - sizeof cmd, out_len - sizeof resp);
+
+ if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
+ return -EINVAL;
+
+ obj = kmalloc(sizeof *obj, GFP_KERNEL);
+ if (!obj)
+ return -ENOMEM;
+
+ obj->uobject.context = file->ucontext;
+
+ /*
+ * We ask for writable memory if any access flags other than
+ * "remote read" are set. "Local write" and "remote write"
+ * obviously require write access. "Remote atomic" can do
+ * things like fetch and add, which will modify memory, and
+ * "MW bind" can change permissions by binding a window.
+ */
+ ret = ib_umem_get(file->device->ib_dev, &obj->umem,
+ (void *) (unsigned long) cmd.start, cmd.length,
+ !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));
+ if (ret)
+ goto err_free;
+
+ obj->umem.virt_base = cmd.hca_va;
+
+ down(&ib_uverbs_idr_mutex);
+
+ pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+ if (!pd || pd->uobject->context != file->ucontext) {
+ ret = -EINVAL;
+ goto err_up;
+ }
+
+ if (!pd->device->reg_user_mr) {
+ ret = -ENOSYS;
+ goto err_up;
+ }
+
+ mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
+ if (IS_ERR(mr)) {
+ ret = PTR_ERR(mr);
+ goto err_up;
+ }
+
+ mr->device = pd->device;
+ mr->pd = pd;
+ mr->uobject = &obj->uobject;
+ atomic_inc(&pd->usecnt);
+ atomic_set(&mr->usecnt, 0);
+
+ memset(&resp, 0, sizeof resp);
+ resp.lkey = mr->lkey;
+ resp.rkey = mr->rkey;
+
+retry:
+ if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto err_unreg;
+ }
+
+ ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);
+
+ if (ret == -EAGAIN)
+ goto retry;
+ if (ret)
+ goto err_unreg;
+
+ resp.mr_handle = obj->uobject.id;
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_list;
+ }
+
+ up(&ib_uverbs_idr_mutex);
+
+ return in_len;
+
+err_list:
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&obj->uobject.list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+err_unreg:
+ ib_dereg_mr(mr);
+
+err_up:
+ up(&ib_uverbs_idr_mutex);
+
+ ib_umem_release(file->device->ib_dev, &obj->umem);
+
+err_free:
+ kfree(obj);
+ return ret;
+}
+
+ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_dereg_mr cmd;
+ struct ib_mr *mr;
+ struct ib_umem_object *memobj;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
+ if (!mr || mr->uobject->context != file->ucontext)
+ goto out;
+
+ memobj = container_of(mr->uobject, struct ib_umem_object, uobject);
+
+ ret = ib_dereg_mr(mr);
+ if (ret)
+ goto out;
+
+ idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&memobj->uobject.list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ ib_umem_release(file->device->ib_dev, &memobj->umem);
+ kfree(memobj);
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_create_cq cmd;
+ struct ib_uverbs_create_cq_resp resp;
+ struct ib_udata udata;
+ struct ib_uobject *uobj;
+ struct ib_cq *cq;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ INIT_UDATA(&udata, buf + sizeof cmd,
+ (unsigned long) cmd.response + sizeof resp,
+ in_len - sizeof cmd, out_len - sizeof resp);
+
+ if (cmd.event_handler >= file->device->num_comp)
+ return -EINVAL;
+
+ uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+ if (!uobj)
+ return -ENOMEM;
+
+ uobj->user_handle = cmd.user_handle;
+ uobj->context = file->ucontext;
+
+ cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
+ file->ucontext, &udata);
+ if (IS_ERR(cq)) {
+ ret = PTR_ERR(cq);
+ goto err;
+ }
+
+ cq->device = file->device->ib_dev;
+ cq->uobject = uobj;
+ cq->comp_handler = ib_uverbs_comp_handler;
+ cq->event_handler = ib_uverbs_cq_event_handler;
+ cq->cq_context = file;
+ atomic_set(&cq->usecnt, 0);
+
+retry:
+ if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto err_cq;
+ }
+
+ down(&ib_uverbs_idr_mutex);
+ ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->id);
+ up(&ib_uverbs_idr_mutex);
+
+ if (ret == -EAGAIN)
+ goto retry;
+ if (ret)
+ goto err_cq;
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_add_tail(&uobj->list, &file->ucontext->cq_list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ memset(&resp, 0, sizeof resp);
+ resp.cq_handle = uobj->id;
+ resp.cqe = cq->cqe;
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_list;
+ }
+
+ return in_len;
+
+err_list:
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ down(&ib_uverbs_idr_mutex);
+ idr_remove(&ib_uverbs_cq_idr, uobj->id);
+ up(&ib_uverbs_idr_mutex);
+
+err_cq:
+ ib_destroy_cq(cq);
+
+err:
+ kfree(uobj);
+ return ret;
+}
+
+ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_destroy_cq cmd;
+ struct ib_cq *cq;
+ struct ib_uobject *uobj;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
+ if (!cq || cq->uobject->context != file->ucontext)
+ goto out;
+
+ uobj = cq->uobject;
+
+ ret = ib_destroy_cq(cq);
+ if (ret)
+ goto out;
+
+ idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ kfree(uobj);
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_create_qp cmd;
+ struct ib_uverbs_create_qp_resp resp;
+ struct ib_udata udata;
+ struct ib_uobject *uobj;
+ struct ib_pd *pd;
+ struct ib_cq *scq, *rcq;
+ struct ib_qp *qp;
+ struct ib_qp_init_attr attr;
+ int ret;
+
+ if (out_len < sizeof resp)
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ INIT_UDATA(&udata, buf + sizeof cmd,
+ (unsigned long) cmd.response + sizeof resp,
+ in_len - sizeof cmd, out_len - sizeof resp);
+
+ uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+ if (!uobj)
+ return -ENOMEM;
+
+ down(&ib_uverbs_idr_mutex);
+
+ pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+ scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
+ rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
+
+ if (!pd || pd->uobject->context != file->ucontext ||
+ !scq || scq->uobject->context != file->ucontext ||
+ !rcq || rcq->uobject->context != file->ucontext) {
+ ret = -EINVAL;
+ goto err_up;
+ }
+
+ attr.event_handler = ib_uverbs_qp_event_handler;
+ attr.qp_context = file;
+ attr.send_cq = scq;
+ attr.recv_cq = rcq;
+ attr.srq = NULL;
+ attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
+ attr.qp_type = cmd.qp_type;
+
+ attr.cap.max_send_wr = cmd.max_send_wr;
+ attr.cap.max_recv_wr = cmd.max_recv_wr;
+ attr.cap.max_send_sge = cmd.max_send_sge;
+ attr.cap.max_recv_sge = cmd.max_recv_sge;
+ attr.cap.max_inline_data = cmd.max_inline_data;
+
+ uobj->user_handle = cmd.user_handle;
+ uobj->context = file->ucontext;
+
+ qp = pd->device->create_qp(pd, &attr, &udata);
+ if (IS_ERR(qp)) {
+ ret = PTR_ERR(qp);
+ goto err_up;
+ }
+
+ qp->device = pd->device;
+ qp->pd = pd;
+ qp->send_cq = attr.send_cq;
+ qp->recv_cq = attr.recv_cq;
+ qp->srq = attr.srq;
+ qp->uobject = uobj;
+ qp->event_handler = attr.event_handler;
+ qp->qp_context = attr.qp_context;
+ qp->qp_type = attr.qp_type;
+ atomic_inc(&pd->usecnt);
+ atomic_inc(&attr.send_cq->usecnt);
+ atomic_inc(&attr.recv_cq->usecnt);
+ if (attr.srq)
+ atomic_inc(&attr.srq->usecnt);
+
+ memset(&resp, 0, sizeof resp);
+ resp.qpn = qp->qp_num;
+
+retry:
+ if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto err_destroy;
+ }
+
+ ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->id);
+
+ if (ret == -EAGAIN)
+ goto retry;
+ if (ret)
+ goto err_destroy;
+
+ resp.qp_handle = uobj->id;
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_add_tail(&uobj->list, &file->ucontext->qp_list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp)) {
+ ret = -EFAULT;
+ goto err_list;
+ }
+
+ up(&ib_uverbs_idr_mutex);
+
+ return in_len;
+
+err_list:
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+err_destroy:
+ ib_destroy_qp(qp);
+
+err_up:
+ up(&ib_uverbs_idr_mutex);
+
+ kfree(uobj);
+ return ret;
+}
+
+ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_modify_qp cmd;
+ struct ib_qp *qp;
+ struct ib_qp_attr *attr;
+ int ret;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ attr = kmalloc(sizeof *attr, GFP_KERNEL);
+ if (!attr)
+ return -ENOMEM;
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (!qp || qp->uobject->context != file->ucontext) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ attr->qp_state = cmd.qp_state;
+ attr->cur_qp_state = cmd.cur_qp_state;
+ attr->path_mtu = cmd.path_mtu;
+ attr->path_mig_state = cmd.path_mig_state;
+ attr->qkey = cmd.qkey;
+ attr->rq_psn = cmd.rq_psn;
+ attr->sq_psn = cmd.sq_psn;
+ attr->dest_qp_num = cmd.dest_qp_num;
+ attr->qp_access_flags = cmd.qp_access_flags;
+ attr->pkey_index = cmd.pkey_index;
+ attr->alt_pkey_index = cmd.pkey_index;
+ attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
+ attr->max_rd_atomic = cmd.max_rd_atomic;
+ attr->max_dest_rd_atomic = cmd.max_dest_rd_atomic;
+ attr->min_rnr_timer = cmd.min_rnr_timer;
+ attr->port_num = cmd.port_num;
+ attr->timeout = cmd.timeout;
+ attr->retry_cnt = cmd.retry_cnt;
+ attr->rnr_retry = cmd.rnr_retry;
+ attr->alt_port_num = cmd.alt_port_num;
+ attr->alt_timeout = cmd.alt_timeout;
+
+ memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
+ attr->ah_attr.grh.flow_label = cmd.dest.flow_label;
+ attr->ah_attr.grh.sgid_index = cmd.dest.sgid_index;
+ attr->ah_attr.grh.hop_limit = cmd.dest.hop_limit;
+ attr->ah_attr.grh.traffic_class = cmd.dest.traffic_class;
+ attr->ah_attr.dlid = cmd.dest.dlid;
+ attr->ah_attr.sl = cmd.dest.sl;
+ attr->ah_attr.src_path_bits = cmd.dest.src_path_bits;
+ attr->ah_attr.static_rate = cmd.dest.static_rate;
+ attr->ah_attr.ah_flags = cmd.dest.is_global ? IB_AH_GRH : 0;
+ attr->ah_attr.port_num = cmd.dest.port_num;
+
+ memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
+ attr->alt_ah_attr.grh.flow_label = cmd.alt_dest.flow_label;
+ attr->alt_ah_attr.grh.sgid_index = cmd.alt_dest.sgid_index;
+ attr->alt_ah_attr.grh.hop_limit = cmd.alt_dest.hop_limit;
+ attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
+ attr->alt_ah_attr.dlid = cmd.alt_dest.dlid;
+ attr->alt_ah_attr.sl = cmd.alt_dest.sl;
+ attr->alt_ah_attr.src_path_bits = cmd.alt_dest.src_path_bits;
+ attr->alt_ah_attr.static_rate = cmd.alt_dest.static_rate;
+ attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
+ attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
+
+ ret = ib_modify_qp(qp, attr, cmd.attr_mask);
+ if (ret)
+ goto out;
+
+ ret = in_len;
+
+out:
+ up(&ib_uverbs_idr_mutex);
+ kfree(attr);
+
+ return ret;
+}
+
+ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_destroy_qp cmd;
+ struct ib_qp *qp;
+ struct ib_uobject *uobj;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (!qp || qp->uobject->context != file->ucontext)
+ goto out;
+
+ uobj = qp->uobject;
+
+ ret = ib_destroy_qp(qp);
+ if (ret)
+ goto out;
+
+ idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
+
+ spin_lock_irq(&file->ucontext->lock);
+ list_del(&uobj->list);
+ spin_unlock_irq(&file->ucontext->lock);
+
+ kfree(uobj);
+
+out:
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_attach_mcast cmd;
+ struct ib_qp *qp;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (qp && qp->uobject->context == file->ucontext)
+ ret = ib_attach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
+
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len)
+{
+ struct ib_uverbs_detach_mcast cmd;
+ struct ib_qp *qp;
+ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, buf, sizeof cmd))
+ return -EFAULT;
+
+ down(&ib_uverbs_idr_mutex);
+
+ qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+ if (qp && qp->uobject->context == file->ucontext)
+ ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
+
+ up(&ib_uverbs_idr_mutex);
+
+ return ret ? ret : in_len;
+}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
new file mode 100644
index 00000000000..fbbe03d8c90
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: uverbs_main.c 2733 2005-06-28 19:14:34Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+
+#include <asm/uaccess.h>
+
+#include "uverbs.h"
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("InfiniBand userspace verbs access");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */
+
+enum {
+ IB_UVERBS_MAJOR = 231,
+ IB_UVERBS_BASE_MINOR = 192,
+ IB_UVERBS_MAX_DEVICES = 32
+};
+
+#define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
+
+DECLARE_MUTEX(ib_uverbs_idr_mutex);
+DEFINE_IDR(ib_uverbs_pd_idr);
+DEFINE_IDR(ib_uverbs_mr_idr);
+DEFINE_IDR(ib_uverbs_mw_idr);
+DEFINE_IDR(ib_uverbs_ah_idr);
+DEFINE_IDR(ib_uverbs_cq_idr);
+DEFINE_IDR(ib_uverbs_qp_idr);
+
+static spinlock_t map_lock;
+static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
+
+static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
+ const char __user *buf, int in_len,
+ int out_len) = {
+ [IB_USER_VERBS_CMD_QUERY_PARAMS] = ib_uverbs_query_params,
+ [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context,
+ [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device,
+ [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port,
+ [IB_USER_VERBS_CMD_QUERY_GID] = ib_uverbs_query_gid,
+ [IB_USER_VERBS_CMD_QUERY_PKEY] = ib_uverbs_query_pkey,
+ [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd,
+ [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd,
+ [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr,
+ [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr,
+ [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq,
+ [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq,
+ [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp,
+ [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp,
+ [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
+ [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
+ [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
+};
+
+static struct vfsmount *uverbs_event_mnt;
+
+static void ib_uverbs_add_one(struct ib_device *device);
+static void ib_uverbs_remove_one(struct ib_device *device);
+
+static int ib_dealloc_ucontext(struct ib_ucontext *context)
+{
+ struct ib_uobject *uobj, *tmp;
+
+ if (!context)
+ return 0;
+
+ down(&ib_uverbs_idr_mutex);
+
+ /* XXX Free AHs */
+
+ list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
+ struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id);
+ idr_remove(&ib_uverbs_qp_idr, uobj->id);
+ ib_destroy_qp(qp);
+ list_del(&uobj->list);
+ kfree(uobj);
+ }
+
+ list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
+ struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id);
+ idr_remove(&ib_uverbs_cq_idr, uobj->id);
+ ib_destroy_cq(cq);
+ list_del(&uobj->list);
+ kfree(uobj);
+ }
+
+ /* XXX Free SRQs */
+ /* XXX Free MWs */
+
+ list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
+ struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id);
+ struct ib_umem_object *memobj;
+
+ idr_remove(&ib_uverbs_mr_idr, uobj->id);
+ ib_dereg_mr(mr);
+
+ memobj = container_of(uobj, struct ib_umem_object, uobject);
+ ib_umem_release_on_close(mr->device, &memobj->umem);
+
+ list_del(&uobj->list);
+ kfree(memobj);
+ }
+
+ list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) {
+ struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id);
+ idr_remove(&ib_uverbs_pd_idr, uobj->id);
+ ib_dealloc_pd(pd);
+ list_del(&uobj->list);
+ kfree(uobj);
+ }
+
+ up(&ib_uverbs_idr_mutex);
+
+ return context->device->dealloc_ucontext(context);
+}
+
+static void ib_uverbs_release_file(struct kref *ref)
+{
+ struct ib_uverbs_file *file =
+ container_of(ref, struct ib_uverbs_file, ref);
+
+ module_put(file->device->ib_dev->owner);
+ kfree(file);
+}
+
+static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct ib_uverbs_event_file *file = filp->private_data;
+ void *event;
+ int eventsz;
+ int ret = 0;
+
+ spin_lock_irq(&file->lock);
+
+ while (list_empty(&file->event_list) && file->fd >= 0) {
+ spin_unlock_irq(&file->lock);
+
+ if (filp->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ if (wait_event_interruptible(file->poll_wait,
+ !list_empty(&file->event_list) ||
+ file->fd < 0))
+ return -ERESTARTSYS;
+
+ spin_lock_irq(&file->lock);
+ }
+
+ if (file->fd < 0) {
+ spin_unlock_irq(&file->lock);
+ return -ENODEV;
+ }
+
+ if (file->is_async) {
+ event = list_entry(file->event_list.next,
+ struct ib_uverbs_async_event, list);
+ eventsz = sizeof (struct ib_uverbs_async_event_desc);
+ } else {
+ event = list_entry(file->event_list.next,
+ struct ib_uverbs_comp_event, list);
+ eventsz = sizeof (struct ib_uverbs_comp_event_desc);
+ }
+
+ if (eventsz > count) {
+ ret = -EINVAL;
+ event = NULL;
+ } else
+ list_del(file->event_list.next);
+
+ spin_unlock_irq(&file->lock);
+
+ if (event) {
+ if (copy_to_user(buf, event, eventsz))
+ ret = -EFAULT;
+ else
+ ret = eventsz;
+ }
+
+ kfree(event);
+
+ return ret;
+}
+
+static unsigned int ib_uverbs_event_poll(struct file *filp,
+ struct poll_table_struct *wait)
+{
+ unsigned int pollflags = 0;
+ struct ib_uverbs_event_file *file = filp->private_data;
+
+ poll_wait(filp, &file->poll_wait, wait);
+
+ spin_lock_irq(&file->lock);
+ if (file->fd < 0)
+ pollflags = POLLERR;
+ else if (!list_empty(&file->event_list))
+ pollflags = POLLIN | POLLRDNORM;
+ spin_unlock_irq(&file->lock);
+
+ return pollflags;
+}
+
+static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
+{
+ struct list_head *entry, *tmp;
+
+ spin_lock_irq(&file->lock);
+ if (file->fd != -1) {
+ file->fd = -1;
+ list_for_each_safe(entry, tmp, &file->event_list)
+ if (file->is_async)
+ kfree(list_entry(entry, struct ib_uverbs_async_event, list));
+ else
+ kfree(list_entry(entry, struct ib_uverbs_comp_event, list));
+ }
+ spin_unlock_irq(&file->lock);
+}
+
+static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
+{
+ struct ib_uverbs_event_file *file = filp->private_data;
+
+ ib_uverbs_event_release(file);
+ kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
+
+ return 0;
+}
+
+static struct file_operations uverbs_event_fops = {
+ /*
+ * No .owner field since we artificially create event files,
+ * so there is no increment to the module reference count in
+ * the open path. All event files come from a uverbs command
+ * file, which already takes a module reference, so this is OK.
+ */
+ .read = ib_uverbs_event_read,
+ .poll = ib_uverbs_event_poll,
+ .release = ib_uverbs_event_close
+};
+
+void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
+{
+ struct ib_uverbs_file *file = cq_context;
+ struct ib_uverbs_comp_event *entry;
+ unsigned long flags;
+
+ entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+ if (!entry)
+ return;
+
+ entry->desc.cq_handle = cq->uobject->user_handle;
+
+ spin_lock_irqsave(&file->comp_file[0].lock, flags);
+ list_add_tail(&entry->list, &file->comp_file[0].event_list);
+ spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
+
+ wake_up_interruptible(&file->comp_file[0].poll_wait);
+}
+
+static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
+ __u64 element, __u64 event)
+{
+ struct ib_uverbs_async_event *entry;
+ unsigned long flags;
+
+ entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+ if (!entry)
+ return;
+
+ entry->desc.element = element;
+ entry->desc.event_type = event;
+
+ spin_lock_irqsave(&file->async_file.lock, flags);
+ list_add_tail(&entry->list, &file->async_file.event_list);
+ spin_unlock_irqrestore(&file->async_file.lock, flags);
+
+ wake_up_interruptible(&file->async_file.poll_wait);
+}
+
+void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
+{
+ ib_uverbs_async_handler(context_ptr,
+ event->element.cq->uobject->user_handle,
+ event->event);
+}
+
+void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
+{
+ ib_uverbs_async_handler(context_ptr,
+ event->element.qp->uobject->user_handle,
+ event->event);
+}
+
+static void ib_uverbs_event_handler(struct ib_event_handler *handler,
+ struct ib_event *event)
+{
+ struct ib_uverbs_file *file =
+ container_of(handler, struct ib_uverbs_file, event_handler);
+
+ ib_uverbs_async_handler(file, event->element.port_num, event->event);
+}
+
+static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
+ struct ib_uverbs_file *uverbs_file)
+{
+ struct file *filp;
+
+ spin_lock_init(&file->lock);
+ INIT_LIST_HEAD(&file->event_list);
+ init_waitqueue_head(&file->poll_wait);
+ file->uverbs_file = uverbs_file;
+
+ file->fd = get_unused_fd();
+ if (file->fd < 0)
+ return file->fd;
+
+ filp = get_empty_filp();
+ if (!filp) {
+ put_unused_fd(file->fd);
+ return -ENFILE;
+ }
+
+ filp->f_op = &uverbs_event_fops;
+ filp->f_vfsmnt = mntget(uverbs_event_mnt);
+ filp->f_dentry = dget(uverbs_event_mnt->mnt_root);
+ filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+ filp->f_flags = O_RDONLY;
+ filp->f_mode = FMODE_READ;
+ filp->private_data = file;
+
+ fd_install(file->fd, filp);
+
+ return 0;
+}
+
+static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct ib_uverbs_file *file = filp->private_data;
+ struct ib_uverbs_cmd_hdr hdr;
+
+ if (count < sizeof hdr)
+ return -EINVAL;
+
+ if (copy_from_user(&hdr, buf, sizeof hdr))
+ return -EFAULT;
+
+ if (hdr.in_words * 4 != count)
+ return -EINVAL;
+
+ if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
+ return -EINVAL;
+
+ if (!file->ucontext &&
+ hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS &&
+ hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)
+ return -EINVAL;
+
+ return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr,
+ hdr.in_words * 4, hdr.out_words * 4);
+}
+
+static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct ib_uverbs_file *file = filp->private_data;
+
+ if (!file->ucontext)
+ return -ENODEV;
+ else
+ return file->device->ib_dev->mmap(file->ucontext, vma);
+}
+
+static int ib_uverbs_open(struct inode *inode, struct file *filp)
+{
+ struct ib_uverbs_device *dev =
+ container_of(inode->i_cdev, struct ib_uverbs_device, dev);
+ struct ib_uverbs_file *file;
+ int i = 0;
+ int ret;
+
+ if (!try_module_get(dev->ib_dev->owner))
+ return -ENODEV;
+
+ file = kmalloc(sizeof *file +
+ (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
+ GFP_KERNEL);
+ if (!file)
+ return -ENOMEM;
+
+ file->device = dev;
+ kref_init(&file->ref);
+
+ file->ucontext = NULL;
+
+ ret = ib_uverbs_event_init(&file->async_file, file);
+ if (ret)
+ goto err;
+
+ file->async_file.is_async = 1;
+
+ kref_get(&file->ref);
+
+ for (i = 0; i < dev->num_comp; ++i) {
+ ret = ib_uverbs_event_init(&file->comp_file[i], file);
+ if (ret)
+ goto err_async;
+ kref_get(&file->ref);
+ file->comp_file[i].is_async = 0;
+ }
+
+
+ filp->private_data = file;
+
+ INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev,
+ ib_uverbs_event_handler);
+ if (ib_register_event_handler(&file->event_handler))
+ goto err_async;
+
+ return 0;
+
+err_async:
+ while (i--)
+ ib_uverbs_event_release(&file->comp_file[i]);
+
+ ib_uverbs_event_release(&file->async_file);
+
+err:
+ kref_put(&file->ref, ib_uverbs_release_file);
+
+ return ret;
+}
+
+static int ib_uverbs_close(struct inode *inode, struct file *filp)
+{
+ struct ib_uverbs_file *file = filp->private_data;
+ int i;
+
+ ib_unregister_event_handler(&file->event_handler);
+ ib_uverbs_event_release(&file->async_file);
+ ib_dealloc_ucontext(file->ucontext);
+
+ for (i = 0; i < file->device->num_comp; ++i)
+ ib_uverbs_event_release(&file->comp_file[i]);
+
+ kref_put(&file->ref, ib_uverbs_release_file);
+
+ return 0;
+}
+
+static struct file_operations uverbs_fops = {
+ .owner = THIS_MODULE,
+ .write = ib_uverbs_write,
+ .open = ib_uverbs_open,
+ .release = ib_uverbs_close
+};
+
+static struct file_operations uverbs_mmap_fops = {
+ .owner = THIS_MODULE,
+ .write = ib_uverbs_write,
+ .mmap = ib_uverbs_mmap,
+ .open = ib_uverbs_open,
+ .release = ib_uverbs_close
+};
+
+static struct ib_client uverbs_client = {
+ .name = "uverbs",
+ .add = ib_uverbs_add_one,
+ .remove = ib_uverbs_remove_one
+};
+
+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+{
+ struct ib_uverbs_device *dev =
+ container_of(class_dev, struct ib_uverbs_device, class_dev);
+
+ return sprintf(buf, "%s\n", dev->ib_dev->name);
+}
+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+
+static void ib_uverbs_release_class_dev(struct class_device *class_dev)
+{
+ struct ib_uverbs_device *dev =
+ container_of(class_dev, struct ib_uverbs_device, class_dev);
+
+ cdev_del(&dev->dev);
+ clear_bit(dev->devnum, dev_map);
+ kfree(dev);
+}
+
+static struct class uverbs_class = {
+ .name = "infiniband_verbs",
+ .release = ib_uverbs_release_class_dev
+};
+
+static ssize_t show_abi_version(struct class *class, char *buf)
+{
+ return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
+}
+static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+
+static void ib_uverbs_add_one(struct ib_device *device)
+{
+ struct ib_uverbs_device *uverbs_dev;
+
+ if (!device->alloc_ucontext)
+ return;
+
+ uverbs_dev = kmalloc(sizeof *uverbs_dev, GFP_KERNEL);
+ if (!uverbs_dev)
+ return;
+
+ memset(uverbs_dev, 0, sizeof *uverbs_dev);
+
+ spin_lock(&map_lock);
+ uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
+ if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {
+ spin_unlock(&map_lock);
+ goto err;
+ }
+ set_bit(uverbs_dev->devnum, dev_map);
+ spin_unlock(&map_lock);
+
+ uverbs_dev->ib_dev = device;
+ uverbs_dev->num_comp = 1;
+
+ if (device->mmap)
+ cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops);
+ else
+ cdev_init(&uverbs_dev->dev, &uverbs_fops);
+ uverbs_dev->dev.owner = THIS_MODULE;
+ kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum);
+ if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+ goto err;
+
+ uverbs_dev->class_dev.class = &uverbs_class;
+ uverbs_dev->class_dev.dev = device->dma_device;
+ uverbs_dev->class_dev.devt = uverbs_dev->dev.dev;
+ snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum);
+ if (class_device_register(&uverbs_dev->class_dev))
+ goto err_cdev;
+
+ if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev))
+ goto err_class;
+
+ ib_set_client_data(device, &uverbs_client, uverbs_dev);
+
+ return;
+
+err_class:
+ class_device_unregister(&uverbs_dev->class_dev);
+
+err_cdev:
+ cdev_del(&uverbs_dev->dev);
+ clear_bit(uverbs_dev->devnum, dev_map);
+
+err:
+ kfree(uverbs_dev);
+ return;
+}
+
+static void ib_uverbs_remove_one(struct ib_device *device)
+{
+ struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client);
+
+ if (!uverbs_dev)
+ return;
+
+ class_device_unregister(&uverbs_dev->class_dev);
+}
+
+static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data)
+{
+ return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
+ INFINIBANDEVENTFS_MAGIC);
+}
+
+static struct file_system_type uverbs_event_fs = {
+ /* No owner field so module can be unloaded */
+ .name = "infinibandeventfs",
+ .get_sb = uverbs_event_get_sb,
+ .kill_sb = kill_litter_super
+};
+
+static int __init ib_uverbs_init(void)
+{
+ int ret;
+
+ spin_lock_init(&map_lock);
+
+ ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES,
+ "infiniband_verbs");
+ if (ret) {
+ printk(KERN_ERR "user_verbs: couldn't register device number\n");
+ goto out;
+ }
+
+ ret = class_register(&uverbs_class);
+ if (ret) {
+ printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");
+ goto out_chrdev;
+ }
+
+ ret = class_create_file(&uverbs_class, &class_attr_abi_version);
+ if (ret) {
+ printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
+ goto out_class;
+ }
+
+ ret = register_filesystem(&uverbs_event_fs);
+ if (ret) {
+ printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
+ goto out_class;
+ }
+
+ uverbs_event_mnt = kern_mount(&uverbs_event_fs);
+ if (IS_ERR(uverbs_event_mnt)) {
+ ret = PTR_ERR(uverbs_event_mnt);
+ printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
+ goto out_fs;
+ }
+
+ ret = ib_register_client(&uverbs_client);
+ if (ret) {
+ printk(KERN_ERR "user_verbs: couldn't register client\n");
+ goto out_mnt;
+ }
+
+ return 0;
+
+out_mnt:
+ mntput(uverbs_event_mnt);
+
+out_fs:
+ unregister_filesystem(&uverbs_event_fs);
+
+out_class:
+ class_unregister(&uverbs_class);
+
+out_chrdev:
+ unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+
+out:
+ return ret;
+}
+
+static void __exit ib_uverbs_cleanup(void)
+{
+ ib_unregister_client(&uverbs_client);
+ mntput(uverbs_event_mnt);
+ unregister_filesystem(&uverbs_event_fs);
+ class_unregister(&uverbs_class);
+ unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+}
+
+module_init(ib_uverbs_init);
+module_exit(ib_uverbs_cleanup);
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c
new file mode 100644
index 00000000000..ed550f6595b
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_mem.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: uverbs_mem.c 2743 2005-06-28 22:27:59Z roland $
+ */
+
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+#include "uverbs.h"
+
+struct ib_umem_account_work {
+ struct work_struct work;
+ struct mm_struct *mm;
+ unsigned long diff;
+};
+
+
+static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
+{
+ struct ib_umem_chunk *chunk, *tmp;
+ int i;
+
+ list_for_each_entry_safe(chunk, tmp, &umem->chunk_list, list) {
+ dma_unmap_sg(dev->dma_device, chunk->page_list,
+ chunk->nents, DMA_BIDIRECTIONAL);
+ for (i = 0; i < chunk->nents; ++i) {
+ if (umem->writable && dirty)
+ set_page_dirty_lock(chunk->page_list[i].page);
+ put_page(chunk->page_list[i].page);
+ }
+
+ kfree(chunk);
+ }
+}
+
+int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
+ void *addr, size_t size, int write)
+{
+ struct page **page_list;
+ struct ib_umem_chunk *chunk;
+ unsigned long locked;
+ unsigned long lock_limit;
+ unsigned long cur_base;
+ unsigned long npages;
+ int ret = 0;
+ int off;
+ int i;
+
+ if (!can_do_mlock())
+ return -EPERM;
+
+ page_list = (struct page **) __get_free_page(GFP_KERNEL);
+ if (!page_list)
+ return -ENOMEM;
+
+ mem->user_base = (unsigned long) addr;
+ mem->length = size;
+ mem->offset = (unsigned long) addr & ~PAGE_MASK;
+ mem->page_size = PAGE_SIZE;
+ mem->writable = write;
+
+ INIT_LIST_HEAD(&mem->chunk_list);
+
+ npages = PAGE_ALIGN(size + mem->offset) >> PAGE_SHIFT;
+
+ down_write(&current->mm->mmap_sem);
+
+ locked = npages + current->mm->locked_vm;
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+
+ if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ cur_base = (unsigned long) addr & PAGE_MASK;
+
+ while (npages) {
+ ret = get_user_pages(current, current->mm, cur_base,
+ min_t(int, npages,
+ PAGE_SIZE / sizeof (struct page *)),
+ 1, !write, page_list, NULL);
+
+ if (ret < 0)
+ goto out;
+
+ cur_base += ret * PAGE_SIZE;
+ npages -= ret;
+
+ off = 0;
+
+ while (ret) {
+ chunk = kmalloc(sizeof *chunk + sizeof (struct scatterlist) *
+ min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK),
+ GFP_KERNEL);
+ if (!chunk) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+ for (i = 0; i < chunk->nents; ++i) {
+ chunk->page_list[i].page = page_list[i + off];
+ chunk->page_list[i].offset = 0;
+ chunk->page_list[i].length = PAGE_SIZE;
+ }
+
+ chunk->nmap = dma_map_sg(dev->dma_device,
+ &chunk->page_list[0],
+ chunk->nents,
+ DMA_BIDIRECTIONAL);
+ if (chunk->nmap <= 0) {
+ for (i = 0; i < chunk->nents; ++i)
+ put_page(chunk->page_list[i].page);
+ kfree(chunk);
+
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret -= chunk->nents;
+ off += chunk->nents;
+ list_add_tail(&chunk->list, &mem->chunk_list);
+ }
+
+ ret = 0;
+ }
+
+out:
+ if (ret < 0)
+ __ib_umem_release(dev, mem, 0);
+ else
+ current->mm->locked_vm = locked;
+
+ up_write(&current->mm->mmap_sem);
+ free_page((unsigned long) page_list);
+
+ return ret;
+}
+
+void ib_umem_release(struct ib_device *dev, struct ib_umem *umem)
+{
+ __ib_umem_release(dev, umem, 1);
+
+ down_write(&current->mm->mmap_sem);
+ current->mm->locked_vm -=
+ PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
+ up_write(&current->mm->mmap_sem);
+}
+
+static void ib_umem_account(void *work_ptr)
+{
+ struct ib_umem_account_work *work = work_ptr;
+
+ down_write(&work->mm->mmap_sem);
+ work->mm->locked_vm -= work->diff;
+ up_write(&work->mm->mmap_sem);
+ mmput(work->mm);
+ kfree(work);
+}
+
+void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem)
+{
+ struct ib_umem_account_work *work;
+ struct mm_struct *mm;
+
+ __ib_umem_release(dev, umem, 1);
+
+ mm = get_task_mm(current);
+ if (!mm)
+ return;
+
+ /*
+ * We may be called with the mm's mmap_sem already held. This
+ * can happen when a userspace munmap() is the call that drops
+ * the last reference to our file and calls our release
+ * method. If there are memory regions to destroy, we'll end
+ * up here and not be able to take the mmap_sem. Therefore we
+ * defer the vm_locked accounting to the system workqueue.
+ */
+
+ work = kmalloc(sizeof *work, GFP_KERNEL);
+ if (!work)
+ return;
+
+ INIT_WORK(&work->work, ib_umem_account, work);
+ work->mm = mm;
+ work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
+
+ schedule_work(&work->work);
+}
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 7c08ed0cd7d..2516f964651 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -4,6 +4,7 @@
* Copyright (c) 2004 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -47,10 +48,11 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device)
{
struct ib_pd *pd;
- pd = device->alloc_pd(device);
+ pd = device->alloc_pd(device, NULL, NULL);
if (!IS_ERR(pd)) {
- pd->device = device;
+ pd->device = device;
+ pd->uobject = NULL;
atomic_set(&pd->usecnt, 0);
}
@@ -76,8 +78,9 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
ah = pd->device->create_ah(pd, ah_attr);
if (!IS_ERR(ah)) {
- ah->device = pd->device;
- ah->pd = pd;
+ ah->device = pd->device;
+ ah->pd = pd;
+ ah->uobject = NULL;
atomic_inc(&pd->usecnt);
}
@@ -122,7 +125,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
{
struct ib_qp *qp;
- qp = pd->device->create_qp(pd, qp_init_attr);
+ qp = pd->device->create_qp(pd, qp_init_attr, NULL);
if (!IS_ERR(qp)) {
qp->device = pd->device;
@@ -130,6 +133,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->send_cq = qp_init_attr->send_cq;
qp->recv_cq = qp_init_attr->recv_cq;
qp->srq = qp_init_attr->srq;
+ qp->uobject = NULL;
qp->event_handler = qp_init_attr->event_handler;
qp->qp_context = qp_init_attr->qp_context;
qp->qp_type = qp_init_attr->qp_type;
@@ -197,10 +201,11 @@ struct ib_cq *ib_create_cq(struct ib_device *device,
{
struct ib_cq *cq;
- cq = device->create_cq(device, cqe);
+ cq = device->create_cq(device, cqe, NULL, NULL);
if (!IS_ERR(cq)) {
cq->device = device;
+ cq->uobject = NULL;
cq->comp_handler = comp_handler;
cq->event_handler = event_handler;
cq->cq_context = cq_context;
@@ -245,8 +250,9 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
mr = pd->device->get_dma_mr(pd, mr_access_flags);
if (!IS_ERR(mr)) {
- mr->device = pd->device;
- mr->pd = pd;
+ mr->device = pd->device;
+ mr->pd = pd;
+ mr->uobject = NULL;
atomic_inc(&pd->usecnt);
atomic_set(&mr->usecnt, 0);
}
@@ -267,8 +273,9 @@ struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
mr_access_flags, iova_start);
if (!IS_ERR(mr)) {
- mr->device = pd->device;
- mr->pd = pd;
+ mr->device = pd->device;
+ mr->pd = pd;
+ mr->uobject = NULL;
atomic_inc(&pd->usecnt);
atomic_set(&mr->usecnt, 0);
}
@@ -344,8 +351,9 @@ struct ib_mw *ib_alloc_mw(struct ib_pd *pd)
mw = pd->device->alloc_mw(pd);
if (!IS_ERR(mw)) {
- mw->device = pd->device;
- mw->pd = pd;
+ mw->device = pd->device;
+ mw->pd = pd;
+ mw->uobject = NULL;
atomic_inc(&pd->usecnt);
}
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 766e9031ec4..b5aea7b869f 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -742,6 +743,7 @@ err_out:
}
int mthca_init_cq(struct mthca_dev *dev, int nent,
+ struct mthca_ucontext *ctx, u32 pdn,
struct mthca_cq *cq)
{
int size = nent * MTHCA_CQ_ENTRY_SIZE;
@@ -753,30 +755,33 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
might_sleep();
- cq->ibcq.cqe = nent - 1;
+ cq->ibcq.cqe = nent - 1;
+ cq->is_kernel = !ctx;
cq->cqn = mthca_alloc(&dev->cq_table.alloc);
if (cq->cqn == -1)
return -ENOMEM;
if (mthca_is_memfree(dev)) {
- cq->arm_sn = 1;
-
err = mthca_table_get(dev, dev->cq_table.table, cq->cqn);
if (err)
goto err_out;
- err = -ENOMEM;
+ if (cq->is_kernel) {
+ cq->arm_sn = 1;
+
+ err = -ENOMEM;
- cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
- cq->cqn, &cq->set_ci_db);
- if (cq->set_ci_db_index < 0)
- goto err_out_icm;
+ cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
+ cq->cqn, &cq->set_ci_db);
+ if (cq->set_ci_db_index < 0)
+ goto err_out_icm;
- cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
- cq->cqn, &cq->arm_db);
- if (cq->arm_db_index < 0)
- goto err_out_ci;
+ cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
+ cq->cqn, &cq->arm_db);
+ if (cq->arm_db_index < 0)
+ goto err_out_ci;
+ }
}
mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
@@ -785,12 +790,14 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
cq_context = mailbox->buf;
- err = mthca_alloc_cq_buf(dev, size, cq);
- if (err)
- goto err_out_mailbox;
+ if (cq->is_kernel) {
+ err = mthca_alloc_cq_buf(dev, size, cq);
+ if (err)
+ goto err_out_mailbox;
- for (i = 0; i < nent; ++i)
- set_cqe_hw(get_cqe(cq, i));
+ for (i = 0; i < nent; ++i)
+ set_cqe_hw(get_cqe(cq, i));
+ }
spin_lock_init(&cq->lock);
atomic_set(&cq->refcount, 1);
@@ -801,11 +808,14 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
MTHCA_CQ_STATE_DISARMED |
MTHCA_CQ_FLAG_TR);
cq_context->start = cpu_to_be64(0);
- cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24 |
- dev->driver_uar.index);
+ cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
+ if (ctx)
+ cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index);
+ else
+ cq_context->logsize_usrpage |= cpu_to_be32(dev->driver_uar.index);
cq_context->error_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn);
cq_context->comp_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn);
- cq_context->pd = cpu_to_be32(dev->driver_pd.pd_num);
+ cq_context->pd = cpu_to_be32(pdn);
cq_context->lkey = cpu_to_be32(cq->mr.ibmr.lkey);
cq_context->cqn = cpu_to_be32(cq->cqn);
@@ -843,18 +853,20 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
return 0;
err_out_free_mr:
- mthca_free_mr(dev, &cq->mr);
- mthca_free_cq_buf(dev, cq);
+ if (cq->is_kernel) {
+ mthca_free_mr(dev, &cq->mr);
+ mthca_free_cq_buf(dev, cq);
+ }
err_out_mailbox:
mthca_free_mailbox(dev, mailbox);
err_out_arm:
- if (mthca_is_memfree(dev))
+ if (cq->is_kernel && mthca_is_memfree(dev))
mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
err_out_ci:
- if (mthca_is_memfree(dev))
+ if (cq->is_kernel && mthca_is_memfree(dev))
mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
err_out_icm:
@@ -892,7 +904,8 @@ void mthca_free_cq(struct mthca_dev *dev,
int j;
printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
- cq->cqn, cq->cons_index, !!next_cqe_sw(cq));
+ cq->cqn, cq->cons_index,
+ cq->is_kernel ? !!next_cqe_sw(cq) : 0);
for (j = 0; j < 16; ++j)
printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
}
@@ -910,12 +923,13 @@ void mthca_free_cq(struct mthca_dev *dev,
atomic_dec(&cq->refcount);
wait_event(cq->wait, !atomic_read(&cq->refcount));
- mthca_free_mr(dev, &cq->mr);
- mthca_free_cq_buf(dev, cq);
-
- if (mthca_is_memfree(dev)) {
- mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
- mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
+ if (cq->is_kernel) {
+ mthca_free_mr(dev, &cq->mr);
+ mthca_free_cq_buf(dev, cq);
+ if (mthca_is_memfree(dev)) {
+ mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
+ mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
+ }
}
mthca_table_put(dev, dev->cq_table.table, cq->cqn);
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 4127f09dc5e..5ecdd2eeeb0 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -378,7 +379,7 @@ void mthca_unregister_device(struct mthca_dev *dev);
int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
-int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd);
+int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd);
void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);
struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size);
@@ -413,6 +414,7 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
int mthca_init_cq(struct mthca_dev *dev, int nent,
+ struct mthca_ucontext *ctx, u32 pdn,
struct mthca_cq *cq);
void mthca_free_cq(struct mthca_dev *dev,
struct mthca_cq *cq);
@@ -438,12 +440,14 @@ int mthca_alloc_qp(struct mthca_dev *dev,
struct mthca_cq *recv_cq,
enum ib_qp_type type,
enum ib_sig_type send_policy,
+ struct ib_qp_cap *cap,
struct mthca_qp *qp);
int mthca_alloc_sqp(struct mthca_dev *dev,
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
enum ib_sig_type send_policy,
+ struct ib_qp_cap *cap,
int qpn,
int port,
struct mthca_sqp *sqp);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 09519b604c0..2ef916859e1 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -665,7 +665,7 @@ static int __devinit mthca_setup_hca(struct mthca_dev *dev)
goto err_pd_table_free;
}
- err = mthca_pd_alloc(dev, &dev->driver_pd);
+ err = mthca_pd_alloc(dev, 1, &dev->driver_pd);
if (err) {
mthca_err(dev, "Failed to create driver PD, "
"aborting.\n");
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 6d3b05dd9e3..2a864615035 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -47,6 +48,15 @@ enum {
MTHCA_TABLE_CHUNK_SIZE = 1 << 18
};
+struct mthca_user_db_table {
+ struct semaphore mutex;
+ struct {
+ u64 uvirt;
+ struct scatterlist mem;
+ int refcount;
+ } page[0];
+};
+
void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
{
struct mthca_icm_chunk *chunk, *tmp;
@@ -344,13 +354,133 @@ void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table)
kfree(table);
}
-static u64 mthca_uarc_virt(struct mthca_dev *dev, int page)
+static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int page)
{
return dev->uar_table.uarc_base +
- dev->driver_uar.index * dev->uar_table.uarc_size +
+ uar->index * dev->uar_table.uarc_size +
page * 4096;
}
+int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab, int index, u64 uaddr)
+{
+ int ret = 0;
+ u8 status;
+ int i;
+
+ if (!mthca_is_memfree(dev))
+ return 0;
+
+ if (index < 0 || index > dev->uar_table.uarc_size / 8)
+ return -EINVAL;
+
+ down(&db_tab->mutex);
+
+ i = index / MTHCA_DB_REC_PER_PAGE;
+
+ if ((db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE) ||
+ (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr) ||
+ (uaddr & 4095)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (db_tab->page[i].refcount) {
+ ++db_tab->page[i].refcount;
+ goto out;
+ }
+
+ ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
+ &db_tab->page[i].mem.page, NULL);
+ if (ret < 0)
+ goto out;
+
+ db_tab->page[i].mem.length = 4096;
+ db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
+
+ ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+ if (ret < 0) {
+ put_page(db_tab->page[i].mem.page);
+ goto out;
+ }
+
+ ret = mthca_MAP_ICM_page(dev, sg_dma_address(&db_tab->page[i].mem),
+ mthca_uarc_virt(dev, uar, i), &status);
+ if (!ret && status)
+ ret = -EINVAL;
+ if (ret) {
+ pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+ put_page(db_tab->page[i].mem.page);
+ goto out;
+ }
+
+ db_tab->page[i].uvirt = uaddr;
+ db_tab->page[i].refcount = 1;
+
+out:
+ up(&db_tab->mutex);
+ return ret;
+}
+
+void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab, int index)
+{
+ if (!mthca_is_memfree(dev))
+ return;
+
+ /*
+ * To make our bookkeeping simpler, we don't unmap DB
+ * pages until we clean up the whole db table.
+ */
+
+ down(&db_tab->mutex);
+
+ --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
+
+ up(&db_tab->mutex);
+}
+
+struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
+{
+ struct mthca_user_db_table *db_tab;
+ int npages;
+ int i;
+
+ if (!mthca_is_memfree(dev))
+ return NULL;
+
+ npages = dev->uar_table.uarc_size / 4096;
+ db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL);
+ if (!db_tab)
+ return ERR_PTR(-ENOMEM);
+
+ init_MUTEX(&db_tab->mutex);
+ for (i = 0; i < npages; ++i) {
+ db_tab->page[i].refcount = 0;
+ db_tab->page[i].uvirt = 0;
+ }
+
+ return db_tab;
+}
+
+void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab)
+{
+ int i;
+ u8 status;
+
+ if (!mthca_is_memfree(dev))
+ return;
+
+ for (i = 0; i < dev->uar_table.uarc_size / 4096; ++i) {
+ if (db_tab->page[i].uvirt) {
+ mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
+ pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+ put_page(db_tab->page[i].mem.page);
+ }
+ }
+}
+
int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db)
{
int group;
@@ -407,7 +537,8 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db)
}
memset(page->db_rec, 0, 4096);
- ret = mthca_MAP_ICM_page(dev, page->mapping, mthca_uarc_virt(dev, i), &status);
+ ret = mthca_MAP_ICM_page(dev, page->mapping,
+ mthca_uarc_virt(dev, &dev->driver_uar, i), &status);
if (!ret && status)
ret = -EINVAL;
if (ret) {
@@ -461,7 +592,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
if (bitmap_empty(page->used, MTHCA_DB_REC_PER_PAGE) &&
i >= dev->db_tab->max_group1 - 1) {
- mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status);
+ mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
dma_free_coherent(&dev->pdev->dev, 4096,
page->db_rec, page->mapping);
@@ -530,7 +661,7 @@ void mthca_cleanup_db_tab(struct mthca_dev *dev)
if (!bitmap_empty(dev->db_tab->page[i].used, MTHCA_DB_REC_PER_PAGE))
mthca_warn(dev, "Kernel UARC page %d not empty\n", i);
- mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status);
+ mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
dma_free_coherent(&dev->pdev->dev, 4096,
dev->db_tab->page[i].db_rec,
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index fe7be2a6bc4..4761d844cb5 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -148,7 +149,7 @@ struct mthca_db_table {
struct semaphore mutex;
};
-enum {
+enum mthca_db_type {
MTHCA_DB_TYPE_INVALID = 0x0,
MTHCA_DB_TYPE_CQ_SET_CI = 0x1,
MTHCA_DB_TYPE_CQ_ARM = 0x2,
@@ -158,6 +159,17 @@ enum {
MTHCA_DB_TYPE_GROUP_SEP = 0x7
};
+struct mthca_user_db_table;
+struct mthca_uar;
+
+int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab, int index, u64 uaddr);
+void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab, int index);
+struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev);
+void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
+ struct mthca_user_db_table *db_tab);
+
int mthca_init_db_tab(struct mthca_dev *dev);
void mthca_cleanup_db_tab(struct mthca_dev *dev);
int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db);
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
index ea66847e4ea..c2c899844e9 100644
--- a/drivers/infiniband/hw/mthca/mthca_pd.c
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -37,23 +38,27 @@
#include "mthca_dev.h"
-int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd)
+int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd)
{
- int err;
+ int err = 0;
might_sleep();
+ pd->privileged = privileged;
+
atomic_set(&pd->sqp_count, 0);
pd->pd_num = mthca_alloc(&dev->pd_table.alloc);
if (pd->pd_num == -1)
return -ENOMEM;
- err = mthca_mr_alloc_notrans(dev, pd->pd_num,
- MTHCA_MPT_FLAG_LOCAL_READ |
- MTHCA_MPT_FLAG_LOCAL_WRITE,
- &pd->ntmr);
- if (err)
- mthca_free(&dev->pd_table.alloc, pd->pd_num);
+ if (privileged) {
+ err = mthca_mr_alloc_notrans(dev, pd->pd_num,
+ MTHCA_MPT_FLAG_LOCAL_READ |
+ MTHCA_MPT_FLAG_LOCAL_WRITE,
+ &pd->ntmr);
+ if (err)
+ mthca_free(&dev->pd_table.alloc, pd->pd_num);
+ }
return err;
}
@@ -61,7 +66,8 @@ int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd)
void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd)
{
might_sleep();
- mthca_free_mr(dev, &pd->ntmr);
+ if (pd->privileged)
+ mthca_free_mr(dev, &pd->ntmr);
mthca_free(&dev->pd_table.alloc, pd->pd_num);
}
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 0b5adfd9159..7a58ce90e17 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -34,9 +35,12 @@
*/
#include <ib_smi.h>
+#include <linux/mm.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
+#include "mthca_user.h"
+#include "mthca_memfree.h"
static int mthca_query_device(struct ib_device *ibdev,
struct ib_device_attr *props)
@@ -284,7 +288,78 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port,
return err;
}
-static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev)
+static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
+ struct ib_udata *udata)
+{
+ struct mthca_alloc_ucontext_resp uresp;
+ struct mthca_ucontext *context;
+ int err;
+
+ memset(&uresp, 0, sizeof uresp);
+
+ uresp.qp_tab_size = to_mdev(ibdev)->limits.num_qps;
+ if (mthca_is_memfree(to_mdev(ibdev)))
+ uresp.uarc_size = to_mdev(ibdev)->uar_table.uarc_size;
+ else
+ uresp.uarc_size = 0;
+
+ context = kmalloc(sizeof *context, GFP_KERNEL);
+ if (!context)
+ return ERR_PTR(-ENOMEM);
+
+ err = mthca_uar_alloc(to_mdev(ibdev), &context->uar);
+ if (err) {
+ kfree(context);
+ return ERR_PTR(err);
+ }
+
+ context->db_tab = mthca_init_user_db_tab(to_mdev(ibdev));
+ if (IS_ERR(context->db_tab)) {
+ err = PTR_ERR(context->db_tab);
+ mthca_uar_free(to_mdev(ibdev), &context->uar);
+ kfree(context);
+ return ERR_PTR(err);
+ }
+
+ if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) {
+ mthca_cleanup_user_db_tab(to_mdev(ibdev), &context->uar, context->db_tab);
+ mthca_uar_free(to_mdev(ibdev), &context->uar);
+ kfree(context);
+ return ERR_PTR(-EFAULT);
+ }
+
+ return &context->ibucontext;
+}
+
+static int mthca_dealloc_ucontext(struct ib_ucontext *context)
+{
+ mthca_cleanup_user_db_tab(to_mdev(context->device), &to_mucontext(context)->uar,
+ to_mucontext(context)->db_tab);
+ mthca_uar_free(to_mdev(context->device), &to_mucontext(context)->uar);
+ kfree(to_mucontext(context));
+
+ return 0;
+}
+
+static int mthca_mmap_uar(struct ib_ucontext *context,
+ struct vm_area_struct *vma)
+{
+ if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start,
+ to_mucontext(context)->uar.pfn,
+ PAGE_SIZE, vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
{
struct mthca_pd *pd;
int err;
@@ -293,12 +368,20 @@ static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev)
if (!pd)
return ERR_PTR(-ENOMEM);
- err = mthca_pd_alloc(to_mdev(ibdev), pd);
+ err = mthca_pd_alloc(to_mdev(ibdev), !context, pd);
if (err) {
kfree(pd);
return ERR_PTR(err);
}
+ if (context) {
+ if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
+ mthca_pd_free(to_mdev(ibdev), pd);
+ kfree(pd);
+ return ERR_PTR(-EFAULT);
+ }
+ }
+
return &pd->ibpd;
}
@@ -338,8 +421,10 @@ static int mthca_ah_destroy(struct ib_ah *ah)
}
static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
- struct ib_qp_init_attr *init_attr)
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
{
+ struct mthca_create_qp ucmd;
struct mthca_qp *qp;
int err;
@@ -348,41 +433,82 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
case IB_QPT_UC:
case IB_QPT_UD:
{
+ struct mthca_ucontext *context;
+
qp = kmalloc(sizeof *qp, GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);
- qp->sq.max = init_attr->cap.max_send_wr;
- qp->rq.max = init_attr->cap.max_recv_wr;
- qp->sq.max_gs = init_attr->cap.max_send_sge;
- qp->rq.max_gs = init_attr->cap.max_recv_sge;
+ if (pd->uobject) {
+ context = to_mucontext(pd->uobject->context);
+
+ if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+ return ERR_PTR(-EFAULT);
+
+ err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
+ context->db_tab,
+ ucmd.sq_db_index, ucmd.sq_db_page);
+ if (err) {
+ kfree(qp);
+ return ERR_PTR(err);
+ }
+
+ err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
+ context->db_tab,
+ ucmd.rq_db_index, ucmd.rq_db_page);
+ if (err) {
+ mthca_unmap_user_db(to_mdev(pd->device),
+ &context->uar,
+ context->db_tab,
+ ucmd.sq_db_index);
+ kfree(qp);
+ return ERR_PTR(err);
+ }
+
+ qp->mr.ibmr.lkey = ucmd.lkey;
+ qp->sq.db_index = ucmd.sq_db_index;
+ qp->rq.db_index = ucmd.rq_db_index;
+ }
err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd),
to_mcq(init_attr->send_cq),
to_mcq(init_attr->recv_cq),
init_attr->qp_type, init_attr->sq_sig_type,
- qp);
+ &init_attr->cap, qp);
+
+ if (err && pd->uobject) {
+ context = to_mucontext(pd->uobject->context);
+
+ mthca_unmap_user_db(to_mdev(pd->device),
+ &context->uar,
+ context->db_tab,
+ ucmd.sq_db_index);
+ mthca_unmap_user_db(to_mdev(pd->device),
+ &context->uar,
+ context->db_tab,
+ ucmd.rq_db_index);
+ }
+
qp->ibqp.qp_num = qp->qpn;
break;
}
case IB_QPT_SMI:
case IB_QPT_GSI:
{
+ /* Don't allow userspace to create special QPs */
+ if (pd->uobject)
+ return ERR_PTR(-EINVAL);
+
qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);
- qp->sq.max = init_attr->cap.max_send_wr;
- qp->rq.max = init_attr->cap.max_recv_wr;
- qp->sq.max_gs = init_attr->cap.max_send_sge;
- qp->rq.max_gs = init_attr->cap.max_recv_sge;
-
qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd),
to_mcq(init_attr->send_cq),
to_mcq(init_attr->recv_cq),
- init_attr->sq_sig_type,
+ init_attr->sq_sig_type, &init_attr->cap,
qp->ibqp.qp_num, init_attr->port_num,
to_msqp(qp));
break;
@@ -397,42 +523,115 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
return ERR_PTR(err);
}
- init_attr->cap.max_inline_data = 0;
+ init_attr->cap.max_inline_data = 0;
+ init_attr->cap.max_send_wr = qp->sq.max;
+ init_attr->cap.max_recv_wr = qp->rq.max;
+ init_attr->cap.max_send_sge = qp->sq.max_gs;
+ init_attr->cap.max_recv_sge = qp->rq.max_gs;
return &qp->ibqp;
}
static int mthca_destroy_qp(struct ib_qp *qp)
{
+ if (qp->uobject) {
+ mthca_unmap_user_db(to_mdev(qp->device),
+ &to_mucontext(qp->uobject->context)->uar,
+ to_mucontext(qp->uobject->context)->db_tab,
+ to_mqp(qp)->sq.db_index);
+ mthca_unmap_user_db(to_mdev(qp->device),
+ &to_mucontext(qp->uobject->context)->uar,
+ to_mucontext(qp->uobject->context)->db_tab,
+ to_mqp(qp)->rq.db_index);
+ }
mthca_free_qp(to_mdev(qp->device), to_mqp(qp));
kfree(qp);
return 0;
}
-static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries)
+static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
{
+ struct mthca_create_cq ucmd;
struct mthca_cq *cq;
int nent;
int err;
+ if (context) {
+ if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+ return ERR_PTR(-EFAULT);
+
+ err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+ to_mucontext(context)->db_tab,
+ ucmd.set_db_index, ucmd.set_db_page);
+ if (err)
+ return ERR_PTR(err);
+
+ err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+ to_mucontext(context)->db_tab,
+ ucmd.arm_db_index, ucmd.arm_db_page);
+ if (err)
+ goto err_unmap_set;
+ }
+
cq = kmalloc(sizeof *cq, GFP_KERNEL);
- if (!cq)
- return ERR_PTR(-ENOMEM);
+ if (!cq) {
+ err = -ENOMEM;
+ goto err_unmap_arm;
+ }
+
+ if (context) {
+ cq->mr.ibmr.lkey = ucmd.lkey;
+ cq->set_ci_db_index = ucmd.set_db_index;
+ cq->arm_db_index = ucmd.arm_db_index;
+ }
for (nent = 1; nent <= entries; nent <<= 1)
; /* nothing */
- err = mthca_init_cq(to_mdev(ibdev), nent, cq);
- if (err) {
- kfree(cq);
- cq = ERR_PTR(err);
+ err = mthca_init_cq(to_mdev(ibdev), nent,
+ context ? to_mucontext(context) : NULL,
+ context ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
+ cq);
+ if (err)
+ goto err_free;
+
+ if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
+ mthca_free_cq(to_mdev(ibdev), cq);
+ goto err_free;
}
return &cq->ibcq;
+
+err_free:
+ kfree(cq);
+
+err_unmap_arm:
+ if (context)
+ mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+ to_mucontext(context)->db_tab, ucmd.arm_db_index);
+
+err_unmap_set:
+ if (context)
+ mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+ to_mucontext(context)->db_tab, ucmd.set_db_index);
+
+ return ERR_PTR(err);
}
static int mthca_destroy_cq(struct ib_cq *cq)
{
+ if (cq->uobject) {
+ mthca_unmap_user_db(to_mdev(cq->device),
+ &to_mucontext(cq->uobject->context)->uar,
+ to_mucontext(cq->uobject->context)->db_tab,
+ to_mcq(cq)->arm_db_index);
+ mthca_unmap_user_db(to_mdev(cq->device),
+ &to_mucontext(cq->uobject->context)->uar,
+ to_mucontext(cq->uobject->context)->db_tab,
+ to_mcq(cq)->set_ci_db_index);
+ }
mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
kfree(cq);
@@ -568,6 +767,87 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd,
return &mr->ibmr;
}
+static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
+ int acc, struct ib_udata *udata)
+{
+ struct mthca_dev *dev = to_mdev(pd->device);
+ struct ib_umem_chunk *chunk;
+ struct mthca_mr *mr;
+ u64 *pages;
+ int shift, n, len;
+ int i, j, k;
+ int err = 0;
+
+ shift = ffs(region->page_size) - 1;
+
+ mr = kmalloc(sizeof *mr, GFP_KERNEL);
+ if (!mr)
+ return ERR_PTR(-ENOMEM);
+
+ n = 0;
+ list_for_each_entry(chunk, &region->chunk_list, list)
+ n += chunk->nents;
+
+ mr->mtt = mthca_alloc_mtt(dev, n);
+ if (IS_ERR(mr->mtt)) {
+ err = PTR_ERR(mr->mtt);
+ goto err;
+ }
+
+ pages = (u64 *) __get_free_page(GFP_KERNEL);
+ if (!pages) {
+ err = -ENOMEM;
+ goto err_mtt;
+ }
+
+ i = n = 0;
+
+ list_for_each_entry(chunk, &region->chunk_list, list)
+ for (j = 0; j < chunk->nmap; ++j) {
+ len = sg_dma_len(&chunk->page_list[j]) >> shift;
+ for (k = 0; k < len; ++k) {
+ pages[i++] = sg_dma_address(&chunk->page_list[j]) +
+ region->page_size * k;
+ /*
+ * Be friendly to WRITE_MTT command
+ * and leave two empty slots for the
+ * index and reserved fields of the
+ * mailbox.
+ */
+ if (i == PAGE_SIZE / sizeof (u64) - 2) {
+ err = mthca_write_mtt(dev, mr->mtt,
+ n, pages, i);
+ if (err)
+ goto mtt_done;
+ n += i;
+ i = 0;
+ }
+ }
+ }
+
+ if (i)
+ err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
+mtt_done:
+ free_page((unsigned long) pages);
+ if (err)
+ goto err_mtt;
+
+ err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, shift, region->virt_base,
+ region->length, convert_access(acc), mr);
+
+ if (err)
+ goto err_mtt;
+
+ return &mr->ibmr;
+
+err_mtt:
+ mthca_free_mtt(dev, mr->mtt);
+
+err:
+ kfree(mr);
+ return ERR_PTR(err);
+}
+
static int mthca_dereg_mr(struct ib_mr *mr)
{
struct mthca_mr *mmr = to_mmr(mr);
@@ -692,6 +972,8 @@ int mthca_register_device(struct mthca_dev *dev)
int i;
strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
+ dev->ib_dev.owner = THIS_MODULE;
+
dev->ib_dev.node_type = IB_NODE_CA;
dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
dev->ib_dev.dma_device = &dev->pdev->dev;
@@ -701,6 +983,9 @@ int mthca_register_device(struct mthca_dev *dev)
dev->ib_dev.modify_port = mthca_modify_port;
dev->ib_dev.query_pkey = mthca_query_pkey;
dev->ib_dev.query_gid = mthca_query_gid;
+ dev->ib_dev.alloc_ucontext = mthca_alloc_ucontext;
+ dev->ib_dev.dealloc_ucontext = mthca_dealloc_ucontext;
+ dev->ib_dev.mmap = mthca_mmap_uar;
dev->ib_dev.alloc_pd = mthca_alloc_pd;
dev->ib_dev.dealloc_pd = mthca_dealloc_pd;
dev->ib_dev.create_ah = mthca_ah_create;
@@ -713,6 +998,7 @@ int mthca_register_device(struct mthca_dev *dev)
dev->ib_dev.poll_cq = mthca_poll_cq;
dev->ib_dev.get_dma_mr = mthca_get_dma_mr;
dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
+ dev->ib_dev.reg_user_mr = mthca_reg_user_mr;
dev->ib_dev.dereg_mr = mthca_dereg_mr;
if (dev->mthca_flags & MTHCA_FLAG_FMR) {
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index 4d976cccb1a..1d032791cc8 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -54,6 +55,14 @@ struct mthca_uar {
int index;
};
+struct mthca_user_db_table;
+
+struct mthca_ucontext {
+ struct ib_ucontext ibucontext;
+ struct mthca_uar uar;
+ struct mthca_user_db_table *db_tab;
+};
+
struct mthca_mtt;
struct mthca_mr {
@@ -83,6 +92,7 @@ struct mthca_pd {
u32 pd_num;
atomic_t sqp_count;
struct mthca_mr ntmr;
+ int privileged;
};
struct mthca_eq {
@@ -167,6 +177,7 @@ struct mthca_cq {
int cqn;
u32 cons_index;
int is_direct;
+ int is_kernel;
/* Next fields are Arbel only */
int set_ci_db_index;
@@ -236,6 +247,11 @@ struct mthca_sqp {
dma_addr_t header_dma;
};
+static inline struct mthca_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
+{
+ return container_of(ibucontext, struct mthca_ucontext, ibucontext);
+}
+
static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibmr)
{
return container_of(ibmr, struct mthca_fmr, ibmr);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 163a8ef4186..f7126b14d5a 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -46,7 +47,9 @@ enum {
MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE,
MTHCA_ACK_REQ_FREQ = 10,
MTHCA_FLIGHT_LIMIT = 9,
- MTHCA_UD_HEADER_SIZE = 72 /* largest UD header possible */
+ MTHCA_UD_HEADER_SIZE = 72, /* largest UD header possible */
+ MTHCA_INLINE_HEADER_SIZE = 4, /* data segment overhead for inline */
+ MTHCA_INLINE_CHUNK_SIZE = 16 /* inline data segment chunk */
};
enum {
@@ -689,7 +692,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
/* leave arbel_sched_queue as 0 */
- qp_context->usr_page = cpu_to_be32(dev->driver_uar.index);
+ if (qp->ibqp.uobject)
+ qp_context->usr_page =
+ cpu_to_be32(to_mucontext(qp->ibqp.uobject->context)->uar.index);
+ else
+ qp_context->usr_page = cpu_to_be32(dev->driver_uar.index);
qp_context->local_qpn = cpu_to_be32(qp->qpn);
if (attr_mask & IB_QP_DEST_QPN) {
qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
@@ -954,6 +961,15 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
qp->send_wqe_offset = ALIGN(qp->rq.max << qp->rq.wqe_shift,
1 << qp->sq.wqe_shift);
+
+ /*
+ * If this is a userspace QP, we don't actually have to
+ * allocate anything. All we need is to calculate the WQE
+ * sizes and the send_wqe_offset, so we're done now.
+ */
+ if (pd->ibpd.uobject)
+ return 0;
+
size = PAGE_ALIGN(qp->send_wqe_offset +
(qp->sq.max << qp->sq.wqe_shift));
@@ -1053,10 +1069,32 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
return err;
}
-static int mthca_alloc_memfree(struct mthca_dev *dev,
+static void mthca_free_wqe_buf(struct mthca_dev *dev,
struct mthca_qp *qp)
{
- int ret = 0;
+ int i;
+ int size = PAGE_ALIGN(qp->send_wqe_offset +
+ (qp->sq.max << qp->sq.wqe_shift));
+
+ if (qp->is_direct) {
+ dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
+ pci_unmap_addr(&qp->queue.direct, mapping));
+ } else {
+ for (i = 0; i < size / PAGE_SIZE; ++i) {
+ dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+ qp->queue.page_list[i].buf,
+ pci_unmap_addr(&qp->queue.page_list[i],
+ mapping));
+ }
+ }
+
+ kfree(qp->wrid);
+}
+
+static int mthca_map_memfree(struct mthca_dev *dev,
+ struct mthca_qp *qp)
+{
+ int ret;
if (mthca_is_memfree(dev)) {
ret = mthca_table_get(dev, dev->qp_table.qp_table, qp->qpn);
@@ -1067,35 +1105,15 @@ static int mthca_alloc_memfree(struct mthca_dev *dev,
if (ret)
goto err_qpc;
- ret = mthca_table_get(dev, dev->qp_table.rdb_table,
- qp->qpn << dev->qp_table.rdb_shift);
- if (ret)
- goto err_eqpc;
-
- qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
- qp->qpn, &qp->rq.db);
- if (qp->rq.db_index < 0) {
- ret = -ENOMEM;
- goto err_rdb;
- }
+ ret = mthca_table_get(dev, dev->qp_table.rdb_table,
+ qp->qpn << dev->qp_table.rdb_shift);
+ if (ret)
+ goto err_eqpc;
- qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
- qp->qpn, &qp->sq.db);
- if (qp->sq.db_index < 0) {
- ret = -ENOMEM;
- goto err_rq_db;
- }
}
return 0;
-err_rq_db:
- mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
-
-err_rdb:
- mthca_table_put(dev, dev->qp_table.rdb_table,
- qp->qpn << dev->qp_table.rdb_shift);
-
err_eqpc:
mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
@@ -1105,6 +1123,35 @@ err_qpc:
return ret;
}
+static void mthca_unmap_memfree(struct mthca_dev *dev,
+ struct mthca_qp *qp)
+{
+ mthca_table_put(dev, dev->qp_table.rdb_table,
+ qp->qpn << dev->qp_table.rdb_shift);
+ mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
+ mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
+}
+
+static int mthca_alloc_memfree(struct mthca_dev *dev,
+ struct mthca_qp *qp)
+{
+ int ret = 0;
+
+ if (mthca_is_memfree(dev)) {
+ qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
+ qp->qpn, &qp->rq.db);
+ if (qp->rq.db_index < 0)
+ return ret;
+
+ qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
+ qp->qpn, &qp->sq.db);
+ if (qp->sq.db_index < 0)
+ mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
+ }
+
+ return ret;
+}
+
static void mthca_free_memfree(struct mthca_dev *dev,
struct mthca_qp *qp)
{
@@ -1112,11 +1159,6 @@ static void mthca_free_memfree(struct mthca_dev *dev,
mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index);
mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
}
-
- mthca_table_put(dev, dev->qp_table.rdb_table,
- qp->qpn << dev->qp_table.rdb_shift);
- mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
- mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
}
static void mthca_wq_init(struct mthca_wq* wq)
@@ -1147,13 +1189,28 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
mthca_wq_init(&qp->sq);
mthca_wq_init(&qp->rq);
- ret = mthca_alloc_memfree(dev, qp);
+ ret = mthca_map_memfree(dev, qp);
if (ret)
return ret;
ret = mthca_alloc_wqe_buf(dev, pd, qp);
if (ret) {
- mthca_free_memfree(dev, qp);
+ mthca_unmap_memfree(dev, qp);
+ return ret;
+ }
+
+ /*
+ * If this is a userspace QP, we're done now. The doorbells
+ * will be allocated and buffers will be initialized in
+ * userspace.
+ */
+ if (pd->ibpd.uobject)
+ return 0;
+
+ ret = mthca_alloc_memfree(dev, qp);
+ if (ret) {
+ mthca_free_wqe_buf(dev, qp);
+ mthca_unmap_memfree(dev, qp);
return ret;
}
@@ -1186,22 +1243,39 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
return 0;
}
-static void mthca_align_qp_size(struct mthca_dev *dev, struct mthca_qp *qp)
+static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
+ struct mthca_qp *qp)
{
- int i;
-
- if (!mthca_is_memfree(dev))
- return;
+ /* Sanity check QP size before proceeding */
+ if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 ||
+ cap->max_send_sge > 64 || cap->max_recv_sge > 64)
+ return -EINVAL;
- for (i = 0; 1 << i < qp->rq.max; ++i)
- ; /* nothing */
+ if (mthca_is_memfree(dev)) {
+ qp->rq.max = cap->max_recv_wr ?
+ roundup_pow_of_two(cap->max_recv_wr) : 0;
+ qp->sq.max = cap->max_send_wr ?
+ roundup_pow_of_two(cap->max_send_wr) : 0;
+ } else {
+ qp->rq.max = cap->max_recv_wr;
+ qp->sq.max = cap->max_send_wr;
+ }
- qp->rq.max = 1 << i;
+ qp->rq.max_gs = cap->max_recv_sge;
+ qp->sq.max_gs = max_t(int, cap->max_send_sge,
+ ALIGN(cap->max_inline_data + MTHCA_INLINE_HEADER_SIZE,
+ MTHCA_INLINE_CHUNK_SIZE) /
+ sizeof (struct mthca_data_seg));
- for (i = 0; 1 << i < qp->sq.max; ++i)
- ; /* nothing */
+ /*
+ * For MLX transport we need 2 extra S/G entries:
+ * one for the header and one for the checksum at the end
+ */
+ if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) ||
+ qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg)
+ return -EINVAL;
- qp->sq.max = 1 << i;
+ return 0;
}
int mthca_alloc_qp(struct mthca_dev *dev,
@@ -1210,11 +1284,14 @@ int mthca_alloc_qp(struct mthca_dev *dev,
struct mthca_cq *recv_cq,
enum ib_qp_type type,
enum ib_sig_type send_policy,
+ struct ib_qp_cap *cap,
struct mthca_qp *qp)
{
int err;
- mthca_align_qp_size(dev, qp);
+ err = mthca_set_qp_size(dev, cap, qp);
+ if (err)
+ return err;
switch (type) {
case IB_QPT_RC: qp->transport = RC; break;
@@ -1247,14 +1324,17 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
enum ib_sig_type send_policy,
+ struct ib_qp_cap *cap,
int qpn,
int port,
struct mthca_sqp *sqp)
{
- int err = 0;
u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
+ int err;
- mthca_align_qp_size(dev, &sqp->qp);
+ err = mthca_set_qp_size(dev, cap, &sqp->qp);
+ if (err)
+ return err;
sqp->header_buf_size = sqp->qp.sq.max * MTHCA_UD_HEADER_SIZE;
sqp->header_buf = dma_alloc_coherent(&dev->pdev->dev, sqp->header_buf_size,
@@ -1313,8 +1393,6 @@ void mthca_free_qp(struct mthca_dev *dev,
struct mthca_qp *qp)
{
u8 status;
- int size;
- int i;
struct mthca_cq *send_cq;
struct mthca_cq *recv_cq;
@@ -1344,31 +1422,22 @@ void mthca_free_qp(struct mthca_dev *dev,
if (qp->state != IB_QPS_RESET)
mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
- mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn);
- if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
- mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn);
-
- mthca_free_mr(dev, &qp->mr);
-
- size = PAGE_ALIGN(qp->send_wqe_offset +
- (qp->sq.max << qp->sq.wqe_shift));
+ /*
+ * If this is a userspace QP, the buffers, MR, CQs and so on
+ * will be cleaned up in userspace, so all we have to do is
+ * unref the mem-free tables and free the QPN in our table.
+ */
+ if (!qp->ibqp.uobject) {
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn);
+ if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
+ mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn);
- if (qp->is_direct) {
- pci_free_consistent(dev->pdev, size,
- qp->queue.direct.buf,
- pci_unmap_addr(&qp->queue.direct, mapping));
- } else {
- for (i = 0; i < size / PAGE_SIZE; ++i) {
- pci_free_consistent(dev->pdev, PAGE_SIZE,
- qp->queue.page_list[i].buf,
- pci_unmap_addr(&qp->queue.page_list[i],
- mapping));
- }
+ mthca_free_mr(dev, &qp->mr);
+ mthca_free_memfree(dev, qp);
+ mthca_free_wqe_buf(dev, qp);
}
- kfree(qp->wrid);
-
- mthca_free_memfree(dev, qp);
+ mthca_unmap_memfree(dev, qp);
if (is_sqp(dev, qp)) {
atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count));
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
new file mode 100644
index 00000000000..3024c1b4547
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef MTHCA_USER_H
+#define MTHCA_USER_H
+
+#include <linux/types.h>
+
+/*
+ * Make sure that all structs defined in this file remain laid out so
+ * that they pack the same way on 32-bit and 64-bit architectures (to
+ * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+ * In particular do not use pointer types -- pass pointers in __u64
+ * instead.
+ */
+
+struct mthca_alloc_ucontext_resp {
+ __u32 qp_tab_size;
+ __u32 uarc_size;
+};
+
+struct mthca_alloc_pd_resp {
+ __u32 pdn;
+ __u32 reserved;
+};
+
+struct mthca_create_cq {
+ __u32 lkey;
+ __u32 pdn;
+ __u64 arm_db_page;
+ __u64 set_db_page;
+ __u32 arm_db_index;
+ __u32 set_db_index;
+};
+
+struct mthca_create_cq_resp {
+ __u32 cqn;
+ __u32 reserved;
+};
+
+struct mthca_create_qp {
+ __u32 lkey;
+ __u32 reserved;
+ __u64 sq_db_page;
+ __u64 rq_db_page;
+ __u32 sq_db_index;
+ __u32 rq_db_index;
+};
+
+#endif /* MTHCA_USER_H */
diff --git a/drivers/infiniband/include/ib_user_verbs.h b/drivers/infiniband/include/ib_user_verbs.h
new file mode 100644
index 00000000000..7c613706af7
--- /dev/null
+++ b/drivers/infiniband/include/ib_user_verbs.h
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: ib_user_verbs.h 2708 2005-06-24 17:27:21Z roland $
+ */
+
+#ifndef IB_USER_VERBS_H
+#define IB_USER_VERBS_H
+
+#include <linux/types.h>
+
+/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define IB_USER_VERBS_ABI_VERSION 1
+
+enum {
+ IB_USER_VERBS_CMD_QUERY_PARAMS,
+ IB_USER_VERBS_CMD_GET_CONTEXT,
+ IB_USER_VERBS_CMD_QUERY_DEVICE,
+ IB_USER_VERBS_CMD_QUERY_PORT,
+ IB_USER_VERBS_CMD_QUERY_GID,
+ IB_USER_VERBS_CMD_QUERY_PKEY,
+ IB_USER_VERBS_CMD_ALLOC_PD,
+ IB_USER_VERBS_CMD_DEALLOC_PD,
+ IB_USER_VERBS_CMD_CREATE_AH,
+ IB_USER_VERBS_CMD_MODIFY_AH,
+ IB_USER_VERBS_CMD_QUERY_AH,
+ IB_USER_VERBS_CMD_DESTROY_AH,
+ IB_USER_VERBS_CMD_REG_MR,
+ IB_USER_VERBS_CMD_REG_SMR,
+ IB_USER_VERBS_CMD_REREG_MR,
+ IB_USER_VERBS_CMD_QUERY_MR,
+ IB_USER_VERBS_CMD_DEREG_MR,
+ IB_USER_VERBS_CMD_ALLOC_MW,
+ IB_USER_VERBS_CMD_BIND_MW,
+ IB_USER_VERBS_CMD_DEALLOC_MW,
+ IB_USER_VERBS_CMD_CREATE_CQ,
+ IB_USER_VERBS_CMD_RESIZE_CQ,
+ IB_USER_VERBS_CMD_DESTROY_CQ,
+ IB_USER_VERBS_CMD_POLL_CQ,
+ IB_USER_VERBS_CMD_PEEK_CQ,
+ IB_USER_VERBS_CMD_REQ_NOTIFY_CQ,
+ IB_USER_VERBS_CMD_CREATE_QP,
+ IB_USER_VERBS_CMD_QUERY_QP,
+ IB_USER_VERBS_CMD_MODIFY_QP,
+ IB_USER_VERBS_CMD_DESTROY_QP,
+ IB_USER_VERBS_CMD_POST_SEND,
+ IB_USER_VERBS_CMD_POST_RECV,
+ IB_USER_VERBS_CMD_ATTACH_MCAST,
+ IB_USER_VERBS_CMD_DETACH_MCAST
+};
+
+/*
+ * Make sure that all structs defined in this file remain laid out so
+ * that they pack the same way on 32-bit and 64-bit architectures (to
+ * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+ * In particular do not use pointer types -- pass pointers in __u64
+ * instead.
+ */
+
+struct ib_uverbs_async_event_desc {
+ __u64 element;
+ __u32 event_type; /* enum ib_event_type */
+ __u32 reserved;
+};
+
+struct ib_uverbs_comp_event_desc {
+ __u64 cq_handle;
+};
+
+/*
+ * All commands from userspace should start with a __u32 command field
+ * followed by __u16 in_words and out_words fields (which give the
+ * length of the command block and response buffer if any in 32-bit
+ * words). The kernel driver will read these fields first and read
+ * the rest of the command struct based on these value.
+ */
+
+struct ib_uverbs_cmd_hdr {
+ __u32 command;
+ __u16 in_words;
+ __u16 out_words;
+};
+
+/*
+ * No driver_data for "query params" command, since this is intended
+ * to be a core function with no possible device dependence.
+ */
+struct ib_uverbs_query_params {
+ __u64 response;
+};
+
+struct ib_uverbs_query_params_resp {
+ __u32 num_cq_events;
+};
+
+struct ib_uverbs_get_context {
+ __u64 response;
+ __u64 cq_fd_tab;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_get_context_resp {
+ __u32 async_fd;
+ __u32 reserved;
+};
+
+struct ib_uverbs_query_device {
+ __u64 response;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_device_resp {
+ __u64 fw_ver;
+ __u64 node_guid;
+ __u64 sys_image_guid;
+ __u64 max_mr_size;
+ __u64 page_size_cap;
+ __u32 vendor_id;
+ __u32 vendor_part_id;
+ __u32 hw_ver;
+ __u32 max_qp;
+ __u32 max_qp_wr;
+ __u32 device_cap_flags;
+ __u32 max_sge;
+ __u32 max_sge_rd;
+ __u32 max_cq;
+ __u32 max_cqe;
+ __u32 max_mr;
+ __u32 max_pd;
+ __u32 max_qp_rd_atom;
+ __u32 max_ee_rd_atom;
+ __u32 max_res_rd_atom;
+ __u32 max_qp_init_rd_atom;
+ __u32 max_ee_init_rd_atom;
+ __u32 atomic_cap;
+ __u32 max_ee;
+ __u32 max_rdd;
+ __u32 max_mw;
+ __u32 max_raw_ipv6_qp;
+ __u32 max_raw_ethy_qp;
+ __u32 max_mcast_grp;
+ __u32 max_mcast_qp_attach;
+ __u32 max_total_mcast_qp_attach;
+ __u32 max_ah;
+ __u32 max_fmr;
+ __u32 max_map_per_fmr;
+ __u32 max_srq;
+ __u32 max_srq_wr;
+ __u32 max_srq_sge;
+ __u16 max_pkeys;
+ __u8 local_ca_ack_delay;
+ __u8 phys_port_cnt;
+ __u8 reserved[4];
+};
+
+struct ib_uverbs_query_port {
+ __u64 response;
+ __u8 port_num;
+ __u8 reserved[7];
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_port_resp {
+ __u32 port_cap_flags;
+ __u32 max_msg_sz;
+ __u32 bad_pkey_cntr;
+ __u32 qkey_viol_cntr;
+ __u32 gid_tbl_len;
+ __u16 pkey_tbl_len;
+ __u16 lid;
+ __u16 sm_lid;
+ __u8 state;
+ __u8 max_mtu;
+ __u8 active_mtu;
+ __u8 lmc;
+ __u8 max_vl_num;
+ __u8 sm_sl;
+ __u8 subnet_timeout;
+ __u8 init_type_reply;
+ __u8 active_width;
+ __u8 active_speed;
+ __u8 phys_state;
+ __u8 reserved[3];
+};
+
+struct ib_uverbs_query_gid {
+ __u64 response;
+ __u8 port_num;
+ __u8 index;
+ __u8 reserved[6];
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_gid_resp {
+ __u8 gid[16];
+};
+
+struct ib_uverbs_query_pkey {
+ __u64 response;
+ __u8 port_num;
+ __u8 index;
+ __u8 reserved[6];
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_pkey_resp {
+ __u16 pkey;
+ __u16 reserved;
+};
+
+struct ib_uverbs_alloc_pd {
+ __u64 response;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_alloc_pd_resp {
+ __u32 pd_handle;
+};
+
+struct ib_uverbs_dealloc_pd {
+ __u32 pd_handle;
+};
+
+struct ib_uverbs_reg_mr {
+ __u64 response;
+ __u64 start;
+ __u64 length;
+ __u64 hca_va;
+ __u32 pd_handle;
+ __u32 access_flags;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_reg_mr_resp {
+ __u32 mr_handle;
+ __u32 lkey;
+ __u32 rkey;
+};
+
+struct ib_uverbs_dereg_mr {
+ __u32 mr_handle;
+};
+
+struct ib_uverbs_create_cq {
+ __u64 response;
+ __u64 user_handle;
+ __u32 cqe;
+ __u32 event_handler;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_create_cq_resp {
+ __u32 cq_handle;
+ __u32 cqe;
+};
+
+struct ib_uverbs_destroy_cq {
+ __u32 cq_handle;
+};
+
+struct ib_uverbs_create_qp {
+ __u64 response;
+ __u64 user_handle;
+ __u32 pd_handle;
+ __u32 send_cq_handle;
+ __u32 recv_cq_handle;
+ __u32 srq_handle;
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 max_recv_sge;
+ __u32 max_inline_data;
+ __u8 sq_sig_all;
+ __u8 qp_type;
+ __u8 is_srq;
+ __u8 reserved;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_create_qp_resp {
+ __u32 qp_handle;
+ __u32 qpn;
+};
+
+/*
+ * This struct needs to remain a multiple of 8 bytes to keep the
+ * alignment of the modify QP parameters.
+ */
+struct ib_uverbs_qp_dest {
+ __u8 dgid[16];
+ __u32 flow_label;
+ __u16 dlid;
+ __u16 reserved;
+ __u8 sgid_index;
+ __u8 hop_limit;
+ __u8 traffic_class;
+ __u8 sl;
+ __u8 src_path_bits;
+ __u8 static_rate;
+ __u8 is_global;
+ __u8 port_num;
+};
+
+struct ib_uverbs_modify_qp {
+ struct ib_uverbs_qp_dest dest;
+ struct ib_uverbs_qp_dest alt_dest;
+ __u32 qp_handle;
+ __u32 attr_mask;
+ __u32 qkey;
+ __u32 rq_psn;
+ __u32 sq_psn;
+ __u32 dest_qp_num;
+ __u32 qp_access_flags;
+ __u16 pkey_index;
+ __u16 alt_pkey_index;
+ __u8 qp_state;
+ __u8 cur_qp_state;
+ __u8 path_mtu;
+ __u8 path_mig_state;
+ __u8 en_sqd_async_notify;
+ __u8 max_rd_atomic;
+ __u8 max_dest_rd_atomic;
+ __u8 min_rnr_timer;
+ __u8 port_num;
+ __u8 timeout;
+ __u8 retry_cnt;
+ __u8 rnr_retry;
+ __u8 alt_port_num;
+ __u8 alt_timeout;
+ __u8 reserved[2];
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_modify_qp_resp {
+};
+
+struct ib_uverbs_destroy_qp {
+ __u32 qp_handle;
+};
+
+struct ib_uverbs_attach_mcast {
+ __u8 gid[16];
+ __u32 qp_handle;
+ __u16 mlid;
+ __u16 reserved;
+ __u64 driver_data[0];
+};
+
+struct ib_uverbs_detach_mcast {
+ __u8 gid[16];
+ __u32 qp_handle;
+ __u16 mlid;
+ __u16 reserved;
+ __u64 driver_data[0];
+};
+
+#endif /* IB_USER_VERBS_H */
diff --git a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h
index cf01f044a22..e5bd9a10c20 100644
--- a/drivers/infiniband/include/ib_verbs.h
+++ b/drivers/infiniband/include/ib_verbs.h
@@ -4,6 +4,7 @@
* Copyright (c) 2004 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -41,7 +42,10 @@
#include <linux/types.h>
#include <linux/device.h>
+
#include <asm/atomic.h>
+#include <asm/scatterlist.h>
+#include <asm/uaccess.h>
union ib_gid {
u8 raw[16];
@@ -544,7 +548,7 @@ struct ib_send_wr {
int num_sge;
enum ib_wr_opcode opcode;
int send_flags;
- u32 imm_data;
+ __be32 imm_data;
union {
struct {
u64 remote_addr;
@@ -618,29 +622,86 @@ struct ib_fmr_attr {
u8 page_size;
};
+struct ib_ucontext {
+ struct ib_device *device;
+ struct list_head pd_list;
+ struct list_head mr_list;
+ struct list_head mw_list;
+ struct list_head cq_list;
+ struct list_head qp_list;
+ struct list_head srq_list;
+ struct list_head ah_list;
+ spinlock_t lock;
+};
+
+struct ib_uobject {
+ u64 user_handle; /* handle given to us by userspace */
+ struct ib_ucontext *context; /* associated user context */
+ struct list_head list; /* link to context's list */
+ u32 id; /* index into kernel idr */
+};
+
+struct ib_umem {
+ unsigned long user_base;
+ unsigned long virt_base;
+ size_t length;
+ int offset;
+ int page_size;
+ int writable;
+ struct list_head chunk_list;
+};
+
+struct ib_umem_chunk {
+ struct list_head list;
+ int nents;
+ int nmap;
+ struct scatterlist page_list[0];
+};
+
+struct ib_udata {
+ void __user *inbuf;
+ void __user *outbuf;
+ size_t inlen;
+ size_t outlen;
+};
+
+#define IB_UMEM_MAX_PAGE_CHUNK \
+ ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
+ ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
+ (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
+
+struct ib_umem_object {
+ struct ib_uobject uobject;
+ struct ib_umem umem;
+};
+
struct ib_pd {
- struct ib_device *device;
- atomic_t usecnt; /* count all resources */
+ struct ib_device *device;
+ struct ib_uobject *uobject;
+ atomic_t usecnt; /* count all resources */
};
struct ib_ah {
struct ib_device *device;
struct ib_pd *pd;
+ struct ib_uobject *uobject;
};
typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context);
struct ib_cq {
- struct ib_device *device;
- ib_comp_handler comp_handler;
- void (*event_handler)(struct ib_event *, void *);
- void * cq_context;
- int cqe;
- atomic_t usecnt; /* count number of work queues */
+ struct ib_device *device;
+ struct ib_uobject *uobject;
+ ib_comp_handler comp_handler;
+ void (*event_handler)(struct ib_event *, void *);
+ void * cq_context;
+ int cqe;
+ atomic_t usecnt; /* count number of work queues */
};
struct ib_srq {
struct ib_device *device;
+ struct ib_uobject *uobject;
struct ib_pd *pd;
void *srq_context;
atomic_t usecnt;
@@ -652,6 +713,7 @@ struct ib_qp {
struct ib_cq *send_cq;
struct ib_cq *recv_cq;
struct ib_srq *srq;
+ struct ib_uobject *uobject;
void (*event_handler)(struct ib_event *, void *);
void *qp_context;
u32 qp_num;
@@ -659,16 +721,18 @@ struct ib_qp {
};
struct ib_mr {
- struct ib_device *device;
- struct ib_pd *pd;
- u32 lkey;
- u32 rkey;
- atomic_t usecnt; /* count number of MWs */
+ struct ib_device *device;
+ struct ib_pd *pd;
+ struct ib_uobject *uobject;
+ u32 lkey;
+ u32 rkey;
+ atomic_t usecnt; /* count number of MWs */
};
struct ib_mw {
struct ib_device *device;
struct ib_pd *pd;
+ struct ib_uobject *uobject;
u32 rkey;
};
@@ -737,7 +801,14 @@ struct ib_device {
int (*modify_port)(struct ib_device *device,
u8 port_num, int port_modify_mask,
struct ib_port_modify *port_modify);
- struct ib_pd * (*alloc_pd)(struct ib_device *device);
+ struct ib_ucontext * (*alloc_ucontext)(struct ib_device *device,
+ struct ib_udata *udata);
+ int (*dealloc_ucontext)(struct ib_ucontext *context);
+ int (*mmap)(struct ib_ucontext *context,
+ struct vm_area_struct *vma);
+ struct ib_pd * (*alloc_pd)(struct ib_device *device,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
int (*dealloc_pd)(struct ib_pd *pd);
struct ib_ah * (*create_ah)(struct ib_pd *pd,
struct ib_ah_attr *ah_attr);
@@ -747,7 +818,8 @@ struct ib_device {
struct ib_ah_attr *ah_attr);
int (*destroy_ah)(struct ib_ah *ah);
struct ib_qp * (*create_qp)(struct ib_pd *pd,
- struct ib_qp_init_attr *qp_init_attr);
+ struct ib_qp_init_attr *qp_init_attr,
+ struct ib_udata *udata);
int (*modify_qp)(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask);
@@ -762,8 +834,9 @@ struct ib_device {
int (*post_recv)(struct ib_qp *qp,
struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr);
- struct ib_cq * (*create_cq)(struct ib_device *device,
- int cqe);
+ struct ib_cq * (*create_cq)(struct ib_device *device, int cqe,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
int (*destroy_cq)(struct ib_cq *cq);
int (*resize_cq)(struct ib_cq *cq, int *cqe);
int (*poll_cq)(struct ib_cq *cq, int num_entries,
@@ -780,6 +853,10 @@ struct ib_device {
int num_phys_buf,
int mr_access_flags,
u64 *iova_start);
+ struct ib_mr * (*reg_user_mr)(struct ib_pd *pd,
+ struct ib_umem *region,
+ int mr_access_flags,
+ struct ib_udata *udata);
int (*query_mr)(struct ib_mr *mr,
struct ib_mr_attr *mr_attr);
int (*dereg_mr)(struct ib_mr *mr);
@@ -817,6 +894,7 @@ struct ib_device {
struct ib_mad *in_mad,
struct ib_mad *out_mad);
+ struct module *owner;
struct class_device class_dev;
struct kobject ports_parent;
struct list_head port_list;
@@ -852,6 +930,16 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client);
void ib_set_client_data(struct ib_device *device, struct ib_client *client,
void *data);
+static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t len)
+{
+ return copy_from_user(dest, udata->inbuf, len) ? -EFAULT : 0;
+}
+
+static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
+{
+ return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
+}
+
int ib_register_event_handler (struct ib_event_handler *event_handler);
int ib_unregister_event_handler(struct ib_event_handler *event_handler);
void ib_dispatch_event(struct ib_event *event);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index ee750e9456d..db9bad2b3d1 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -22,7 +22,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -161,11 +160,6 @@ static dev_link_t *avmcs_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &avmcs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -500,6 +494,7 @@ static struct pcmcia_driver avmcs_driver = {
.name = "avm_cs",
},
.attach = avmcs_attach,
+ .event = avmcs_event,
.detach = avmcs_detach,
.id_table = avmcs_ids,
};
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 67c60e04a37..0e22991635e 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -21,7 +21,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -183,11 +182,6 @@ static dev_link_t *avma1cs_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &avma1cs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -514,6 +508,7 @@ static struct pcmcia_driver avma1cs_driver = {
.name = "avma1_cs",
},
.attach = avma1cs_attach,
+ .event = avma1cs_event,
.detach = avma1cs_detach,
.id_table = avma1cs_ids,
};
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 9146be54704..6fc6868de0b 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -47,7 +47,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -212,11 +211,6 @@ static dev_link_t *elsa_cs_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &elsa_cs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -521,6 +515,7 @@ static struct pcmcia_driver elsa_cs_driver = {
.name = "elsa_cs",
},
.attach = elsa_cs_attach,
+ .event = elsa_cs_event,
.detach = elsa_cs_detach,
.id_table = elsa_ids,
};
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index ac899503a74..bab35688648 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -279,7 +279,8 @@ BChannel_proc_xmt(struct BCState *bcs)
if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags))
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
if (!test_bit(BC_FLG_ACTIV, &bcs->Flag)) {
- if (!test_bit(BC_FLG_BUSY, &bcs->Flag) && (!skb_queue_len(&bcs->squeue))) {
+ if (!test_bit(BC_FLG_BUSY, &bcs->Flag) &&
+ skb_queue_empty(&bcs->squeue)) {
st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL);
}
}
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 9022583fd6a..1615c1a76ab 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -108,7 +108,8 @@ static int l2addrsize(struct Layer2 *l2);
static void
set_peer_busy(struct Layer2 *l2) {
test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
- if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
+ if (!skb_queue_empty(&l2->i_queue) ||
+ !skb_queue_empty(&l2->ui_queue))
test_and_set_bit(FLG_L2BLOCK, &l2->flag);
}
@@ -754,7 +755,7 @@ l2_restart_multi(struct FsmInst *fi, int event, void *arg)
st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL);
if ((ST_L2_7==state) || (ST_L2_8 == state))
- if (skb_queue_len(&st->l2.i_queue) && cansend(st))
+ if (!skb_queue_empty(&st->l2.i_queue) && cansend(st))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
}
@@ -810,7 +811,7 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
if (pr != -1)
st->l2.l2l3(st, pr, NULL);
- if (skb_queue_len(&st->l2.i_queue) && cansend(st))
+ if (!skb_queue_empty(&st->l2.i_queue) && cansend(st))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
}
@@ -1014,7 +1015,7 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
if(typ != RR) FsmDelTimer(&st->l2.t203, 9);
restart_t200(st, 12);
}
- if (skb_queue_len(&st->l2.i_queue) && (typ == RR))
+ if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
} else
nrerrorrecovery(fi);
@@ -1120,7 +1121,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
return;
}
- if (skb_queue_len(&st->l2.i_queue) && (fi->state == ST_L2_7))
+ if (!skb_queue_empty(&st->l2.i_queue) && (fi->state == ST_L2_7))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag))
enquiry_cr(st, RR, RSP, 0);
@@ -1138,7 +1139,7 @@ l2_got_tei(struct FsmInst *fi, int event, void *arg)
test_and_set_bit(FLG_L3_INIT, &st->l2.flag);
} else
FsmChangeState(fi, ST_L2_4);
- if (skb_queue_len(&st->l2.ui_queue))
+ if (!skb_queue_empty(&st->l2.ui_queue))
tx_ui(st);
}
@@ -1301,7 +1302,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
FsmDelTimer(&st->l2.t203, 13);
FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11);
}
- if (skb_queue_len(&l2->i_queue) && cansend(st))
+ if (!skb_queue_empty(&l2->i_queue) && cansend(st))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
}
@@ -1347,7 +1348,7 @@ l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
}
invoke_retransmission(st, nr);
FsmChangeState(fi, ST_L2_7);
- if (skb_queue_len(&l2->i_queue) && cansend(st))
+ if (!skb_queue_empty(&l2->i_queue) && cansend(st))
st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
} else
nrerrorrecovery(fi);
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index abcc9530eb3..c9917cd2132 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -302,7 +302,7 @@ release_l3_process(struct l3_process *p)
!test_bit(FLG_PTP, &p->st->l2.flag)) {
if (p->debug)
l3_debug(p->st, "release_l3_process: last process");
- if (!skb_queue_len(&p->st->l3.squeue)) {
+ if (skb_queue_empty(&p->st->l3.squeue)) {
if (p->debug)
l3_debug(p->st, "release_l3_process: release link");
if (p->st->protocol != ISDN_PTYPE_NI1)
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 058147a6957..c6b5bf7d2ac 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -47,7 +47,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *sedlbauer_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &sedlbauer_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -634,6 +628,7 @@ static struct pcmcia_driver sedlbauer_driver = {
.name = "sedlbauer_cs",
},
.attach = sedlbauer_attach,
+ .event = sedlbauer_event,
.detach = sedlbauer_detach,
.id_table = sedlbauer_ids,
};
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 107376ff5b9..0ddef1bf778 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -193,11 +192,6 @@ static dev_link_t *teles_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &teles_cs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -501,6 +495,7 @@ static struct pcmcia_driver teles_cs_driver = {
.name = "teles_cs",
},
.attach = teles_attach,
+ .event = teles_cs_event,
.detach = teles_detach,
.id_table = teles_ids,
};
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index ad5aa38fb5a..b37ef1f06b3 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1223,7 +1223,7 @@ isdn_tty_write(struct tty_struct *tty, const u_char * buf, int count)
total += c;
}
atomic_dec(&info->xmit_lock);
- if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue))) {
+ if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue)) {
if (m->mdmreg[REG_DXMT] & BIT_DXMT) {
isdn_tty_senddown(info);
isdn_tty_tint(info);
@@ -1284,7 +1284,7 @@ isdn_tty_flush_chars(struct tty_struct *tty)
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_flush_chars"))
return;
- if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue)))
+ if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue))
isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1);
}
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 9fc0c1e0373..e0d1b01cc74 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -304,12 +304,12 @@ icn_pollbchan_send(int channel, icn_card * card)
isdn_ctrl cmd;
if (!(card->sndcount[channel] || card->xskb[channel] ||
- skb_queue_len(&card->spqueue[channel])))
+ !skb_queue_empty(&card->spqueue[channel])))
return;
if (icn_trymaplock_channel(card, mch)) {
while (sbfree &&
(card->sndcount[channel] ||
- skb_queue_len(&card->spqueue[channel]) ||
+ !skb_queue_empty(&card->spqueue[channel]) ||
card->xskb[channel])) {
spin_lock_irqsave(&card->lock, flags);
if (card->xmit_lock[channel]) {
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index f5ae171dbfe..236291bd48a 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -4,7 +4,7 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_PPC_PMAC) += macio_asic.o
+obj-$(CONFIG_PPC_PMAC) += macio_asic.o macio_sysfs.o
obj-$(CONFIG_PMAC_MEDIABAY) += mediabay.o
obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index d0bda7e3e6a..1ee00334692 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -33,7 +33,7 @@ static int macio_bus_match(struct device *dev, struct device_driver *drv)
{
struct macio_dev * macio_dev = to_macio_device(dev);
struct macio_driver * macio_drv = to_macio_driver(drv);
- const struct of_match * matches = macio_drv->match_table;
+ const struct of_device_id * matches = macio_drv->match_table;
if (!matches)
return 0;
@@ -66,7 +66,7 @@ static int macio_device_probe(struct device *dev)
int error = -ENODEV;
struct macio_driver *drv;
struct macio_dev *macio_dev;
- const struct of_match *match;
+ const struct of_device_id *match;
drv = to_macio_driver(dev->driver);
macio_dev = to_macio_device(dev);
@@ -126,11 +126,85 @@ static int macio_device_resume(struct device * dev)
return 0;
}
+static int macio_hotplug (struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
+{
+ struct macio_dev * macio_dev;
+ struct of_device * of;
+ char *scratch, *compat;
+ int i = 0;
+ int length = 0;
+ int cplen, seen = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ macio_dev = to_macio_device(dev);
+ if (!macio_dev)
+ return -ENODEV;
+
+ of = &macio_dev->ofdev;
+ scratch = buffer;
+
+ /* stuff we want to pass to /sbin/hotplug */
+ envp[i++] = scratch;
+ length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s",
+ of->node->name);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp[i++] = scratch;
+ length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s",
+ of->node->type);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ /* Since the compatible field can contain pretty much anything
+ * it's not really legal to split it out with commas. We split it
+ * up using a number of environment variables instead. */
+
+ compat = (char *) get_property(of->node, "compatible", &cplen);
+ while (compat && cplen > 0) {
+ int l;
+ envp[i++] = scratch;
+ length += scnprintf (scratch, buffer_size - length,
+ "OF_COMPATIBLE_%d=%s", seen, compat);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ length++;
+ scratch += length;
+ l = strlen (compat) + 1;
+ compat += l;
+ cplen -= l;
+ seen++;
+ }
+
+ envp[i++] = scratch;
+ length += scnprintf (scratch, buffer_size - length,
+ "OF_COMPATIBLE_N=%d", seen);
+ if ((buffer_size - length <= 0) || (i >= num_envp))
+ return -ENOMEM;
+ ++length;
+ scratch += length;
+
+ envp[i] = NULL;
+
+ return 0;
+}
+
+extern struct device_attribute macio_dev_attrs[];
+
struct bus_type macio_bus_type = {
.name = "macio",
.match = macio_bus_match,
+ .hotplug = macio_hotplug,
.suspend = macio_device_suspend,
.resume = macio_device_resume,
+ .dev_attrs = macio_dev_attrs,
};
static int __init macio_bus_driver_init(void)
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
new file mode 100644
index 00000000000..97d22bb4516
--- /dev/null
+++ b/drivers/macintosh/macio_sysfs.c
@@ -0,0 +1,50 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+#include <asm/macio.h>
+
+
+#define macio_config_of_attr(field, format_string) \
+static ssize_t \
+field##_show (struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct macio_dev *mdev = to_macio_device (dev); \
+ return sprintf (buf, format_string, mdev->ofdev.node->field); \
+}
+
+static ssize_t
+compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct of_device *of;
+ char *compat;
+ int cplen;
+ int length = 0;
+
+ of = &to_macio_device (dev)->ofdev;
+ compat = (char *) get_property(of->node, "compatible", &cplen);
+ if (!compat) {
+ *buf = '\0';
+ return 0;
+ }
+ while (cplen > 0) {
+ int l;
+ length += sprintf (buf, "%s\n", compat);
+ buf += length;
+ l = strlen (compat) + 1;
+ compat += l;
+ cplen -= l;
+ }
+
+ return length;
+}
+
+macio_config_of_attr (name, "%s\n");
+macio_config_of_attr (type, "%s\n");
+
+struct device_attribute macio_dev_attrs[] = {
+ __ATTR_RO(name),
+ __ATTR_RO(type),
+ __ATTR_RO(compatible),
+ __ATTR_NULL
+};
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 4be709e13ee..7c16c25fc5d 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -642,7 +642,7 @@ static int __pmac media_bay_task(void *x)
}
}
-static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
struct media_bay_info* bay;
u32 __iomem *regbase;
@@ -797,23 +797,20 @@ static struct mb_ops keylargo_mb_ops __pmacdata = {
* Therefore we do it all by polling the media bay once each tick.
*/
-static struct of_match media_bay_match[] =
+static struct of_device_id media_bay_match[] =
{
{
.name = "media-bay",
- .type = OF_ANY_MATCH,
.compatible = "keylargo-media-bay",
.data = &keylargo_mb_ops,
},
{
.name = "media-bay",
- .type = OF_ANY_MATCH,
.compatible = "heathrow-media-bay",
.data = &heathrow_mb_ops,
},
{
.name = "media-bay",
- .type = OF_ANY_MATCH,
.compatible = "ohare-media-bay",
.data = &ohare_mb_ops,
},
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index feb4e241385..703e3197331 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -120,6 +120,7 @@
#include <asm/system.h>
#include <asm/sections.h>
#include <asm/of_device.h>
+#include <asm/macio.h>
#include "therm_pm72.h"
@@ -1986,7 +1987,7 @@ static void fcu_lookup_fans(struct device_node *fcu_node)
}
}
-static int fcu_of_probe(struct of_device* dev, const struct of_match *match)
+static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match)
{
int rc;
@@ -2009,12 +2010,10 @@ static int fcu_of_remove(struct of_device* dev)
return 0;
}
-static struct of_match fcu_of_match[] =
+static struct of_device_id fcu_match[] =
{
{
- .name = OF_ANY_MATCH,
.type = "fcu",
- .compatible = OF_ANY_MATCH
},
{},
};
@@ -2022,7 +2021,7 @@ static struct of_match fcu_of_match[] =
static struct of_platform_driver fcu_of_platform_driver =
{
.name = "temperature",
- .match_table = fcu_of_match,
+ .match_table = fcu_match,
.probe = fcu_of_probe,
.remove = fcu_of_remove
};
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 61400f04015..cbb72eb0426 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -43,6 +43,7 @@
#include <asm/system.h>
#include <asm/sections.h>
#include <asm/of_device.h>
+#include <asm/macio.h>
#define LOG_TEMP 0 /* continously log temperature */
@@ -450,7 +451,7 @@ do_probe( struct i2c_adapter *adapter, int addr, int kind )
/************************************************************************/
static int
-therm_of_probe( struct of_device *dev, const struct of_match *match )
+therm_of_probe( struct of_device *dev, const struct of_device_id *match )
{
return i2c_add_driver( &g4fan_driver );
}
@@ -461,9 +462,8 @@ therm_of_remove( struct of_device *dev )
return i2c_del_driver( &g4fan_driver );
}
-static struct of_match therm_of_match[] = {{
+static struct of_device_id therm_of_match[] = {{
.name = "fan",
- .type = OF_ANY_MATCH,
.compatible = "adm1030"
}, {}
};
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 0c1b8520ef8..785806bdb24 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -63,6 +63,7 @@ struct multipath {
unsigned nr_priority_groups;
struct list_head priority_groups;
unsigned pg_init_required; /* pg_init needs calling? */
+ unsigned pg_init_in_progress; /* Only one pg_init allowed at once */
unsigned nr_valid_paths; /* Total number of usable paths */
struct pgpath *current_pgpath;
@@ -72,7 +73,7 @@ struct multipath {
unsigned queue_io; /* Must we queue all I/O? */
unsigned queue_if_no_path; /* Queue I/O if last path fails? */
- unsigned suspended; /* Has dm core suspended our I/O? */
+ unsigned saved_queue_if_no_path;/* Saved state during suspension */
struct work_struct process_queued_ios;
struct bio_list queued_ios;
@@ -304,11 +305,12 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
m->queue_size--;
if ((pgpath && m->queue_io) ||
- (!pgpath && m->queue_if_no_path && !m->suspended)) {
+ (!pgpath && m->queue_if_no_path)) {
/* Queue for the daemon to resubmit */
bio_list_add(&m->queued_ios, bio);
m->queue_size++;
- if (m->pg_init_required || !m->queue_io)
+ if ((m->pg_init_required && !m->pg_init_in_progress) ||
+ !m->queue_io)
queue_work(kmultipathd, &m->process_queued_ios);
pgpath = NULL;
r = 0;
@@ -333,8 +335,9 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
spin_lock_irqsave(&m->lock, flags);
+ m->saved_queue_if_no_path = m->queue_if_no_path;
m->queue_if_no_path = queue_if_no_path;
- if (!m->queue_if_no_path)
+ if (!m->queue_if_no_path && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
@@ -379,25 +382,31 @@ static void process_queued_ios(void *data)
{
struct multipath *m = (struct multipath *) data;
struct hw_handler *hwh = &m->hw_handler;
- struct pgpath *pgpath;
- unsigned init_required, must_queue = 0;
+ struct pgpath *pgpath = NULL;
+ unsigned init_required = 0, must_queue = 1;
unsigned long flags;
spin_lock_irqsave(&m->lock, flags);
+ if (!m->queue_size)
+ goto out;
+
if (!m->current_pgpath)
__choose_pgpath(m);
pgpath = m->current_pgpath;
- if ((pgpath && m->queue_io) ||
- (!pgpath && m->queue_if_no_path && !m->suspended))
- must_queue = 1;
+ if ((pgpath && !m->queue_io) ||
+ (!pgpath && !m->queue_if_no_path))
+ must_queue = 0;
- init_required = m->pg_init_required;
- if (init_required)
+ if (m->pg_init_required && !m->pg_init_in_progress) {
m->pg_init_required = 0;
+ m->pg_init_in_progress = 1;
+ init_required = 1;
+ }
+out:
spin_unlock_irqrestore(&m->lock, flags);
if (init_required)
@@ -752,6 +761,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
static void multipath_dtr(struct dm_target *ti)
{
struct multipath *m = (struct multipath *) ti->private;
+
+ flush_workqueue(kmultipathd);
free_multipath(m);
}
@@ -765,6 +776,9 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
struct mpath_io *mpio;
struct multipath *m = (struct multipath *) ti->private;
+ if (bio_barrier(bio))
+ return -EOPNOTSUPP;
+
mpio = mempool_alloc(m->mpio_pool, GFP_NOIO);
dm_bio_record(&mpio->details, bio);
@@ -837,7 +851,7 @@ static int reinstate_path(struct pgpath *pgpath)
pgpath->path.is_active = 1;
m->current_pgpath = NULL;
- if (!m->nr_valid_paths++)
+ if (!m->nr_valid_paths++ && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios);
queue_work(kmultipathd, &m->trigger_event);
@@ -963,12 +977,13 @@ void dm_pg_init_complete(struct path *path, unsigned err_flags)
bypass_pg(m, pg, 1);
spin_lock_irqsave(&m->lock, flags);
- if (!err_flags)
- m->queue_io = 0;
- else {
+ if (err_flags) {
m->current_pgpath = NULL;
m->current_pg = NULL;
- }
+ } else if (!m->pg_init_required)
+ m->queue_io = 0;
+
+ m->pg_init_in_progress = 0;
queue_work(kmultipathd, &m->process_queued_ios);
spin_unlock_irqrestore(&m->lock, flags);
}
@@ -988,9 +1003,12 @@ static int do_end_io(struct multipath *m, struct bio *bio,
if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
return error;
+ if (error == -EOPNOTSUPP)
+ return error;
+
spin_lock(&m->lock);
if (!m->nr_valid_paths) {
- if (!m->queue_if_no_path || m->suspended) {
+ if (!m->queue_if_no_path) {
spin_unlock(&m->lock);
return -EIO;
} else {
@@ -1051,27 +1069,27 @@ static int multipath_end_io(struct dm_target *ti, struct bio *bio,
/*
* Suspend can't complete until all the I/O is processed so if
- * the last path failed we will now error any queued I/O.
+ * the last path fails we must error any remaining I/O.
+ * Note that if the freeze_bdev fails while suspending, the
+ * queue_if_no_path state is lost - userspace should reset it.
*/
static void multipath_presuspend(struct dm_target *ti)
{
struct multipath *m = (struct multipath *) ti->private;
- unsigned long flags;
- spin_lock_irqsave(&m->lock, flags);
- m->suspended = 1;
- if (m->queue_if_no_path)
- queue_work(kmultipathd, &m->process_queued_ios);
- spin_unlock_irqrestore(&m->lock, flags);
+ queue_if_no_path(m, 0);
}
+/*
+ * Restore the queue_if_no_path setting.
+ */
static void multipath_resume(struct dm_target *ti)
{
struct multipath *m = (struct multipath *) ti->private;
unsigned long flags;
spin_lock_irqsave(&m->lock, flags);
- m->suspended = 0;
+ m->queue_if_no_path = m->saved_queue_if_no_path;
spin_unlock_irqrestore(&m->lock, flags);
}
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6e3cf7e1345..12031c9d3f1 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1060,6 +1060,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = ms;
+ ti->split_io = ms->rh.region_size;
r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
if (r) {
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 7e691ab9a74..ab54f99b7c3 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -777,7 +777,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
/* Full snapshots are not usable */
if (!s->valid)
- return -1;
+ return -EIO;
/*
* Write to snapshot - higher level takes care of RW/RO
@@ -931,6 +931,10 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
if (!snap->valid)
continue;
+ /* Nothing to do if writing beyond end of snapshot */
+ if (bio->bi_sector >= dm_table_get_size(snap->table))
+ continue;
+
down_write(&snap->lock);
/*
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 18e9b9953fc..a5a4c0ed8a1 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -943,6 +943,7 @@ EXPORT_SYMBOL(dm_vcalloc);
EXPORT_SYMBOL(dm_get_device);
EXPORT_SYMBOL(dm_put_device);
EXPORT_SYMBOL(dm_table_event);
+EXPORT_SYMBOL(dm_table_get_size);
EXPORT_SYMBOL(dm_table_get_mode);
EXPORT_SYMBOL(dm_table_put);
EXPORT_SYMBOL(dm_table_get);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index f6b03957efc..54fabbf0667 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -384,7 +384,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
/* error the io and bail out */
struct dm_io *io = tio->io;
free_tio(tio->io->md, tio);
- dec_pending(io, -EIO);
+ dec_pending(io, r);
bio_put(clone);
}
}
@@ -966,23 +966,20 @@ static void __flush_deferred_io(struct mapped_device *md, struct bio *c)
*/
int dm_swap_table(struct mapped_device *md, struct dm_table *table)
{
- int r;
+ int r = -EINVAL;
down_write(&md->lock);
/* device must be suspended */
- if (!test_bit(DMF_SUSPENDED, &md->flags)) {
- up_write(&md->lock);
- return -EPERM;
- }
+ if (!test_bit(DMF_SUSPENDED, &md->flags))
+ goto out;
__unbind(md);
r = __bind(md, table);
- if (r)
- return r;
+out:
up_write(&md->lock);
- return 0;
+ return r;
}
/*
@@ -1055,14 +1052,17 @@ int dm_suspend(struct mapped_device *md)
if (test_bit(DMF_BLOCK_IO, &md->flags))
goto out_read_unlock;
- error = __lock_fs(md);
- if (error)
- goto out_read_unlock;
-
map = dm_get_table(md);
if (map)
+ /* This does not get reverted if there's an error later. */
dm_table_presuspend_targets(map);
+ error = __lock_fs(md);
+ if (error) {
+ dm_table_put(map);
+ goto out_read_unlock;
+ }
+
up_read(&md->lock);
/*
@@ -1121,7 +1121,6 @@ int dm_suspend(struct mapped_device *md)
return 0;
out_unfreeze:
- /* FIXME Undo dm_table_presuspend_targets */
__unlock_fs(md);
clear_bit(DMF_BLOCK_IO, &md->flags);
out_write_unlock:
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 4adb2843f8b..ab7a1fba442 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,5 @@
/*
- * $Id: ir-common.c,v 1.10 2005/05/22 19:23:39 nsh Exp $
+ * $Id: ir-common.c,v 1.11 2005/07/07 14:44:43 mchehab Exp $
*
* some common structs and functions to handle infrared remotes via
* input layer ...
@@ -46,79 +46,49 @@ module_param(debug, int, 0644);
/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
/* used by old (black) Hauppauge remotes */
IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
- [ 0x00 ] = KEY_KP0, // 0
- [ 0x01 ] = KEY_KP1, // 1
- [ 0x02 ] = KEY_KP2, // 2
- [ 0x03 ] = KEY_KP3, // 3
- [ 0x04 ] = KEY_KP4, // 4
- [ 0x05 ] = KEY_KP5, // 5
- [ 0x06 ] = KEY_KP6, // 6
- [ 0x07 ] = KEY_KP7, // 7
- [ 0x08 ] = KEY_KP8, // 8
- [ 0x09 ] = KEY_KP9, // 9
-
- [ 0x0b ] = KEY_CHANNEL, // channel / program (japan: 11)
- [ 0x0c ] = KEY_POWER, // standby
- [ 0x0d ] = KEY_MUTE, // mute / demute
- [ 0x0f ] = KEY_TV, // display
- [ 0x10 ] = KEY_VOLUMEUP, // volume +
- [ 0x11 ] = KEY_VOLUMEDOWN, // volume -
- [ 0x12 ] = KEY_BRIGHTNESSUP, // brightness +
- [ 0x13 ] = KEY_BRIGHTNESSDOWN, // brightness -
- [ 0x1e ] = KEY_SEARCH, // search +
- [ 0x20 ] = KEY_CHANNELUP, // channel / program +
- [ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
- [ 0x22 ] = KEY_CHANNEL, // alt / channel
- [ 0x23 ] = KEY_LANGUAGE, // 1st / 2nd language
- [ 0x26 ] = KEY_SLEEP, // sleeptimer
- [ 0x2e ] = KEY_MENU, // 2nd controls (USA: menu)
- [ 0x30 ] = KEY_PAUSE, // pause
- [ 0x32 ] = KEY_REWIND, // rewind
- [ 0x33 ] = KEY_GOTO, // go to
- [ 0x35 ] = KEY_PLAY, // play
- [ 0x36 ] = KEY_STOP, // stop
- [ 0x37 ] = KEY_RECORD, // recording
- [ 0x3c ] = KEY_TEXT, // teletext submode (Japan: 12)
- [ 0x3d ] = KEY_SUSPEND, // system standby
-
-#if 0 /* FIXME */
- [ 0x0a ] = KEY_RESERVED, // 1/2/3 digits (japan: 10)
- [ 0x0e ] = KEY_RESERVED, // P.P. (personal preference)
- [ 0x14 ] = KEY_RESERVED, // colour saturation +
- [ 0x15 ] = KEY_RESERVED, // colour saturation -
- [ 0x16 ] = KEY_RESERVED, // bass +
- [ 0x17 ] = KEY_RESERVED, // bass -
- [ 0x18 ] = KEY_RESERVED, // treble +
- [ 0x19 ] = KEY_RESERVED, // treble -
- [ 0x1a ] = KEY_RESERVED, // balance right
- [ 0x1b ] = KEY_RESERVED, // balance left
- [ 0x1c ] = KEY_RESERVED, // contrast +
- [ 0x1d ] = KEY_RESERVED, // contrast -
- [ 0x1f ] = KEY_RESERVED, // tint/hue +
- [ 0x24 ] = KEY_RESERVED, // spacial stereo on/off
- [ 0x25 ] = KEY_RESERVED, // mono / stereo (USA)
- [ 0x27 ] = KEY_RESERVED, // tint / hue -
- [ 0x28 ] = KEY_RESERVED, // RF switch/PIP select
- [ 0x29 ] = KEY_RESERVED, // vote
- [ 0x2a ] = KEY_RESERVED, // timed page/channel clck
- [ 0x2b ] = KEY_RESERVED, // increment (USA)
- [ 0x2c ] = KEY_RESERVED, // decrement (USA)
- [ 0x2d ] = KEY_RESERVED, //
- [ 0x2f ] = KEY_RESERVED, // PIP shift
- [ 0x31 ] = KEY_RESERVED, // erase
- [ 0x34 ] = KEY_RESERVED, // wind
- [ 0x38 ] = KEY_RESERVED, // external 1
- [ 0x39 ] = KEY_RESERVED, // external 2
- [ 0x3a ] = KEY_RESERVED, // PIP display mode
- [ 0x3b ] = KEY_RESERVED, // view data mode / advance
- [ 0x3e ] = KEY_RESERVED, // crispener on/off
- [ 0x3f ] = KEY_RESERVED, // system select
-#endif
+ /* Keys 0 to 9 */
+ [ 0x00 ] = KEY_KP0,
+ [ 0x01 ] = KEY_KP1,
+ [ 0x02 ] = KEY_KP2,
+ [ 0x03 ] = KEY_KP3,
+ [ 0x04 ] = KEY_KP4,
+ [ 0x05 ] = KEY_KP5,
+ [ 0x06 ] = KEY_KP6,
+ [ 0x07 ] = KEY_KP7,
+ [ 0x08 ] = KEY_KP8,
+ [ 0x09 ] = KEY_KP9,
+
+ [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */
+ [ 0x0c ] = KEY_POWER, /* standby */
+ [ 0x0d ] = KEY_MUTE, /* mute / demute */
+ [ 0x0f ] = KEY_TV, /* display */
+ [ 0x10 ] = KEY_VOLUMEUP,
+ [ 0x11 ] = KEY_VOLUMEDOWN,
+ [ 0x12 ] = KEY_BRIGHTNESSUP,
+ [ 0x13 ] = KEY_BRIGHTNESSDOWN,
+ [ 0x1e ] = KEY_SEARCH, /* search + */
+ [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */
+ [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */
+ [ 0x22 ] = KEY_CHANNEL, /* alt / channel */
+ [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */
+ [ 0x26 ] = KEY_SLEEP, /* sleeptimer */
+ [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */
+ [ 0x30 ] = KEY_PAUSE,
+ [ 0x32 ] = KEY_REWIND,
+ [ 0x33 ] = KEY_GOTO,
+ [ 0x35 ] = KEY_PLAY,
+ [ 0x36 ] = KEY_STOP,
+ [ 0x37 ] = KEY_RECORD, /* recording */
+ [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */
+ [ 0x3d ] = KEY_SUSPEND, /* system standby */
+
};
EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [ 18 ] = KEY_KP0,
[ 5 ] = KEY_KP1,
[ 6 ] = KEY_KP2,
[ 7 ] = KEY_KP3,
@@ -128,39 +98,31 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 13 ] = KEY_KP7,
[ 14 ] = KEY_KP8,
[ 15 ] = KEY_KP9,
- [ 18 ] = KEY_KP0,
[ 0 ] = KEY_POWER,
-// [ 27 ] = MTS button
- [ 2 ] = KEY_TUNER, // TV/FM
+ [ 2 ] = KEY_TUNER, /* TV/FM */
[ 30 ] = KEY_VIDEO,
-// [ 22 ] = display button
[ 4 ] = KEY_VOLUMEUP,
[ 8 ] = KEY_VOLUMEDOWN,
[ 12 ] = KEY_CHANNELUP,
[ 16 ] = KEY_CHANNELDOWN,
- [ 3 ] = KEY_ZOOM, // fullscreen
- [ 31 ] = KEY_SUBTITLE, // closed caption/teletext
+ [ 3 ] = KEY_ZOOM, /* fullscreen */
+ [ 31 ] = KEY_SUBTITLE, /* closed caption/teletext */
[ 32 ] = KEY_SLEEP,
-// [ 41 ] = boss key
[ 20 ] = KEY_MUTE,
[ 43 ] = KEY_RED,
[ 44 ] = KEY_GREEN,
[ 45 ] = KEY_YELLOW,
[ 46 ] = KEY_BLUE,
- [ 24 ] = KEY_KPPLUS, //fine tune +
- [ 25 ] = KEY_KPMINUS, //fine tune -
-// [ 42 ] = picture in picture
+ [ 24 ] = KEY_KPPLUS, /* fine tune + */
+ [ 25 ] = KEY_KPMINUS, /* fine tune - */
[ 33 ] = KEY_KPDOT,
[ 19 ] = KEY_KPENTER,
-// [ 17 ] = recall
[ 34 ] = KEY_BACK,
[ 35 ] = KEY_PLAYPAUSE,
[ 36 ] = KEY_NEXT,
-// [ 37 ] = time shifting
[ 38 ] = KEY_STOP,
[ 39 ] = KEY_RECORD
-// [ 40 ] = snapshot
};
EXPORT_SYMBOL_GPL(ir_codes_winfast);
@@ -174,54 +136,61 @@ EXPORT_SYMBOL_GPL(ir_codes_empty);
* slightly different versions), shipped with cx88+ivtv cards.
* almost rc5 coding, but some non-standard keys */
IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
- [ 0x00 ] = KEY_KP0, // 0
- [ 0x01 ] = KEY_KP1, // 1
- [ 0x02 ] = KEY_KP2, // 2
- [ 0x03 ] = KEY_KP3, // 3
- [ 0x04 ] = KEY_KP4, // 4
- [ 0x05 ] = KEY_KP5, // 5
- [ 0x06 ] = KEY_KP6, // 6
- [ 0x07 ] = KEY_KP7, // 7
- [ 0x08 ] = KEY_KP8, // 8
- [ 0x09 ] = KEY_KP9, // 9
- [ 0x0a ] = KEY_TEXT, // keypad asterisk as well
- [ 0x0b ] = KEY_RED, // red button
- [ 0x0c ] = KEY_RADIO, // radio
- [ 0x0d ] = KEY_MENU, // menu
- [ 0x0e ] = KEY_SUBTITLE, // also the # key
- [ 0x0f ] = KEY_MUTE, // mute
- [ 0x10 ] = KEY_VOLUMEUP, // volume +
- [ 0x11 ] = KEY_VOLUMEDOWN, // volume -
- [ 0x12 ] = KEY_PREVIOUS, // previous channel
- [ 0x14 ] = KEY_UP, // up
- [ 0x15 ] = KEY_DOWN, // down
- [ 0x16 ] = KEY_LEFT, // left
- [ 0x17 ] = KEY_RIGHT, // right
- [ 0x18 ] = KEY_VIDEO, // Videos
- [ 0x19 ] = KEY_AUDIO, // Music
- [ 0x1a ] = KEY_MHP, // Pictures - presume this means "Multimedia Home Platform"- no "PICTURES" key in input.h
- [ 0x1b ] = KEY_EPG, // Guide
- [ 0x1c ] = KEY_TV, // TV
- [ 0x1e ] = KEY_NEXTSONG, // skip >|
- [ 0x1f ] = KEY_EXIT, // back/exit
- [ 0x20 ] = KEY_CHANNELUP, // channel / program +
- [ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
- [ 0x22 ] = KEY_CHANNEL, // source (old black remote)
- [ 0x24 ] = KEY_PREVIOUSSONG, // replay |<
- [ 0x25 ] = KEY_ENTER, // OK
- [ 0x26 ] = KEY_SLEEP, // minimize (old black remote)
- [ 0x29 ] = KEY_BLUE, // blue key
- [ 0x2e ] = KEY_GREEN, // green button
- [ 0x30 ] = KEY_PAUSE, // pause
- [ 0x32 ] = KEY_REWIND, // backward <<
- [ 0x34 ] = KEY_FASTFORWARD, // forward >>
- [ 0x35 ] = KEY_PLAY, // play
- [ 0x36 ] = KEY_STOP, // stop
- [ 0x37 ] = KEY_RECORD, // recording
- [ 0x38 ] = KEY_YELLOW, // yellow key
- [ 0x3b ] = KEY_SELECT, // top right button
- [ 0x3c ] = KEY_ZOOM, // full
- [ 0x3d ] = KEY_POWER, // system power (green button)
+ /* Keys 0 to 9 */
+ [ 0x00 ] = KEY_KP0,
+ [ 0x01 ] = KEY_KP1,
+ [ 0x02 ] = KEY_KP2,
+ [ 0x03 ] = KEY_KP3,
+ [ 0x04 ] = KEY_KP4,
+ [ 0x05 ] = KEY_KP5,
+ [ 0x06 ] = KEY_KP6,
+ [ 0x07 ] = KEY_KP7,
+ [ 0x08 ] = KEY_KP8,
+ [ 0x09 ] = KEY_KP9,
+
+ [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */
+ [ 0x0b ] = KEY_RED, /* red button */
+ [ 0x0c ] = KEY_RADIO,
+ [ 0x0d ] = KEY_MENU,
+ [ 0x0e ] = KEY_SUBTITLE, /* also the # key */
+ [ 0x0f ] = KEY_MUTE,
+ [ 0x10 ] = KEY_VOLUMEUP,
+ [ 0x11 ] = KEY_VOLUMEDOWN,
+ [ 0x12 ] = KEY_PREVIOUS, /* previous channel */
+ [ 0x14 ] = KEY_UP,
+ [ 0x15 ] = KEY_DOWN,
+ [ 0x16 ] = KEY_LEFT,
+ [ 0x17 ] = KEY_RIGHT,
+ [ 0x18 ] = KEY_VIDEO, /* Videos */
+ [ 0x19 ] = KEY_AUDIO, /* Music */
+ /* 0x1a: Pictures - presume this means
+ "Multimedia Home Platform" -
+ no "PICTURES" key in input.h
+ */
+ [ 0x1a ] = KEY_MHP,
+
+ [ 0x1b ] = KEY_EPG, /* Guide */
+ [ 0x1c ] = KEY_TV,
+ [ 0x1e ] = KEY_NEXTSONG, /* skip >| */
+ [ 0x1f ] = KEY_EXIT, /* back/exit */
+ [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */
+ [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */
+ [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */
+ [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */
+ [ 0x25 ] = KEY_ENTER, /* OK */
+ [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */
+ [ 0x29 ] = KEY_BLUE, /* blue key */
+ [ 0x2e ] = KEY_GREEN, /* green button */
+ [ 0x30 ] = KEY_PAUSE, /* pause */
+ [ 0x32 ] = KEY_REWIND, /* backward << */
+ [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */
+ [ 0x35 ] = KEY_PLAY,
+ [ 0x36 ] = KEY_STOP,
+ [ 0x37 ] = KEY_RECORD, /* recording */
+ [ 0x38 ] = KEY_YELLOW, /* yellow key */
+ [ 0x3b ] = KEY_SELECT, /* top right button */
+ [ 0x3c ] = KEY_ZOOM, /* full */
+ [ 0x3d ] = KEY_POWER, /* system power (green button) */
};
EXPORT_SYMBOL(ir_codes_hauppauge_new);
@@ -237,9 +206,9 @@ IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
[ 10 ] = KEY_KP8,
[ 18 ] = KEY_KP9,
- [ 3 ] = KEY_TUNER, // TV/FM
- [ 7 ] = KEY_SEARCH, // scan
- [ 28 ] = KEY_ZOOM, // full screen
+ [ 3 ] = KEY_TUNER, /* TV/FM */
+ [ 7 ] = KEY_SEARCH, /* scan */
+ [ 28 ] = KEY_ZOOM, /* full screen */
[ 30 ] = KEY_POWER,
[ 23 ] = KEY_VOLUMEDOWN,
[ 31 ] = KEY_VOLUMEUP,
@@ -247,14 +216,14 @@ IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
[ 22 ] = KEY_CHANNELUP,
[ 24 ] = KEY_MUTE,
- [ 0 ] = KEY_LIST, // source
- [ 19 ] = KEY_INFO, // loop
- [ 16 ] = KEY_LAST, // +100
- [ 13 ] = KEY_CLEAR, // reset
- [ 12 ] = BTN_RIGHT, // fun++
- [ 4 ] = BTN_LEFT, // fun--
- [ 14 ] = KEY_GOTO, // function
- [ 15 ] = KEY_STOP, // freeze
+ [ 0 ] = KEY_LIST, /* source */
+ [ 19 ] = KEY_INFO, /* loop */
+ [ 16 ] = KEY_LAST, /* +100 */
+ [ 13 ] = KEY_CLEAR, /* reset */
+ [ 12 ] = BTN_RIGHT, /* fun++ */
+ [ 4 ] = BTN_LEFT, /* fun-- */
+ [ 14 ] = KEY_GOTO, /* function */
+ [ 15 ] = KEY_STOP, /* freeze */
};
EXPORT_SYMBOL(ir_codes_pixelview);
@@ -321,10 +290,6 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
ir->keypressed = 1;
ir_input_key_event(dev,ir);
}
-#if 0
- /* maybe do something like this ??? */
- input_event(a, EV_IR, ir->ir_type, ir->ir_raw);
-#endif
}
/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 50e8b865401..cd5828b5e9e 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -62,13 +62,15 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
{
unsigned long start;
+ int err;
/* wait for registers to be programmed */
start = jiffies;
while (1) {
- if (saa7146_read(dev, MC2) & 2)
- break;
- if (time_after(jiffies, start + HZ/20)) {
+ err = time_after(jiffies, start + HZ/20);
+ if (saa7146_read(dev, MC2) & 2)
+ break;
+ if (err) {
DEB_S(("timed out while waiting for registers getting programmed\n"));
return -ETIMEDOUT;
}
@@ -79,10 +81,11 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
/* wait for transfer to complete */
start = jiffies;
while (1) {
+ err = time_after(jiffies, start + HZ/4);
if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
break;
saa7146_read(dev, MC2);
- if (time_after(jiffies, start + HZ/4)) {
+ if (err) {
DEB_S(("timed out while waiting for transfer completion\n"));
return -ETIMEDOUT;
}
@@ -512,7 +515,7 @@ int saa7146_register_extension(struct saa7146_extension* ext)
ext->driver.remove = saa7146_remove_one;
printk("saa7146: register extension '%s'.\n",ext->name);
- return pci_module_init(&ext->driver);
+ return pci_register_driver(&ext->driver);
}
int saa7146_unregister_extension(struct saa7146_extension* ext)
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 01387f883cd..3f0ec6be03a 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -40,6 +40,10 @@ comment "Supported BT878 Adapters"
depends on DVB_CORE && PCI
source "drivers/media/dvb/bt8xx/Kconfig"
+comment "Supported Pluto2 Adapters"
+ depends on DVB_CORE && PCI
+source "drivers/media/dvb/pluto2/Kconfig"
+
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 3c6ff161910..a7ad0841e6f 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/
+obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index fafd0ab3a28..d7417eac2ab 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -35,17 +35,3 @@ config DVB_B2C2_FLEXCOP_DEBUG
help
Say Y if you want to enable the module option to control debug messages
of all B2C2 FlexCop drivers.
-
-config DVB_B2C2_SKYSTAR
- tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
- depends on DVB_CORE && PCI
- select DVB_STV0299
- select DVB_MT352
- select DVB_MT312
- select DVB_NXT2002
- help
- Support for the Skystar2 PCI DVB card by Technisat, which
- is equipped with the FlexCopII chipset by B2C2, and
- for the B2C2/BBTI Air2PC-ATSC card.
-
- Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 7703812af34..1a1c3bca55f 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -9,6 +9,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
b2c2-flexcop-usb-objs = flexcop-usb.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
-obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
-
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 773d158032d..a94912ac187 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -108,6 +108,8 @@ void flexcop_device_kfree(struct flexcop_device*);
int flexcop_device_initialize(struct flexcop_device*);
void flexcop_device_exit(struct flexcop_device *fc);
+void flexcop_reset_block_300(struct flexcop_device *fc);
+
/* from flexcop-dma.c */
int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
void flexcop_dma_free(struct flexcop_dma *dma);
@@ -115,7 +117,8 @@ void flexcop_dma_free(struct flexcop_dma *dma);
int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
@@ -151,6 +154,7 @@ int flexcop_sram_init(struct flexcop_device *fc);
/* from flexcop-misc.c */
void flexcop_determine_revision(struct flexcop_device *fc);
void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
/* from flexcop-hw-filter.c */
int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 8d270607536..cf4ed1df608 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -37,22 +37,90 @@ void flexcop_dma_free(struct flexcop_dma *dma)
}
EXPORT_SYMBOL(flexcop_dma_free);
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_config(struct flexcop_device *fc,
+ struct flexcop_dma *dma,
+ flexcop_dma_index_t dma_idx)
{
- flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+ flexcop_ibi_value v0x0,v0x4,v0xc;
+ v0x0.raw = v0x4.raw = v0xc.raw = 0;
- if (no & FC_DMA_1)
- v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
+ v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+ v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
+ v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
- if (no & FC_DMA_2)
- v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
+ if ((dma_idx & FC_DMA_1) == dma_idx) {
+ fc->write_ibi_reg(fc,dma1_000,v0x0);
+ fc->write_ibi_reg(fc,dma1_004,v0x4);
+ fc->write_ibi_reg(fc,dma1_00c,v0xc);
+ } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+ fc->write_ibi_reg(fc,dma2_010,v0x0);
+ fc->write_ibi_reg(fc,dma2_014,v0x4);
+ fc->write_ibi_reg(fc,dma2_01c,v0xc);
+ } else {
+ err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+ return -EINVAL;
+ }
- fc->write_ibi_reg(fc,ctrl_208,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
+EXPORT_SYMBOL(flexcop_dma_config);
+
+/* start the DMA transfers, but not the DMA IRQs */
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ flexcop_dma_addr_index_t index,
+ int onoff)
+{
+ flexcop_ibi_value v0x0,v0xc;
+ flexcop_ibi_register r0x0,r0xc;
+
+ if ((dma_idx & FC_DMA_1) == dma_idx) {
+ r0x0 = dma1_000;
+ r0xc = dma1_00c;
+ } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+ r0x0 = dma2_010;
+ r0xc = dma2_01c;
+ } else {
+ err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ return -EINVAL;
+ }
+
+ v0x0 = fc->read_ibi_reg(fc,r0x0);
+ v0xc = fc->read_ibi_reg(fc,r0xc);
+
+ deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+ deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+
+ if (index & FC_DMA_SUBADDR_0)
+ v0x0.dma_0x0.dma_0start = onoff;
+
+ if (index & FC_DMA_SUBADDR_1)
+ v0xc.dma_0xc.dma_1start = onoff;
+
+ fc->write_ibi_reg(fc,r0x0,v0x0);
+ fc->write_ibi_reg(fc,r0xc,v0xc);
+
+ deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+ deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+ return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_xfer_control);
+
+static int flexcop_dma_remap(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ int onoff)
+{
+ flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+ deb_info("%s\n",__FUNCTION__);
+ v.dma_0xc.remap_enable = onoff;
+ fc->write_ibi_reg(fc,r,v);
+ return 0;
+}
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
@@ -67,75 +135,64 @@ int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t
}
EXPORT_SYMBOL(flexcop_dma_control_size_irq);
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
if (no & FC_DMA_1)
- v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+ v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
if (no & FC_DMA_2)
- v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+ v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
fc->write_ibi_reg(fc,ctrl_208,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
+EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index)
+/* 1 cycles = 1.97 msec */
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ u8 cycles)
{
+ flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
- flexcop_ibi_value v0x0,v0x4,v0xc;
- v0x0.raw = v0x4.raw = v0xc.raw = 0;
-
- v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
- v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
- v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
-
- if (index & FC_DMA_SUBADDR_0)
- v0x0.dma_0x0.dma_0start = 1;
-
- if (index & FC_DMA_SUBADDR_1)
- v0xc.dma_0xc.dma_1start = 1;
-
- if (dma_idx & FC_DMA_1) {
- fc->write_ibi_reg(fc,dma1_000,v0x0);
- fc->write_ibi_reg(fc,dma1_004,v0x4);
- fc->write_ibi_reg(fc,dma1_00c,v0xc);
- } else { /* (dma_idx & FC_DMA_2) */
- fc->write_ibi_reg(fc,dma2_010,v0x0);
- fc->write_ibi_reg(fc,dma2_014,v0x4);
- fc->write_ibi_reg(fc,dma2_01c,v0xc);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config);
+ flexcop_dma_remap(fc,dma_idx,0);
-static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff)
-{
- flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
- v.dma_0xc.remap_enable = onoff;
+ deb_info("%s\n",__FUNCTION__);
+ v.dma_0x4_write.dmatimer = cycles;
fc->write_ibi_reg(fc,r,v);
return 0;
}
+EXPORT_SYMBOL(flexcop_dma_config_timer);
-/* 1 cycles = 1.97 msec */
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles)
+/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
+int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
- flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
- flexcop_dma_remap(fc,dma_idx,0);
+ deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
+ if (no & FC_DMA_1)
+ v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+
+ if (no & FC_DMA_2)
+ v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+
+ fc->write_ibi_reg(fc,ctrl_208,v);
+ deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
- v.dma_0x4_write.dmatimer = cycles >> 1;
- fc->write_ibi_reg(fc,r,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_config_timer);
+EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets)
+int flexcop_dma_config_packet_count(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ u8 packets)
{
flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 2baf43d3ce8..75cf237196e 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -10,6 +10,8 @@
static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
+
+ deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
}
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
@@ -151,7 +153,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
{
int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
- fc->feedcount += onoff ? 1 : -1;
+ fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
if (dvbdmxfeed->index >= max_pid_filter)
fc->extra_feedcount += onoff ? 1 : -1;
@@ -178,8 +180,14 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
/* if it was the first or last feed request change the stream-status */
if (fc->feedcount == onoff) {
flexcop_rcv_data_ctrl(fc,onoff);
- if (fc->stream_control)
+ if (fc->stream_control) /* device specific stream control */
fc->stream_control(fc,onoff);
+
+ /* feeding stopped -> reset the flexcop filter*/
+ if (onoff == 0) {
+ flexcop_reset_block_300(fc);
+ flexcop_hw_filter_init(fc);
+ }
}
return 0;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 23082545651..3a08d38b318 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -65,3 +65,15 @@ void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
flexcop_revision_names[fc->rev],suffix);
}
+
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+{
+ flexcop_ibi_value v;
+ int i;
+ for (i = 0; i < num; i++) {
+ v = fc->read_ibi_reg(fc,reg+4*i);
+ deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+ }
+ deb_rdump("\n");
+}
+EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index ed717c0073d..2f76eb3fea4 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -13,6 +13,10 @@ static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+static int irq_chk_intv;
+module_param(irq_chk_intv, int, 0644);
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
+
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
do { if ((debug & level)) printk(args); } while (0)
@@ -26,6 +30,7 @@ MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported
#define deb_reg(args...) dprintk(0x02,args)
#define deb_ts(args...) dprintk(0x04,args)
#define deb_irq(args...) dprintk(0x08,args)
+#define deb_chk(args...) dprintk(0x10,args)
static int debug = 0;
module_param(debug, int, 0644);
@@ -56,6 +61,10 @@ struct flexcop_pci {
spinlock_t irq_lock;
+ unsigned long last_irq;
+
+ struct work_struct irq_check_work;
+
struct flexcop_device *fc_dev;
};
@@ -88,18 +97,55 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi
return 0;
}
+static void flexcop_pci_irq_check_work(void *data)
+{
+ struct flexcop_pci *fc_pci = data;
+ struct flexcop_device *fc = fc_pci->fc_dev;
+
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+
+ flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
+
+ if (v.sram_dest_reg_714.net_ovflow_error)
+ deb_chk("sram net_ovflow_error\n");
+ if (v.sram_dest_reg_714.media_ovflow_error)
+ deb_chk("sram media_ovflow_error\n");
+ if (v.sram_dest_reg_714.cai_ovflow_error)
+ deb_chk("sram cai_ovflow_error\n");
+ if (v.sram_dest_reg_714.cai_ovflow_error)
+ deb_chk("sram cai_ovflow_error\n");
+
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
+}
+
/* When PID filtering is turned on, we use the timer IRQ, because small amounts
* of data need to be passed to the user space instantly as well. When PID
* filtering is turned off, we use the page-change-IRQ */
-static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
{
struct flexcop_pci *fc_pci = dev_id;
struct flexcop_device *fc = fc_pci->fc_dev;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c);
+ flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
spin_lock_irq(&fc_pci->irq_lock);
+ v = fc->read_ibi_reg(fc,irq_20c);
+
+ /* errors */
+ if (v.irq_20c.Data_receiver_error)
+ deb_chk("data receiver error\n");
+ if (v.irq_20c.Continuity_error_flag)
+ deb_chk("Contunuity error flag is set\n");
+ if (v.irq_20c.LLC_SNAP_FLAG_set)
+ deb_chk("LLC_SNAP_FLAG_set is set\n");
+ if (v.irq_20c.Transport_Error)
+ deb_chk("Transport error\n");
+
+ if ((fc_pci->count % 1000) == 0)
+ deb_chk("%d valid irq took place so far\n",fc_pci->count);
+
if (v.irq_20c.DMA1_IRQ_Status == 1) {
if (fc_pci->active_dma1_addr == 0)
flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
@@ -115,8 +161,9 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
- deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
- v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+ deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
+ jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+ fc_pci->last_irq = jiffies;
/* buffer end was reached, restarted from the beginning
* pass the data from last_cur_pos to the buffer end to the demux
@@ -127,7 +174,6 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
(fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
fc_pci->last_dma1_cur_pos = 0;
- fc_pci->count = 0;
}
if (cur_pos > fc_pci->last_dma1_cur_pos) {
@@ -139,16 +185,14 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
deb_irq("\n");
fc_pci->last_dma1_cur_pos = cur_pos;
- } else
+ fc_pci->count++;
+ } else {
+ deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
ret = IRQ_NONE;
+ }
spin_unlock_irq(&fc_pci->irq_lock);
-/* packet count would be ideal for hw filtering, but it isn't working. Either
- * the data book is wrong, or I'm unable to read it correctly */
-
-/* if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */
-
return ret;
}
@@ -156,30 +200,35 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (onoff) {
- flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
- flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
- flexcop_dma_config_timer(fc,FC_DMA_1,1);
+ flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
+ flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
- if (fc_pci->fc_dev->pid_filtering) {
- fc_pci->last_dma1_cur_pos = 0;
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
- } else {
- fc_pci->active_dma1_addr = 0;
- flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
- }
+ flexcop_dma_config_timer(fc,FC_DMA_1,0);
-/* flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0);
- flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */
+ flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+ deb_irq("DMA xfer enabled\n");
- deb_irq("irqs enabled\n");
+ fc_pci->last_dma1_cur_pos = 0;
+ flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+ deb_irq("IRQ enabled\n");
+
+// fc_pci->active_dma1_addr = 0;
+// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
+
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
} else {
- if (fc_pci->fc_dev->pid_filtering)
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
- else
- flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+ if (irq_chk_intv > 0)
+ cancel_delayed_work(&fc_pci->irq_check_work);
+
+ flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ deb_irq("IRQ disabled\n");
-// flexcop_dma_control_packet_irq(fc,FC_DMA_1,0);
- deb_irq("irqs disabled\n");
+// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+
+ flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+ deb_irq("DMA xfer disabled\n");
}
return 0;
@@ -198,6 +247,7 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
fc_pci->init_state |= FC_PCI_DMA_INIT;
+
goto success;
dma1_free:
flexcop_dma_free(&fc_pci->dma[0]);
@@ -244,7 +294,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
pci_set_drvdata(fc_pci->pdev, fc_pci);
- if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq,
+ if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap;
@@ -324,6 +374,8 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
+ INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
+
goto success;
err_fc_exit:
flexcop_device_exit(fc);
@@ -350,17 +402,17 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
static struct pci_device_id flexcop_pci_tbl[] = {
{ PCI_DEVICE(0x13d0, 0x2103) },
-/* { PCI_DEVICE(0x13d0, 0x2200) }, PCI FlexCopIII ? */
+/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
static struct pci_driver flexcop_pci_driver = {
- .name = "Technisat/B2C2 FlexCop II/IIb/III PCI",
+ .name = "b2c2_flexcop_pci",
.id_table = flexcop_pci_tbl,
- .probe = flexcop_pci_probe,
- .remove = flexcop_pci_remove,
+ .probe = flexcop_pci_probe,
+ .remove = flexcop_pci_remove,
};
static int __init flexcop_pci_module_init(void)
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 75b50f21afe..4ae1eb5bfe9 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -36,555 +36,21 @@ typedef enum {
extern const char *flexcop_device_names[];
/* FlexCop IBI Registers */
+#if defined(__LITTLE_ENDIAN)
+ #include "flexcop_ibi_value_le.h"
+#elif defined(__BIG_ENDIAN)
+ #include "flexcop_ibi_value_be.h"
+#else
+ #error no endian defined
+#endif
-/* flexcop_ibi_reg - a huge union representing the register structure */
-typedef union {
- u32 raw;
-
-/* DMA 0x000 to 0x01c
- * DMA1 0x000 to 0x00c
- * DMA2 0x010 to 0x01c
- */
- struct {
- u32 dma_0start : 1; /* set: data will be delivered to dma1_address0 */
- u32 dma_0No_update : 1; /* set: dma1_cur_address will be updated, unset: no update */
- u32 dma_address0 :30; /* physical/virtual host memory address0 DMA */
- } dma_0x0;
-
- struct {
- u32 DMA_maxpackets : 8; /* (remapped) PCI DMA1 Packet Count Interrupt. This variable
- is able to be read and written while bit(1) of register
- 0x00c (remap_enable) is set. This variable represents
- the number of packets that will be transmitted to the PCI
- host using PCI DMA1 before an interrupt to the PCI is
- asserted. This functionality may be enabled using bit(20)
- of register 0x208. N=0 disables the IRQ. */
- u32 dma_addr_size :24; /* size of memory buffer in DWORDs (bytesize / 4) for DMA */
- } dma_0x4_remap;
-
- struct {
- u32 dma1timer : 7; /* reading PCI DMA1 timer ... when remap_enable is 0 */
- u32 unused : 1;
- u32 dma_addr_size :24;
- } dma_0x4_read;
-
- struct {
- u32 unused : 1;
- u32 dmatimer : 7; /* writing PCI DMA1 timer ... when remap_enable is 0 */
- u32 dma_addr_size :24;
- } dma_0x4_write;
-
- struct {
- u32 unused : 2;
- u32 dma_cur_addr :30; /* current physical host memory address pointer for DMA */
- } dma_0x8;
-
- struct {
- u32 dma_1start : 1; /* set: data will be delivered to dma_address1, when dma_address0 is full */
- u32 remap_enable : 1; /* remap enable for 0x0x4(7:0) */
- u32 dma_address1 :30; /* Physical/virtual address 1 on DMA */
- } dma_0xc;
-
-/* Two-wire Serial Master and Clock 0x100-0x110 */
- struct {
-// u32 slave_transmitter : 1; /* ???*/
- u32 chipaddr : 7; /* two-line serial address of the target slave */
- u32 reserved1 : 1;
- u32 baseaddr : 8; /* address of the location of the read/write operation */
- u32 data1_reg : 8; /* first byte in two-line serial read/write operation */
- u32 working_start : 1; /* when doing a write operation this indicator is 0 when ready
- * set to 1 when doing a write operation */
- u32 twoWS_rw : 1; /* read/write indicator (1 = read, 0 write) */
- u32 total_bytes : 2; /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/
- u32 twoWS_port_reg : 2; /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */
- u32 no_base_addr_ack_error : 1; /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o
- * preceding address assignment write frame
- * ACK_ERROR = 1 when no ACK from slave in the last transaction */
- u32 st_done : 1; /* indicator for transaction is done */
- } tw_sm_c_100;
-
- struct {
- u32 data2_reg : 8; /* 2nd data byte */
- u32 data3_reg : 8; /* 3rd data byte */
- u32 data4_reg : 8; /* 4th data byte */
- u32 exlicit_stops : 1; /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */
- u32 force_stop : 1; /* isolated stop flag */
- u32 unused : 6;
- } tw_sm_c_104;
-
-/* Clock. The register allows the FCIII to convert an incoming Master clock
- * (MCLK) signal into a lower frequency clock through the use of a LowCounter
- * (TLO) and a High- Counter (THI). The time counts for THI and TLO are
- * measured in MCLK; each count represents 4 MCLK input clock cycles.
- *
- * The default output for port #1 is set for Front End Demod communication. (0x108)
- * The default output for port #2 is set for EEPROM communication. (0x10c)
- * The default output for port #3 is set for Tuner communication. (0x110)
- */
- struct {
- u32 thi1 : 6; /* Thi for port #1 (def: 100110b; 38) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #1 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_108;
-
- struct {
- u32 thi1 : 6; /* Thi for port #2 (def: 111001b; 57) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #2 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_10c;
-
- struct {
- u32 thi1 : 6; /* Thi for port #3 (def: 111001b; 57) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #3 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_110;
-
-/* LNB Switch Frequency 0x200
- * Clock that creates the LNB switch tone. The default is set to have a fixed
- * low output (not oscillating) to the LNB_CTL line.
- */
- struct {
- u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */
- u32 LNB_CTLLowCount_sig :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master
- Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */
- u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */
- } lnb_switch_freq_200;
-
-/* ACPI, Peripheral Reset, LNB Polarity
- * ACPI power conservation mode, LNB polarity selection (low or high voltage),
- * and peripheral reset.
- */
- struct {
- u32 ACPI1_sig : 1; /* turn of the power of tuner and LNB, not implemented in FCIII */
- u32 ACPI3_sig : 1; /* turn of power of the complete satelite receiver board (except FCIII) */
- u32 LNB_L_H_sig : 1; /* low or high voltage for LNB. (0 = low, 1 = high) */
- u32 Per_reset_sig : 1; /* misc. init reset (default: 1), to reset set to low and back to high */
- u32 reserved :20;
- u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */
- u32 Rev_N_sig_reserved1 : 2;
- u32 Rev_N_sig_caps : 1; /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */
- u32 Rev_N_sig_reserved2 : 1;
- } misc_204;
-
-/* Control and Status 0x208 to 0x21c */
-/* Gross enable and disable control */
- struct {
- u32 Stream1_filter_sig : 1; /* Stream1 PID filtering */
- u32 Stream2_filter_sig : 1; /* Stream2 PID filtering */
- u32 PCR_filter_sig : 1; /* PCR PID filter */
- u32 PMT_filter_sig : 1; /* PMT PID filter */
-
- u32 EMM_filter_sig : 1; /* EMM PID filter */
- u32 ECM_filter_sig : 1; /* ECM PID filter */
- u32 Null_filter_sig : 1; /* Filters null packets, PID=0x1fff. */
- u32 Mask_filter_sig : 1; /* mask PID filter */
-
- u32 WAN_Enable_sig : 1; /* WAN output line through V8 memory space is activated. */
- u32 WAN_CA_Enable_sig : 1; /* not in FCIII */
- u32 CA_Enable_sig : 1; /* not in FCIII */
- u32 SMC_Enable_sig : 1; /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */
-
- u32 Per_CA_Enable_sig : 1; /* not in FCIII */
- u32 Multi2_Enable_sig : 1; /* ? */
- u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */
- u32 Rcv_Data_sig : 1; /* PID filtering module enable. When this bit is a one, the PID filter will
- examine and process packets according to all other (individual) PID
- filtering controls. If it a zero, no packet processing of any kind will
- take place. All data from the tuner will be thrown away. */
-
- u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI
- * interrupt after the specified count for filling the buffer. */
- u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt
- after a specified amount of time. */
- u32 DMA2_IRQ_Enable_sig : 1; /* same as DMA1_IRQ_Enable_sig but for DMA2 */
- u32 DMA2_Timer_Enable_sig : 1; /* same as DMA1_Timer_Enable_sig but for DMA2 */
-
- u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */
- u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */
- u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the
- PCI host to indicate that mailbox data is available. */
-
- u32 unused : 9;
- } ctrl_208;
-
-/* General status. When a PCI interrupt occurs, this register is read to
- * discover the reason for the interrupt.
- */
- struct {
- u32 DMA1_IRQ_Status : 1; /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */
- u32 DMA1_Timer_Status : 1; /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */
- u32 DMA2_IRQ_Status : 1; /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */
- u32 DMA2_Timer_Status : 1; /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */
- u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */
- u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/
- u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */
- u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */
- u32 Continuity_error_flag : 1; /* 1 indicates a continuity error in the TS stream. */
- u32 LLC_SNAP_FLAG_set : 1; /* 1 indicates that the LCC_SNAP_FLAG was set. */
- u32 Transport_Error : 1; /* When set indicates that an unexpected packet was received. */
- u32 reserved :21;
- } irq_20c;
-
-
-/* Software reset register */
- struct {
- u32 reset_blocks : 8; /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00.
- Each bit location represents a 0x100 block of registers. Writing
- a one in a bit location resets that block of registers and the logic
- that it controls. */
- u32 Block_reset_enable : 8; /* This variable is set to 0xB2 when the register is written. */
- u32 Special_controls :16; /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A;
- Turns off pci encryption => 0xC259 Note: pci_encryption default
- at power-up is ON. */
- } sw_reset_210;
-
- struct {
- u32 vuart_oe_sig : 1; /* When clear, the V8 processor has sole control of the serial UART
- (RS-232 Smart Card interface). When set, the IBI interface
- defined by register 0x600 controls the serial UART. */
- u32 v2WS_oe_sig : 1; /* When clear, the V8 processor has direct control of the Two-line
- Serial Master EEPROM target. When set, the Two-line Serial Master
- EEPROM target interface is controlled by IBI register 0x100. */
- u32 halt_V8_sig : 1; /* When set, contiguous wait states are applied to the V8-space
- bus masters. Once this signal is cleared, normal V8-space
- operations resume. */
- u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry
- to process section packed transport streams. */
- u32 s2p_sel_sig : 1; /* Serial to parallel conversion. When set, polarized transport data
- within the FlexCop3 front end circuitry is converted from a serial
- stream into parallel data before downstream processing otherwise
- interprets the data. */
- u32 unused1 : 3;
- u32 polarity_PS_CLK_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream CLOCK signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream VALID signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream SYNC signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_ERR_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream ERROR signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 unused2 :20;
- } misc_214;
-
-/* Mailbox from V8 to host */
- struct {
- u32 Mailbox_from_V8 :32; /* When this register is written by either the V8 processor or by an
- end host, an interrupt is generated to the PCI host to indicate
- that mailbox data is available. Reading register 20c will clear
- the IRQ. */
- } mbox_v8_to_host_218;
-
-/* Mailbox from host to v8 Mailbox_to_V8
- * Mailbox_to_V8 mailbox storage register
- * used to send messages from PCI to V8. Writing to this register will send an
- * IRQ to the V8. Then it can read the data from here. Reading this register
- * will clear the IRQ. If the V8 is halted and bit 31 of this register is set,
- * then this register is used instead as a direct interface to access the
- * V8space memory.
- */
- struct {
- u32 sysramaccess_data : 8; /* Data byte written or read from the specified address in V8 SysRAM. */
- u32 sysramaccess_addr :15; /* 15 bit address used to access V8 Sys-RAM. */
- u32 unused : 7;
- u32 sysramaccess_write: 1; /* Write flag used to latch data into the V8 SysRAM. */
- u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows
- this IBI register interface to directly drive the V8-space memory. */
- } mbox_host_to_v8_21c;
-
-
-/* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */
- struct {
- u32 Stream1_PID :13; /* Primary use is receiving Net data, so these 13 bits normally
- hold the PID value for the desired network stream. */
- u32 Stream1_trans : 1; /* When set, Net translation will take place for Net data ferried in TS packets. */
- u32 MAC_Multicast_filter : 1; /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */
- u32 debug_flag_pid_saved : 1;
- u32 Stream2_PID :13; /* 13 bits for Stream 2 PID filter value. General use. */
- u32 Stream2_trans : 1; /* When set Tables/CAI translation will take place for the data ferried in
- Stream2_PID TS packets. */
- u32 debug_flag_write_status00 : 1;
- u32 debug_fifo_problem : 1;
- } pid_filter_300;
-
- struct {
- u32 PCR_PID :13; /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */
- u32 PCR_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 debug_overrun3 : 1;
- u32 debug_overrun2 : 1;
- u32 PMT_PID :13; /* stream PID filter value. Primary use is Program Management Table segment filtering. */
- u32 PMT_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 reserved : 2;
- } pid_filter_304;
-
- struct {
- u32 EMM_PID :13; /* EMM PID filter value. Primary use is Entitlement Management Messaging for
- conditional access-related data. */
- u32 EMM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 EMM_filter_4 : 1; /* When set will pass only EMM data possessing the same ID code as the
- first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */
- u32 EMM_filter_6 : 1; /* When set will pass only EMM data possessing the same 6-byte code as the end-users
- complete 6-byte Smart Card ID number. */
- u32 ECM_PID :13; /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional
- access-related data. */
- u32 ECM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 reserved : 2;
- } pid_filter_308;
-
- struct {
- u32 Group_PID :13; /* PID value for group filtering. */
- u32 Group_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 unused1 : 2;
- u32 Group_mask :13; /* Mask value used in logical "and" equation that defines group filtering */
- u32 unused2 : 3;
- } pid_filter_30c_ext_ind_0_7;
-
- struct {
- u32 net_master_read :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_1;
-
- struct {
- u32 net_master_write :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_2;
-
- struct {
- u32 next_net_master_write :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_3;
-
- struct {
- u32 unused1 : 1;
- u32 state_write :10;
- u32 reserved1 : 6; /* default: 000100 */
- u32 stack_read :10;
- u32 reserved2 : 5; /* default: 00100 */
- } pid_filter_30c_ext_ind_4;
-
- struct {
- u32 stack_cnt :10;
- u32 unused :22;
- } pid_filter_30c_ext_ind_5;
-
- struct {
- u32 pid_fsm_save_reg0 : 2;
- u32 pid_fsm_save_reg1 : 2;
- u32 pid_fsm_save_reg2 : 2;
- u32 pid_fsm_save_reg3 : 2;
- u32 pid_fsm_save_reg4 : 2;
- u32 pid_fsm_save_reg300 : 2;
- u32 write_status1 : 2;
- u32 write_status4 : 2;
- u32 data_size_reg :12;
- u32 unused : 4;
- } pid_filter_30c_ext_ind_6;
-
- struct {
- u32 index_reg : 5; /* (Index pointer) Points at an internal PIDn register. A binary code
- representing one of 32 internal PIDn registers as well as its
- corresponding internal MAC_lown register. */
- u32 extra_index_reg : 3; /* This vector is used to select between sets of debug signals routed to register 0x30c. */
- u32 AB_select : 1; /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register
- 0=MAC_highB register, 1=MAC_highA */
- u32 pass_alltables : 1; /* 1=Net packets are not filtered against the Network Table ID found in register 0x400.
- All types of networks (DVB, ATSC, ISDB) are passed. */
- u32 unused :22;
- } index_reg_310;
-
- struct {
- u32 PID :13; /* PID value */
- u32 PID_trans : 1; /* translation will take place for packets filtered */
- u32 PID_enable_bit : 1; /* When set this PID filter is enabled */
- u32 reserved :17;
- } pid_n_reg_314;
-
- struct {
- u32 A4_byte : 8;
- u32 A5_byte : 8;
- u32 A6_byte : 8;
- u32 Enable_bit : 1; /* enabled (1) or disabled (1) */
- u32 HighAB_bit : 1; /* use MAC_highA (1) or MAC_highB (0) as MSB */
- u32 reserved : 6;
- } mac_low_reg_318;
-
- struct {
- u32 A1_byte : 8;
- u32 A2_byte : 8;
- u32 A3_byte : 8;
- u32 reserved : 8;
- } mac_high_reg_31c;
-
-/* Table, SMCID,MACDestination Filters 0x400 to 0x41c */
- struct {
- u32 reserved :16;
#define fc_data_Tag_ID_DVB 0x3e
#define fc_data_Tag_ID_ATSC 0x3f
#define fc_data_Tag_ID_IDSB 0x8b
- u32 data_Tag_ID :16;
- } data_tag_400;
-
- struct {
- u32 Card_IDbyte6 : 8;
- u32 Card_IDbyte5 : 8;
- u32 Card_IDbyte4 : 8;
- u32 Card_IDbyte3 : 8;
- } card_id_408;
-
- struct {
- u32 Card_IDbyte2 : 8;
- u32 Card_IDbyte1 : 8;
- } card_id_40c;
-
- /* holding the unique mac address of the receiver which houses the FlexCopIII */
- struct {
- u32 MAC1 : 8;
- u32 MAC2 : 8;
- u32 MAC3 : 8;
- u32 MAC6 : 8;
- } mac_address_418;
-
- struct {
- u32 MAC7 : 8;
- u32 MAC8 : 8;
- u32 reserved : 16;
- } mac_address_41c;
-
- struct {
- u32 transmitter_data_byte : 8;
- u32 ReceiveDataReady : 1;
- u32 ReceiveByteFrameError: 1;
- u32 txbuffempty : 1;
- u32 reserved :21;
- } ci_600;
-
- struct {
- u32 pi_d : 8;
- u32 pi_ha :20;
- u32 pi_rw : 1;
- u32 pi_component_reg : 3;
- } pi_604;
-
- struct {
- u32 serialReset : 1;
- u32 oncecycle_read : 1;
- u32 Timer_Read_req : 1;
- u32 Timer_Load_req : 1;
- u32 timer_data : 7;
- u32 unused : 1; /* ??? not mentioned in data book */
- u32 Timer_addr : 5;
- u32 reserved : 3;
- u32 pcmcia_a_mod_pwr_n : 1;
- u32 pcmcia_b_mod_pwr_n : 1;
- u32 config_Done_stat : 1;
- u32 config_Init_stat : 1;
- u32 config_Prog_n : 1;
- u32 config_wr_n : 1;
- u32 config_cs_n : 1;
- u32 config_cclk : 1;
- u32 pi_CiMax_IRQ_n : 1;
- u32 pi_timeout_status : 1;
- u32 pi_wait_n : 1;
- u32 pi_busy_n : 1;
- } pi_608;
- struct {
- u32 PID :13;
- u32 key_enable : 1;
#define fc_key_code_default 0x1
#define fc_key_code_even 0x2
#define fc_key_code_odd 0x3
- u32 key_code : 2;
- u32 key_array_col : 3;
- u32 key_array_row : 5;
- u32 dvb_en : 1; /* 0=TS bypasses the Descrambler */
- u32 rw_flag : 1;
- u32 reserved : 6;
- } dvb_reg_60c;
-
-/* SRAM and Output Destination 0x700 to 0x714 */
- struct {
- u32 sram_addr :15;
- u32 sram_rw : 1; /* 0=write, 1=read */
- u32 sram_data : 8;
- u32 sc_xfer_bit : 1;
- u32 reserved1 : 3;
- u32 oe_pin_reg : 1;
- u32 ce_pin_reg : 1;
- u32 reserved2 : 1;
- u32 start_sram_ibi : 1;
- } sram_ctrl_reg_700;
-
- struct {
- u32 net_addr_read :16;
- u32 net_addr_write :16;
- } net_buf_reg_704;
-
- struct {
- u32 cai_read :11;
- u32 reserved1 : 5;
- u32 cai_write :11;
- u32 reserved2 : 6;
- u32 cai_cnt : 4;
- } cai_buf_reg_708;
-
- struct {
- u32 cao_read :11;
- u32 reserved1 : 5;
- u32 cap_write :11;
- u32 reserved2 : 6;
- u32 cao_cnt : 4;
- } cao_buf_reg_70c;
-
- struct {
- u32 media_read :11;
- u32 reserved1 : 5;
- u32 media_write :11;
- u32 reserved2 : 6;
- u32 media_cnt : 4;
- } media_buf_reg_710;
-
- struct {
- u32 NET_Dest : 2;
- u32 CAI_Dest : 2;
- u32 CAO_Dest : 2;
- u32 MEDIA_Dest : 2;
- u32 net_ovflow_error : 1;
- u32 media_ovflow_error : 1;
- u32 cai_ovflow_error : 1;
- u32 cao_ovflow_error : 1;
- u32 ctrl_usb_wan : 1;
- u32 ctrl_sramdma : 1;
- u32 ctrl_maximumfill : 1;
- u32 reserved :17;
- } sram_dest_reg_714;
-
- struct {
- u32 net_cnt :12;
- u32 reserved1 : 4;
- u32 net_addr_read : 1;
- u32 reserved2 : 3;
- u32 net_addr_write : 1;
- u32 reserved3 :11;
- } net_buf_reg_718;
-
- struct {
- u32 wan_speed_sig : 2;
- u32 reserved1 : 6;
- u32 wan_wait_state : 8;
- u32 sram_chip : 2;
- u32 sram_memmap : 2;
- u32 reserved2 : 4;
- u32 wan_pkt_frame : 4;
- u32 reserved3 : 4;
- } wan_ctrl_reg_71c;
-} flexcop_ibi_value;
extern flexcop_ibi_value ibi_zero;
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 0113449abd1..0a78ba3737a 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -545,7 +545,7 @@ static struct usb_device_id flexcop_usb_table [] = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver flexcop_usb_driver = {
.owner = THIS_MODULE,
- .name = "Technisat/B2C2 FlexCop II/IIb/III USB",
+ .name = "b2c2_flexcop_usb",
.probe = flexcop_usb_probe,
.disconnect = flexcop_usb_disconnect,
.id_table = flexcop_usb_table,
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 8b5d14dd36e..12873d43540 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -46,7 +46,7 @@
int b2c2_flexcop_debug;
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
#undef DEBSTATUS
/* global zero for ibi values */
@@ -173,9 +173,20 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
- v210.sw_reset_210.reset_blocks = 0xff;
+ v210.sw_reset_210.reset_block_000 = 1;
+ v210.sw_reset_210.reset_block_100 = 1;
+ v210.sw_reset_210.reset_block_200 = 1;
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.reset_block_400 = 1;
+ v210.sw_reset_210.reset_block_500 = 1;
+ v210.sw_reset_210.reset_block_600 = 1;
+ v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ v210.sw_reset_210.Special_controls = 0xc259;
+
fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
/* reset the periphical devices */
@@ -186,6 +197,25 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,misc_204,v204);
}
+void flexcop_reset_block_300(struct flexcop_device *fc)
+{
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
+ v210 = fc->read_ibi_reg(fc,sw_reset_210);
+
+ deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+
+ fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
+
+ fc->write_ibi_reg(fc,ctrl_208,v208_save);
+}
+EXPORT_SYMBOL(flexcop_reset_block_300);
+
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index caa343a97bd..0cebe1d92e0 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -26,5 +26,6 @@ extern int b2c2_flexcop_debug;
#define deb_i2c(args...) dprintk(0x04,args)
#define deb_ts(args...) dprintk(0x08,args)
#define deb_sram(args...) dprintk(0x10,args)
+#define deb_rdump(args...) dprintk(0x20,args)
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
new file mode 100644
index 00000000000..ed9a6756b19
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+ u32 raw;
+
+ struct {
+ u32 dma_address0 :30;
+ u32 dma_0No_update : 1;
+ u32 dma_0start : 1;
+ } dma_0x0;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 DMA_maxpackets : 8;
+ } dma_0x4_remap;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 unused : 1;
+ u32 dma1timer : 7;
+ } dma_0x4_read;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 dmatimer : 7;
+ u32 unused : 1;
+ } dma_0x4_write;
+
+ struct {
+ u32 dma_cur_addr :30;
+ u32 unused : 2;
+ } dma_0x8;
+
+ struct {
+ u32 dma_address1 :30;
+ u32 remap_enable : 1;
+ u32 dma_1start : 1;
+ } dma_0xc;
+
+ struct {
+ u32 st_done : 1;
+ u32 no_base_addr_ack_error : 1;
+ u32 twoWS_port_reg : 2;
+ u32 total_bytes : 2;
+ u32 twoWS_rw : 1;
+ u32 working_start : 1;
+ u32 data1_reg : 8;
+ u32 baseaddr : 8;
+ u32 reserved1 : 1;
+ u32 chipaddr : 7;
+ } tw_sm_c_100;
+
+ struct {
+ u32 unused : 6;
+ u32 force_stop : 1;
+ u32 exlicit_stops : 1;
+ u32 data4_reg : 8;
+ u32 data3_reg : 8;
+ u32 data2_reg : 8;
+ } tw_sm_c_104;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_108;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_10c;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_110;
+
+ struct {
+ u32 LNB_CTLPrescaler_sig : 2;
+ u32 LNB_CTLLowCount_sig :15;
+ u32 LNB_CTLHighCount_sig :15;
+ } lnb_switch_freq_200;
+
+ struct {
+ u32 Rev_N_sig_reserved2 : 1;
+ u32 Rev_N_sig_caps : 1;
+ u32 Rev_N_sig_reserved1 : 2;
+ u32 Rev_N_sig_revision_hi : 4;
+ u32 reserved :20;
+ u32 Per_reset_sig : 1;
+ u32 LNB_L_H_sig : 1;
+ u32 ACPI3_sig : 1;
+ u32 ACPI1_sig : 1;
+ } misc_204;
+
+ struct {
+ u32 unused : 9;
+ u32 Mailbox_from_V8_Enable_sig : 1;
+ u32 DMA2_Size_IRQ_Enable_sig : 1;
+ u32 DMA1_Size_IRQ_Enable_sig : 1;
+ u32 DMA2_Timer_Enable_sig : 1;
+ u32 DMA2_IRQ_Enable_sig : 1;
+ u32 DMA1_Timer_Enable_sig : 1;
+ u32 DMA1_IRQ_Enable_sig : 1;
+ u32 Rcv_Data_sig : 1;
+ u32 MAC_filter_Mode_sig : 1;
+ u32 Multi2_Enable_sig : 1;
+ u32 Per_CA_Enable_sig : 1;
+ u32 SMC_Enable_sig : 1;
+ u32 CA_Enable_sig : 1;
+ u32 WAN_CA_Enable_sig : 1;
+ u32 WAN_Enable_sig : 1;
+ u32 Mask_filter_sig : 1;
+ u32 Null_filter_sig : 1;
+ u32 ECM_filter_sig : 1;
+ u32 EMM_filter_sig : 1;
+ u32 PMT_filter_sig : 1;
+ u32 PCR_filter_sig : 1;
+ u32 Stream2_filter_sig : 1;
+ u32 Stream1_filter_sig : 1;
+ } ctrl_208;
+
+ struct {
+ u32 reserved :21;
+ u32 Transport_Error : 1;
+ u32 LLC_SNAP_FLAG_set : 1;
+ u32 Continuity_error_flag : 1;
+ u32 Data_receiver_error : 1;
+ u32 Mailbox_from_V8_Status_sig : 1;
+ u32 DMA2_Size_IRQ_Status : 1;
+ u32 DMA1_Size_IRQ_Status : 1;
+ u32 DMA2_Timer_Status : 1;
+ u32 DMA2_IRQ_Status : 1;
+ u32 DMA1_Timer_Status : 1;
+ u32 DMA1_IRQ_Status : 1;
+ } irq_20c;
+
+ struct {
+ u32 Special_controls :16;
+ u32 Block_reset_enable : 8;
+ u32 reset_block_700 : 1;
+ u32 reset_block_600 : 1;
+ u32 reset_block_500 : 1;
+ u32 reset_block_400 : 1;
+ u32 reset_block_300 : 1;
+ u32 reset_block_200 : 1;
+ u32 reset_block_100 : 1;
+ u32 reset_block_000 : 1;
+ } sw_reset_210;
+
+ struct {
+ u32 unused2 :20;
+ u32 polarity_PS_ERR_sig : 1;
+ u32 polarity_PS_SYNC_sig : 1;
+ u32 polarity_PS_VALID_sig : 1;
+ u32 polarity_PS_CLK_sig : 1;
+ u32 unused1 : 3;
+ u32 s2p_sel_sig : 1;
+ u32 section_pkg_enable_sig : 1;
+ u32 halt_V8_sig : 1;
+ u32 v2WS_oe_sig : 1;
+ u32 vuart_oe_sig : 1;
+ } misc_214;
+
+ struct {
+ u32 Mailbox_from_V8 :32;
+ } mbox_v8_to_host_218;
+
+ struct {
+ u32 sysramaccess_busmuster : 1;
+ u32 sysramaccess_write : 1;
+ u32 unused : 7;
+ u32 sysramaccess_addr :15;
+ u32 sysramaccess_data : 8;
+ } mbox_host_to_v8_21c;
+
+ struct {
+ u32 debug_fifo_problem : 1;
+ u32 debug_flag_write_status00 : 1;
+ u32 Stream2_trans : 1;
+ u32 Stream2_PID :13;
+ u32 debug_flag_pid_saved : 1;
+ u32 MAC_Multicast_filter : 1;
+ u32 Stream1_trans : 1;
+ u32 Stream1_PID :13;
+ } pid_filter_300;
+
+ struct {
+ u32 reserved : 2;
+ u32 PMT_trans : 1;
+ u32 PMT_PID :13;
+ u32 debug_overrun2 : 1;
+ u32 debug_overrun3 : 1;
+ u32 PCR_trans : 1;
+ u32 PCR_PID :13;
+ } pid_filter_304;
+
+ struct {
+ u32 reserved : 2;
+ u32 ECM_trans : 1;
+ u32 ECM_PID :13;
+ u32 EMM_filter_6 : 1;
+ u32 EMM_filter_4 : 1;
+ u32 EMM_trans : 1;
+ u32 EMM_PID :13;
+ } pid_filter_308;
+
+ struct {
+ u32 unused2 : 3;
+ u32 Group_mask :13;
+ u32 unused1 : 2;
+ u32 Group_trans : 1;
+ u32 Group_PID :13;
+ } pid_filter_30c_ext_ind_0_7;
+
+ struct {
+ u32 unused :15;
+ u32 net_master_read :17;
+ } pid_filter_30c_ext_ind_1;
+
+ struct {
+ u32 unused :15;
+ u32 net_master_write :17;
+ } pid_filter_30c_ext_ind_2;
+
+ struct {
+ u32 unused :15;
+ u32 next_net_master_write :17;
+ } pid_filter_30c_ext_ind_3;
+
+ struct {
+ u32 reserved2 : 5;
+ u32 stack_read :10;
+ u32 reserved1 : 6;
+ u32 state_write :10;
+ u32 unused1 : 1;
+ } pid_filter_30c_ext_ind_4;
+
+ struct {
+ u32 unused :22;
+ u32 stack_cnt :10;
+ } pid_filter_30c_ext_ind_5;
+
+ struct {
+ u32 unused : 4;
+ u32 data_size_reg :12;
+ u32 write_status4 : 2;
+ u32 write_status1 : 2;
+ u32 pid_fsm_save_reg300 : 2;
+ u32 pid_fsm_save_reg4 : 2;
+ u32 pid_fsm_save_reg3 : 2;
+ u32 pid_fsm_save_reg2 : 2;
+ u32 pid_fsm_save_reg1 : 2;
+ u32 pid_fsm_save_reg0 : 2;
+ } pid_filter_30c_ext_ind_6;
+
+ struct {
+ u32 unused :22;
+ u32 pass_alltables : 1;
+ u32 AB_select : 1;
+ u32 extra_index_reg : 3;
+ u32 index_reg : 5;
+ } index_reg_310;
+
+ struct {
+ u32 reserved :17;
+ u32 PID_enable_bit : 1;
+ u32 PID_trans : 1;
+ u32 PID :13;
+ } pid_n_reg_314;
+
+ struct {
+ u32 reserved : 6;
+ u32 HighAB_bit : 1;
+ u32 Enable_bit : 1;
+ u32 A6_byte : 8;
+ u32 A5_byte : 8;
+ u32 A4_byte : 8;
+ } mac_low_reg_318;
+
+ struct {
+ u32 reserved : 8;
+ u32 A3_byte : 8;
+ u32 A2_byte : 8;
+ u32 A1_byte : 8;
+ } mac_high_reg_31c;
+
+ struct {
+ u32 data_Tag_ID :16;
+ u32 reserved :16;
+ } data_tag_400;
+
+ struct {
+ u32 Card_IDbyte3 : 8;
+ u32 Card_IDbyte4 : 8;
+ u32 Card_IDbyte5 : 8;
+ u32 Card_IDbyte6 : 8;
+ } card_id_408;
+
+ struct {
+ u32 Card_IDbyte1 : 8;
+ u32 Card_IDbyte2 : 8;
+ } card_id_40c;
+
+ struct {
+ u32 MAC6 : 8;
+ u32 MAC3 : 8;
+ u32 MAC2 : 8;
+ u32 MAC1 : 8;
+ } mac_address_418;
+
+ struct {
+ u32 reserved :16;
+ u32 MAC8 : 8;
+ u32 MAC7 : 8;
+ } mac_address_41c;
+
+ struct {
+ u32 reserved :21;
+ u32 txbuffempty : 1;
+ u32 ReceiveByteFrameError : 1;
+ u32 ReceiveDataReady : 1;
+ u32 transmitter_data_byte : 8;
+ } ci_600;
+
+ struct {
+ u32 pi_component_reg : 3;
+ u32 pi_rw : 1;
+ u32 pi_ha :20;
+ u32 pi_d : 8;
+ } pi_604;
+
+ struct {
+ u32 pi_busy_n : 1;
+ u32 pi_wait_n : 1;
+ u32 pi_timeout_status : 1;
+ u32 pi_CiMax_IRQ_n : 1;
+ u32 config_cclk : 1;
+ u32 config_cs_n : 1;
+ u32 config_wr_n : 1;
+ u32 config_Prog_n : 1;
+ u32 config_Init_stat : 1;
+ u32 config_Done_stat : 1;
+ u32 pcmcia_b_mod_pwr_n : 1;
+ u32 pcmcia_a_mod_pwr_n : 1;
+ u32 reserved : 3;
+ u32 Timer_addr : 5;
+ u32 unused : 1;
+ u32 timer_data : 7;
+ u32 Timer_Load_req : 1;
+ u32 Timer_Read_req : 1;
+ u32 oncecycle_read : 1;
+ u32 serialReset : 1;
+ } pi_608;
+
+ struct {
+ u32 reserved : 6;
+ u32 rw_flag : 1;
+ u32 dvb_en : 1;
+ u32 key_array_row : 5;
+ u32 key_array_col : 3;
+ u32 key_code : 2;
+ u32 key_enable : 1;
+ u32 PID :13;
+ } dvb_reg_60c;
+
+ struct {
+ u32 start_sram_ibi : 1;
+ u32 reserved2 : 1;
+ u32 ce_pin_reg : 1;
+ u32 oe_pin_reg : 1;
+ u32 reserved1 : 3;
+ u32 sc_xfer_bit : 1;
+ u32 sram_data : 8;
+ u32 sram_rw : 1;
+ u32 sram_addr :15;
+ } sram_ctrl_reg_700;
+
+ struct {
+ u32 net_addr_write :16;
+ u32 net_addr_read :16;
+ } net_buf_reg_704;
+
+ struct {
+ u32 cai_cnt : 4;
+ u32 reserved2 : 6;
+ u32 cai_write :11;
+ u32 reserved1 : 5;
+ u32 cai_read :11;
+ } cai_buf_reg_708;
+
+ struct {
+ u32 cao_cnt : 4;
+ u32 reserved2 : 6;
+ u32 cap_write :11;
+ u32 reserved1 : 5;
+ u32 cao_read :11;
+ } cao_buf_reg_70c;
+
+ struct {
+ u32 media_cnt : 4;
+ u32 reserved2 : 6;
+ u32 media_write :11;
+ u32 reserved1 : 5;
+ u32 media_read :11;
+ } media_buf_reg_710;
+
+ struct {
+ u32 reserved :17;
+ u32 ctrl_maximumfill : 1;
+ u32 ctrl_sramdma : 1;
+ u32 ctrl_usb_wan : 1;
+ u32 cao_ovflow_error : 1;
+ u32 cai_ovflow_error : 1;
+ u32 media_ovflow_error : 1;
+ u32 net_ovflow_error : 1;
+ u32 MEDIA_Dest : 2;
+ u32 CAO_Dest : 2;
+ u32 CAI_Dest : 2;
+ u32 NET_Dest : 2;
+ } sram_dest_reg_714;
+
+ struct {
+ u32 reserved3 :11;
+ u32 net_addr_write : 1;
+ u32 reserved2 : 3;
+ u32 net_addr_read : 1;
+ u32 reserved1 : 4;
+ u32 net_cnt :12;
+ } net_buf_reg_718;
+
+ struct {
+ u32 reserved3 : 4;
+ u32 wan_pkt_frame : 4;
+ u32 reserved2 : 4;
+ u32 sram_memmap : 2;
+ u32 sram_chip : 2;
+ u32 wan_wait_state : 8;
+ u32 reserved1 : 6;
+ u32 wan_speed_sig : 2;
+ } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
new file mode 100644
index 00000000000..49f2315b6e5
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+ u32 raw;
+
+ struct {
+ u32 dma_0start : 1;
+ u32 dma_0No_update : 1;
+ u32 dma_address0 :30;
+ } dma_0x0;
+
+ struct {
+ u32 DMA_maxpackets : 8;
+ u32 dma_addr_size :24;
+ } dma_0x4_remap;
+
+ struct {
+ u32 dma1timer : 7;
+ u32 unused : 1;
+ u32 dma_addr_size :24;
+ } dma_0x4_read;
+
+ struct {
+ u32 unused : 1;
+ u32 dmatimer : 7;
+ u32 dma_addr_size :24;
+ } dma_0x4_write;
+
+ struct {
+ u32 unused : 2;
+ u32 dma_cur_addr :30;
+ } dma_0x8;
+
+ struct {
+ u32 dma_1start : 1;
+ u32 remap_enable : 1;
+ u32 dma_address1 :30;
+ } dma_0xc;
+
+ struct {
+ u32 chipaddr : 7;
+ u32 reserved1 : 1;
+ u32 baseaddr : 8;
+ u32 data1_reg : 8;
+ u32 working_start : 1;
+ u32 twoWS_rw : 1;
+ u32 total_bytes : 2;
+ u32 twoWS_port_reg : 2;
+ u32 no_base_addr_ack_error : 1;
+ u32 st_done : 1;
+ } tw_sm_c_100;
+
+ struct {
+ u32 data2_reg : 8;
+ u32 data3_reg : 8;
+ u32 data4_reg : 8;
+ u32 exlicit_stops : 1;
+ u32 force_stop : 1;
+ u32 unused : 6;
+ } tw_sm_c_104;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_108;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_10c;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_110;
+
+ struct {
+ u32 LNB_CTLHighCount_sig :15;
+ u32 LNB_CTLLowCount_sig :15;
+ u32 LNB_CTLPrescaler_sig : 2;
+ } lnb_switch_freq_200;
+
+ struct {
+ u32 ACPI1_sig : 1;
+ u32 ACPI3_sig : 1;
+ u32 LNB_L_H_sig : 1;
+ u32 Per_reset_sig : 1;
+ u32 reserved :20;
+ u32 Rev_N_sig_revision_hi : 4;
+ u32 Rev_N_sig_reserved1 : 2;
+ u32 Rev_N_sig_caps : 1;
+ u32 Rev_N_sig_reserved2 : 1;
+ } misc_204;
+
+ struct {
+ u32 Stream1_filter_sig : 1;
+ u32 Stream2_filter_sig : 1;
+ u32 PCR_filter_sig : 1;
+ u32 PMT_filter_sig : 1;
+ u32 EMM_filter_sig : 1;
+ u32 ECM_filter_sig : 1;
+ u32 Null_filter_sig : 1;
+ u32 Mask_filter_sig : 1;
+ u32 WAN_Enable_sig : 1;
+ u32 WAN_CA_Enable_sig : 1;
+ u32 CA_Enable_sig : 1;
+ u32 SMC_Enable_sig : 1;
+ u32 Per_CA_Enable_sig : 1;
+ u32 Multi2_Enable_sig : 1;
+ u32 MAC_filter_Mode_sig : 1;
+ u32 Rcv_Data_sig : 1;
+ u32 DMA1_IRQ_Enable_sig : 1;
+ u32 DMA1_Timer_Enable_sig : 1;
+ u32 DMA2_IRQ_Enable_sig : 1;
+ u32 DMA2_Timer_Enable_sig : 1;
+ u32 DMA1_Size_IRQ_Enable_sig : 1;
+ u32 DMA2_Size_IRQ_Enable_sig : 1;
+ u32 Mailbox_from_V8_Enable_sig : 1;
+ u32 unused : 9;
+ } ctrl_208;
+
+ struct {
+ u32 DMA1_IRQ_Status : 1;
+ u32 DMA1_Timer_Status : 1;
+ u32 DMA2_IRQ_Status : 1;
+ u32 DMA2_Timer_Status : 1;
+ u32 DMA1_Size_IRQ_Status : 1;
+ u32 DMA2_Size_IRQ_Status : 1;
+ u32 Mailbox_from_V8_Status_sig : 1;
+ u32 Data_receiver_error : 1;
+ u32 Continuity_error_flag : 1;
+ u32 LLC_SNAP_FLAG_set : 1;
+ u32 Transport_Error : 1;
+ u32 reserved :21;
+ } irq_20c;
+
+ struct {
+ u32 reset_block_000 : 1;
+ u32 reset_block_100 : 1;
+ u32 reset_block_200 : 1;
+ u32 reset_block_300 : 1;
+ u32 reset_block_400 : 1;
+ u32 reset_block_500 : 1;
+ u32 reset_block_600 : 1;
+ u32 reset_block_700 : 1;
+ u32 Block_reset_enable : 8;
+ u32 Special_controls :16;
+ } sw_reset_210;
+
+ struct {
+ u32 vuart_oe_sig : 1;
+ u32 v2WS_oe_sig : 1;
+ u32 halt_V8_sig : 1;
+ u32 section_pkg_enable_sig : 1;
+ u32 s2p_sel_sig : 1;
+ u32 unused1 : 3;
+ u32 polarity_PS_CLK_sig : 1;
+ u32 polarity_PS_VALID_sig : 1;
+ u32 polarity_PS_SYNC_sig : 1;
+ u32 polarity_PS_ERR_sig : 1;
+ u32 unused2 :20;
+ } misc_214;
+
+ struct {
+ u32 Mailbox_from_V8 :32;
+ } mbox_v8_to_host_218;
+
+ struct {
+ u32 sysramaccess_data : 8;
+ u32 sysramaccess_addr :15;
+ u32 unused : 7;
+ u32 sysramaccess_write : 1;
+ u32 sysramaccess_busmuster : 1;
+ } mbox_host_to_v8_21c;
+
+ struct {
+ u32 Stream1_PID :13;
+ u32 Stream1_trans : 1;
+ u32 MAC_Multicast_filter : 1;
+ u32 debug_flag_pid_saved : 1;
+ u32 Stream2_PID :13;
+ u32 Stream2_trans : 1;
+ u32 debug_flag_write_status00 : 1;
+ u32 debug_fifo_problem : 1;
+ } pid_filter_300;
+
+ struct {
+ u32 PCR_PID :13;
+ u32 PCR_trans : 1;
+ u32 debug_overrun3 : 1;
+ u32 debug_overrun2 : 1;
+ u32 PMT_PID :13;
+ u32 PMT_trans : 1;
+ u32 reserved : 2;
+ } pid_filter_304;
+
+ struct {
+ u32 EMM_PID :13;
+ u32 EMM_trans : 1;
+ u32 EMM_filter_4 : 1;
+ u32 EMM_filter_6 : 1;
+ u32 ECM_PID :13;
+ u32 ECM_trans : 1;
+ u32 reserved : 2;
+ } pid_filter_308;
+
+ struct {
+ u32 Group_PID :13;
+ u32 Group_trans : 1;
+ u32 unused1 : 2;
+ u32 Group_mask :13;
+ u32 unused2 : 3;
+ } pid_filter_30c_ext_ind_0_7;
+
+ struct {
+ u32 net_master_read :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_1;
+
+ struct {
+ u32 net_master_write :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_2;
+
+ struct {
+ u32 next_net_master_write :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_3;
+
+ struct {
+ u32 unused1 : 1;
+ u32 state_write :10;
+ u32 reserved1 : 6;
+ u32 stack_read :10;
+ u32 reserved2 : 5;
+ } pid_filter_30c_ext_ind_4;
+
+ struct {
+ u32 stack_cnt :10;
+ u32 unused :22;
+ } pid_filter_30c_ext_ind_5;
+
+ struct {
+ u32 pid_fsm_save_reg0 : 2;
+ u32 pid_fsm_save_reg1 : 2;
+ u32 pid_fsm_save_reg2 : 2;
+ u32 pid_fsm_save_reg3 : 2;
+ u32 pid_fsm_save_reg4 : 2;
+ u32 pid_fsm_save_reg300 : 2;
+ u32 write_status1 : 2;
+ u32 write_status4 : 2;
+ u32 data_size_reg :12;
+ u32 unused : 4;
+ } pid_filter_30c_ext_ind_6;
+
+ struct {
+ u32 index_reg : 5;
+ u32 extra_index_reg : 3;
+ u32 AB_select : 1;
+ u32 pass_alltables : 1;
+ u32 unused :22;
+ } index_reg_310;
+
+ struct {
+ u32 PID :13;
+ u32 PID_trans : 1;
+ u32 PID_enable_bit : 1;
+ u32 reserved :17;
+ } pid_n_reg_314;
+
+ struct {
+ u32 A4_byte : 8;
+ u32 A5_byte : 8;
+ u32 A6_byte : 8;
+ u32 Enable_bit : 1;
+ u32 HighAB_bit : 1;
+ u32 reserved : 6;
+ } mac_low_reg_318;
+
+ struct {
+ u32 A1_byte : 8;
+ u32 A2_byte : 8;
+ u32 A3_byte : 8;
+ u32 reserved : 8;
+ } mac_high_reg_31c;
+
+ struct {
+ u32 reserved :16;
+ u32 data_Tag_ID :16;
+ } data_tag_400;
+
+ struct {
+ u32 Card_IDbyte6 : 8;
+ u32 Card_IDbyte5 : 8;
+ u32 Card_IDbyte4 : 8;
+ u32 Card_IDbyte3 : 8;
+ } card_id_408;
+
+ struct {
+ u32 Card_IDbyte2 : 8;
+ u32 Card_IDbyte1 : 8;
+ } card_id_40c;
+
+ struct {
+ u32 MAC1 : 8;
+ u32 MAC2 : 8;
+ u32 MAC3 : 8;
+ u32 MAC6 : 8;
+ } mac_address_418;
+
+ struct {
+ u32 MAC7 : 8;
+ u32 MAC8 : 8;
+ u32 reserved :16;
+ } mac_address_41c;
+
+ struct {
+ u32 transmitter_data_byte : 8;
+ u32 ReceiveDataReady : 1;
+ u32 ReceiveByteFrameError : 1;
+ u32 txbuffempty : 1;
+ u32 reserved :21;
+ } ci_600;
+
+ struct {
+ u32 pi_d : 8;
+ u32 pi_ha :20;
+ u32 pi_rw : 1;
+ u32 pi_component_reg : 3;
+ } pi_604;
+
+ struct {
+ u32 serialReset : 1;
+ u32 oncecycle_read : 1;
+ u32 Timer_Read_req : 1;
+ u32 Timer_Load_req : 1;
+ u32 timer_data : 7;
+ u32 unused : 1;
+ u32 Timer_addr : 5;
+ u32 reserved : 3;
+ u32 pcmcia_a_mod_pwr_n : 1;
+ u32 pcmcia_b_mod_pwr_n : 1;
+ u32 config_Done_stat : 1;
+ u32 config_Init_stat : 1;
+ u32 config_Prog_n : 1;
+ u32 config_wr_n : 1;
+ u32 config_cs_n : 1;
+ u32 config_cclk : 1;
+ u32 pi_CiMax_IRQ_n : 1;
+ u32 pi_timeout_status : 1;
+ u32 pi_wait_n : 1;
+ u32 pi_busy_n : 1;
+ } pi_608;
+
+ struct {
+ u32 PID :13;
+ u32 key_enable : 1;
+ u32 key_code : 2;
+ u32 key_array_col : 3;
+ u32 key_array_row : 5;
+ u32 dvb_en : 1;
+ u32 rw_flag : 1;
+ u32 reserved : 6;
+ } dvb_reg_60c;
+
+ struct {
+ u32 sram_addr :15;
+ u32 sram_rw : 1;
+ u32 sram_data : 8;
+ u32 sc_xfer_bit : 1;
+ u32 reserved1 : 3;
+ u32 oe_pin_reg : 1;
+ u32 ce_pin_reg : 1;
+ u32 reserved2 : 1;
+ u32 start_sram_ibi : 1;
+ } sram_ctrl_reg_700;
+
+ struct {
+ u32 net_addr_read :16;
+ u32 net_addr_write :16;
+ } net_buf_reg_704;
+
+ struct {
+ u32 cai_read :11;
+ u32 reserved1 : 5;
+ u32 cai_write :11;
+ u32 reserved2 : 6;
+ u32 cai_cnt : 4;
+ } cai_buf_reg_708;
+
+ struct {
+ u32 cao_read :11;
+ u32 reserved1 : 5;
+ u32 cap_write :11;
+ u32 reserved2 : 6;
+ u32 cao_cnt : 4;
+ } cao_buf_reg_70c;
+
+ struct {
+ u32 media_read :11;
+ u32 reserved1 : 5;
+ u32 media_write :11;
+ u32 reserved2 : 6;
+ u32 media_cnt : 4;
+ } media_buf_reg_710;
+
+ struct {
+ u32 NET_Dest : 2;
+ u32 CAI_Dest : 2;
+ u32 CAO_Dest : 2;
+ u32 MEDIA_Dest : 2;
+ u32 net_ovflow_error : 1;
+ u32 media_ovflow_error : 1;
+ u32 cai_ovflow_error : 1;
+ u32 cao_ovflow_error : 1;
+ u32 ctrl_usb_wan : 1;
+ u32 ctrl_sramdma : 1;
+ u32 ctrl_maximumfill : 1;
+ u32 reserved :17;
+ } sram_dest_reg_714;
+
+ struct {
+ u32 net_cnt :12;
+ u32 reserved1 : 4;
+ u32 net_addr_read : 1;
+ u32 reserved2 : 3;
+ u32 net_addr_write : 1;
+ u32 reserved3 :11;
+ } net_buf_reg_718;
+
+ struct {
+ u32 wan_speed_sig : 2;
+ u32 reserved1 : 6;
+ u32 wan_wait_state : 8;
+ u32 sram_chip : 2;
+ u32 sram_memmap : 2;
+ u32 reserved2 : 4;
+ u32 wan_pkt_frame : 4;
+ u32 reserved3 : 4;
+ } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
deleted file mode 100644
index acbc4c34f72..00000000000
--- a/drivers/media/dvb/b2c2/skystar2.c
+++ /dev/null
@@ -1,2644 +0,0 @@
-/*
- * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
- * based on the FlexCopII by B2C2,Inc.
- *
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
- *
- * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
- * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
- * Vincenzo Di Massa, hawk.it at tiscalinet.it
- *
- * Converted to Linux coding style
- * Misc reorganization, polishing, restyling
- * Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
- *
- * Added hardware filtering support,
- * Niklas Peinecke, peinecke at gdv.uni-hannover.de
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#include <asm/io.h>
-
-#include "dvb_frontend.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_filter.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_net.h"
-#include "stv0299.h"
-#include "mt352.h"
-#include "mt312.h"
-#include "nxt2002.h"
-
-static int debug;
-static int enable_hw_filters = 2;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
-module_param(enable_hw_filters, int, 0444);
-MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
-
-#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
-#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
-
-#define SIZE_OF_BUF_DMA1 0x3ac00
-#define SIZE_OF_BUF_DMA2 0x758
-
-#define MAX_N_HW_FILTERS (6+32)
-#define N_PID_SLOTS 256
-
-struct dmaq {
- u32 bus_addr;
- u32 head;
- u32 tail;
- u32 buffer_size;
- u8 *buffer;
-};
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-#define __iomem
-#endif
-
-struct adapter {
- struct pci_dev *pdev;
-
- u8 card_revision;
- u32 b2c2_revision;
- u32 pid_filter_max;
- u32 mac_filter_max;
- u32 irq;
- void __iomem *io_mem;
- unsigned long io_port;
- u8 mac_addr[8];
- u32 dw_sram_type;
-
- struct dvb_adapter dvb_adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend hw_frontend;
- struct dmx_frontend mem_frontend;
- struct i2c_adapter i2c_adap;
- struct dvb_net dvbnet;
-
- struct semaphore i2c_sem;
-
- struct dmaq dmaq1;
- struct dmaq dmaq2;
-
- u32 dma_ctrl;
- u32 dma_status;
-
- int capturing;
-
- spinlock_t lock;
-
- int useable_hw_filters;
- u16 hw_pids[MAX_N_HW_FILTERS];
- u16 pid_list[N_PID_SLOTS];
- int pid_rc[N_PID_SLOTS]; // ref counters for the pids
- int pid_count;
- int whole_bandwidth_count;
- u32 mac_filter;
-
- struct dvb_frontend* fe;
- int (*fe_sleep)(struct dvb_frontend* fe);
-};
-
-#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
-#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
-
-static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
-{
- u32 tmp;
-
- tmp = read_reg_dw(adapter, reg);
- tmp = (tmp & ~zeromask) | orvalue;
- write_reg_dw(adapter, reg, tmp);
-}
-
-/* i2c functions */
-static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
-{
- int i;
- u32 value;
-
- write_reg_dw(adapter, 0x100, 0);
- write_reg_dw(adapter, 0x100, command);
-
- for (i = 0; i < retries; i++) {
- value = read_reg_dw(adapter, 0x100);
-
- if ((value & 0x40000000) == 0) {
- if ((value & 0x81000000) == 0x80000000) {
- if (buf != 0)
- *buf = (value >> 0x10) & 0xff;
-
- return 1;
- }
- } else {
- write_reg_dw(adapter, 0x100, 0);
- write_reg_dw(adapter, 0x100, command);
- }
- }
-
- return 0;
-}
-
-/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
-static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
-{
- *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
-
- if (op != 0)
- *command = *command | 0x03000000;
- else
- *command = *command | 0x01000000;
-}
-
-static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
-{
- u32 command;
- u32 value;
-
- int result, i;
-
- i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
-
- result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
-
- if ((result & 0xff) != 0) {
- if (len > 1) {
- value = read_reg_dw(adapter, 0x104);
-
- for (i = 1; i < len; i++) {
- buf[i] = value & 0xff;
- value = value >> 8;
- }
- }
- }
-
- return result;
-}
-
-static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
-{
- u32 command;
- u32 value;
- int i;
-
- if (len > 1) {
- value = 0;
-
- for (i = len; i > 1; i--) {
- value = value << 8;
- value = value | buf[i - 1];
- }
-
- write_reg_dw(adapter, 0x104, value);
- }
-
- i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
-
- return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
-}
-
-static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
-{
- if (device == 0x20000000)
- *ret = bus | ((addr >> 8) & 3);
- else
- *ret = bus;
-}
-
-static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
- u32 chipaddr;
- u32 bytes_to_transfer;
- u8 *start;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- start = buf;
-
- while (len != 0) {
- bytes_to_transfer = len;
-
- if (bytes_to_transfer > 4)
- bytes_to_transfer = 4;
-
- fixchipaddr(device, bus, addr, &chipaddr);
-
- if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
- return buf - start;
-
- buf = buf + bytes_to_transfer;
- addr = addr + bytes_to_transfer;
- len = len - bytes_to_transfer;
- };
-
- return buf - start;
-}
-
-static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
- u32 chipaddr;
- u32 bytes_to_transfer;
- u8 *start;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- start = buf;
-
- while (len != 0) {
- bytes_to_transfer = len;
-
- if (bytes_to_transfer > 4)
- bytes_to_transfer = 4;
-
- fixchipaddr(device, bus, addr, &chipaddr);
-
- if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
- return buf - start;
-
- buf = buf + bytes_to_transfer;
- addr = addr + bytes_to_transfer;
- len = len - bytes_to_transfer;
- }
-
- return buf - start;
-}
-
-static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
-{
- struct adapter *tmp = i2c_get_adapdata(adapter);
- int i, ret = 0;
-
- if (down_interruptible(&tmp->i2c_sem))
- return -ERESTARTSYS;
-
- ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
-
- for (i = 0; i < num; i++) {
- ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
- }
-
- // read command
- if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
-
- ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-
- up(&tmp->i2c_sem);
-
- if (ret != msgs[1].len) {
- dprintk("%s: read error !\n", __FUNCTION__);
-
- for (i = 0; i < 2; i++) {
- dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
- }
-
- return -EREMOTEIO;
- }
-
- return num;
- }
- // write command
- for (i = 0; i < num; i++) {
-
- if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
- return -EINVAL;
-
- ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
-
- up(&tmp->i2c_sem);
-
- if (ret != msgs[0].len - 1) {
- dprintk("%s: write error %i !\n", __FUNCTION__, ret);
-
- dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
-
- return -EREMOTEIO;
- }
-
- return num;
- }
-
- printk("%s: unknown command format !\n", __FUNCTION__);
-
- return -EINVAL;
-}
-
-/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
- but it seems that FlexCopII can work with more than one chip) */
-static void sram_set_net_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
-
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_media_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-/* SRAM memory is accessed through a buffer register in the FlexCop
- chip (0x700). This register has the following structure:
- bits 0-14 : address
- bit 15 : read/write flag
- bits 16-23 : 8-bit word to write
- bits 24-27 : = 4
- bits 28-29 : memory bank selector
- bit 31 : busy flag
-*/
-static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
- int i, retries;
- u32 command;
-
- for (i = 0; i < len; i++) {
- command = bank | addr | 0x04000000 | (*buf << 0x10);
-
- retries = 2;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- write_reg_dw(adapter, 0x700, command);
-
- buf++;
- addr++;
- }
-}
-
-static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
- int i, retries;
- u32 command, value;
-
- for (i = 0; i < len; i++) {
- command = bank | addr | 0x04008000;
-
- retries = 10000;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- write_reg_dw(adapter, 0x700, command);
-
- retries = 10000;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- value = read_reg_dw(adapter, 0x700) >> 0x10;
-
- *buf = (value & 0xff);
-
- addr++;
- buf++;
- }
-}
-
-static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
- u32 bank;
-
- bank = 0;
-
- if (adapter->dw_sram_type == 0x20000) {
- bank = (addr & 0x18000) << 0x0d;
- }
-
- if (adapter->dw_sram_type == 0x00000) {
- if ((addr >> 0x0f) == 0)
- bank = 0x20000000;
- else
- bank = 0x10000000;
- }
-
- flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
- u32 bank;
-
- bank = 0;
-
- if (adapter->dw_sram_type == 0x20000) {
- bank = (addr & 0x18000) << 0x0d;
- }
-
- if (adapter->dw_sram_type == 0x00000) {
- if ((addr >> 0x0f) == 0)
- bank = 0x20000000;
- else
- bank = 0x10000000;
- }
-
- flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
- u32 length;
-
- while (len != 0) {
- length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is read from
- // one chip at a time.
- if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
- length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
- }
-
- sram_read_chunk(adapter, addr, buf, length);
-
- addr = addr + length;
- buf = buf + length;
- len = len - length;
- }
-}
-
-static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
- u32 length;
-
- while (len != 0) {
- length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is written to
- // one chip at a time.
- if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
- length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
- }
-
- sram_write_chunk(adapter, addr, buf, length);
-
- addr = addr + length;
- buf = buf + length;
- len = len - length;
- }
-}
-
-static void sram_set_size(struct adapter *adapter, u32 mask)
-{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
-}
-
-static void sram_init(struct adapter *adapter)
-{
- u32 tmp;
-
- tmp = read_reg_dw(adapter, 0x71c);
-
- write_reg_dw(adapter, 0x71c, 1);
-
- if (read_reg_dw(adapter, 0x71c) != 0) {
- write_reg_dw(adapter, 0x71c, tmp);
-
- adapter->dw_sram_type = tmp & 0x30000;
-
- ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
-
- } else {
-
- adapter->dw_sram_type = 0x10000;
-
- ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
- }
-
- /* return value is never used? */
-/* return adapter->dw_sram_type; */
-}
-
-static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
-{
- u8 tmp1, tmp2;
-
- dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
-
- sram_set_size(adapter, mask);
- sram_init(adapter);
-
- tmp2 = 0xa5;
- tmp1 = 0x4f;
-
- sram_write(adapter, addr, &tmp2, 1);
- sram_write(adapter, addr + 4, &tmp1, 1);
-
- tmp2 = 0;
-
- mdelay(20);
-
- sram_read(adapter, addr, &tmp2, 1);
- sram_read(adapter, addr, &tmp2, 1);
-
- dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
-
- if (tmp2 != 0xa5)
- return 0;
-
- tmp2 = 0x5a;
- tmp1 = 0xf4;
-
- sram_write(adapter, addr, &tmp2, 1);
- sram_write(adapter, addr + 4, &tmp1, 1);
-
- tmp2 = 0;
-
- mdelay(20);
-
- sram_read(adapter, addr, &tmp2, 1);
- sram_read(adapter, addr, &tmp2, 1);
-
- dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
-
- if (tmp2 != 0x5a)
- return 0;
-
- return 1;
-}
-
-static u32 sram_length(struct adapter *adapter)
-{
- if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
- if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
- if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
-}
-
-/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
- - for 128K there are 4x32K chips at bank 0,1,2,3.
- - for 64K there are 2x32K chips at bank 1,2.
- - for 32K there is one 32K chip at bank 0.
-
- FlexCop works only with one bank at a time. The bank is selected
- by bits 28-29 of the 0x700 register.
-
- bank 0 covers addresses 0x00000-0x07fff
- bank 1 covers addresses 0x08000-0x0ffff
- bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
-static int sram_detect_for_flex2(struct adapter *adapter)
-{
- u32 tmp, tmp2, tmp3;
-
- dprintk("%s:\n", __FUNCTION__);
-
- tmp = read_reg_dw(adapter, 0x208);
- write_reg_dw(adapter, 0x208, 0);
-
- tmp2 = read_reg_dw(adapter, 0x71c);
-
- dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
-
- write_reg_dw(adapter, 0x71c, 1);
-
- tmp3 = read_reg_dw(adapter, 0x71c);
-
- dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
-
- write_reg_dw(adapter, 0x71c, tmp2);
-
- // check for internal SRAM ???
- tmp3--;
- if (tmp3 != 0) {
- sram_set_size(adapter, 0x10000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
- return 32;
- }
-
- if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
- sram_set_size(adapter, 0x20000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 128K\n", __FUNCTION__);
-
- return 128;
- }
-
- if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
- sram_set_size(adapter, 0x00000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 64K\n", __FUNCTION__);
-
- return 64;
- }
-
- if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
- sram_set_size(adapter, 0x10000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
- return 32;
- }
-
- sram_set_size(adapter, 0x10000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
-
- return 0;
-}
-
-static void sll_detect_sram_size(struct adapter *adapter)
-{
- sram_detect_for_flex2(adapter);
-}
-
-/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
-/*
-static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
- return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-*/
-
-static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
- return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-
-static u8 calc_lrc(u8 *buf, int len)
-{
- int i;
- u8 sum;
-
- sum = 0;
-
- for (i = 0; i < len; i++)
- sum = sum ^ buf[i];
-
- return sum;
-}
-
-static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
-{
- int i;
-
- for (i = 0; i < retries; i++) {
- if (eeprom_read(adapter, addr, buf, len) == len) {
- if (calc_lrc(buf, len - 1) == buf[len - 1])
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
-{
- int i;
-
- for (i = 0; i < retries; i++) {
- if (eeprom_write(adapter, addr, wbuf, len) == len) {
- if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
- return 1;
- }
- }
-
- return 0;
-}
-*/
-
-
-/* These functions could be used to unlock SkyStar2 cards. */
-
-/*
-static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
-{
- u8 rbuf[20];
- u8 wbuf[20];
-
- if (len != 16)
- return 0;
-
- memcpy(wbuf, key, len);
-
- wbuf[16] = 0;
- wbuf[17] = 0;
- wbuf[18] = 0;
- wbuf[19] = calc_lrc(wbuf, 19);
-
- return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
-}
-
-static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
-{
- u8 buf[20];
-
- if (len != 16)
- return 0;
-
- if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
- return 0;
-
- memcpy(key, buf, len);
-
- return 1;
-}
-*/
-
-static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
- u8 tmp[8];
-
- if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
- if (type != 0) {
- mac[0] = tmp[0];
- mac[1] = tmp[1];
- mac[2] = tmp[2];
- mac[3] = 0xfe;
- mac[4] = 0xff;
- mac[5] = tmp[3];
- mac[6] = tmp[4];
- mac[7] = tmp[5];
-
- } else {
-
- mac[0] = tmp[0];
- mac[1] = tmp[1];
- mac[2] = tmp[2];
- mac[3] = tmp[3];
- mac[4] = tmp[4];
- mac[5] = tmp[5];
- }
-
- return 1;
-
- } else {
-
- if (type == 0) {
- memset(mac, 0, 6);
-
- } else {
-
- memset(mac, 0, 8);
- }
-
- return 0;
- }
-}
-
-/*
-static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
- u8 tmp[8];
-
- if (type != 0) {
- tmp[0] = mac[0];
- tmp[1] = mac[1];
- tmp[2] = mac[2];
- tmp[3] = mac[5];
- tmp[4] = mac[6];
- tmp[5] = mac[7];
-
- } else {
-
- tmp[0] = mac[0];
- tmp[1] = mac[1];
- tmp[2] = mac[2];
- tmp[3] = mac[3];
- tmp[4] = mac[4];
- tmp[5] = mac[5];
- }
-
- tmp[6] = 0;
- tmp[7] = calc_lrc(tmp, 7);
-
- if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
- return 1;
-
- return 0;
-}
-*/
-
-/* PID filter */
-
-/* every flexcop has 6 "lower" hw PID filters */
-/* these are enabled by setting bits 0-5 of 0x208 */
-/* for the 32 additional filters we have to select one */
-/* of them through 0x310 and modify through 0x314 */
-/* op: 0=disable, 1=enable */
-static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
-{
- dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
- if (id <= 5) {
- u32 mask = (0x00000001 << id);
- write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
- } else {
- /* select */
- write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
- /* modify */
- write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
- }
-}
-
-/* this sets the PID that should pass the specified filter */
-static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
-{
- dprintk("%s: id=%d pid=%d\n", __FUNCTION__, id, pid);
- if (id <= 5) {
- u32 adr = 0x300 + ((id & 6) << 1);
- int shift = (id & 1) ? 16 : 0;
- dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
- write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
- } else {
- /* select */
- write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
- /* modify */
- write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
- }
-}
-
-
-/*
-static void filter_enable_null_filter(struct adapter *adapter, u32 op)
-{
- dprintk("%s: op=%x\n", __FUNCTION__, op);
-
- write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
-}
-*/
-
-static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
-{
- dprintk("%s: op=%x\n", __FUNCTION__, op);
-
- write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
-}
-
-
-static void ctrl_enable_mac(struct adapter *adapter, u32 op)
-{
- write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
-}
-
-static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
-{
- u32 tmp1, tmp2;
-
- tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
- tmp2 = (mac[5] << 0x08) | mac[4];
-
- write_reg_dw(adapter, 0x418, tmp1);
- write_reg_dw(adapter, 0x41c, tmp2);
-
- return 0;
-}
-
-/*
-static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
-{
- if (op != 0) {
- write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
- adapter->mac_filter = 1;
- } else {
- if (adapter->mac_filter != 0) {
- adapter->mac_filter = 0;
- write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
- }
- }
-}
-*/
-
-/*
-static void check_null_filter_enable(struct adapter *adapter)
-{
- filter_enable_null_filter(adapter, 1);
- filter_enable_mask_filter(adapter, 1);
-}
-*/
-
-static void pid_set_group_pid(struct adapter *adapter, u16 pid)
-{
- u32 value;
-
- dprintk("%s: pid=%x\n", __FUNCTION__, pid);
- value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
- write_reg_dw(adapter, 0x30c, value);
-}
-
-static void pid_set_group_mask(struct adapter *adapter, u16 pid)
-{
- u32 value;
-
- dprintk("%s: pid=%x\n", __FUNCTION__, pid);
- value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
- write_reg_dw(adapter, 0x30c, value);
-}
-
-/*
-static int pid_get_group_pid(struct adapter *adapter)
-{
- return read_reg_dw(adapter, 0x30c) & 0x00001fff;
-}
-
-static int pid_get_group_mask(struct adapter *adapter)
-{
- return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
-}
-*/
-
-/*
-static void reset_hardware_pid_filter(struct adapter *adapter)
-{
- pid_set_stream1_pid(adapter, 0x1fff);
-
- pid_set_stream2_pid(adapter, 0x1fff);
- filter_enable_stream2_filter(adapter, 0);
-
- pid_set_pcr_pid(adapter, 0x1fff);
- filter_enable_pcr_filter(adapter, 0);
-
- pid_set_pmt_pid(adapter, 0x1fff);
- filter_enable_pmt_filter(adapter, 0);
-
- pid_set_ecm_pid(adapter, 0x1fff);
- filter_enable_ecm_filter(adapter, 0);
-
- pid_set_emm_pid(adapter, 0x1fff);
- filter_enable_emm_filter(adapter, 0);
-}
-*/
-
-static void init_pids(struct adapter *adapter)
-{
- int i;
-
- adapter->pid_count = 0;
- adapter->whole_bandwidth_count = 0;
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
- adapter->hw_pids[i] = 0x1fff;
- pid_set_hw_pid(adapter, i, 0x1fff);
-}
-
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0x1fe0);
-}
-
-static void open_whole_bandwidth(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0);
-/*
- filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void close_whole_bandwidth(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0x1fe0);
-/*
- filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void whole_bandwidth_inc(struct adapter *adapter)
-{
- if (adapter->whole_bandwidth_count++ == 0)
- open_whole_bandwidth(adapter);
-}
-
-static void whole_bandwidth_dec(struct adapter *adapter)
-{
- if (--adapter->whole_bandwidth_count <= 0)
- close_whole_bandwidth(adapter);
-}
-
-/* The specified PID has to be let through the
- hw filters.
- We try to allocate an hardware filter and open whole
- bandwidth when allocation is impossible.
- All pids<=0x1f pass through the group filter.
- Returns 1 on success, -1 on error */
-static int add_hw_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid <= 0x1f)
- return 1;
-
- /* we can't use a filter for 0x2000, so no search */
- if (pid != 0x2000) {
- /* find an unused hardware filter */
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
- if (adapter->hw_pids[i] == 0x1fff) {
- dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
- adapter->hw_pids[i] = pid;
- pid_set_hw_pid(adapter, i, pid);
- filter_enable_hw_filter(adapter, i, 1);
- return 1;
- }
- }
- }
- /* if we have not used a filter, this pid depends on whole bandwidth */
- dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
- whole_bandwidth_inc(adapter);
- return 1;
- }
-
-/* returns -1 if the pid was not present in the filters */
-static int remove_hw_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid <= 0x1f)
- return 1;
-
- /* we can't use a filter for 0x2000, so no search */
- if (pid != 0x2000) {
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
- if (adapter->hw_pids[i] == pid) { // find the pid slot
- dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
- adapter->hw_pids[i] = 0x1fff;
- pid_set_hw_pid(adapter, i, 0x1fff);
- filter_enable_hw_filter(adapter, i, 0);
- return 1;
- }
- }
- }
- /* if we have not used a filter, this pid depended on whole bandwith */
- dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
- whole_bandwidth_dec(adapter);
- return 1;
- }
-
-/* Adds a PID to the filters.
- Adding a pid more than once is possible, we keep reference counts.
- Whole stream available through pid==0x2000.
- Returns 1 on success, -1 on error */
-static int add_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid > 0x1ffe && pid != 0x2000)
- return -1;
-
- // check if the pid is already present
- for (i = 0; i < adapter->pid_count; i++)
- if (adapter->pid_list[i] == pid) {
- adapter->pid_rc[i]++; // increment ref counter
- return 1;
- }
-
- if (adapter->pid_count == N_PID_SLOTS)
- return -1; // no more pids can be added
- adapter->pid_list[adapter->pid_count] = pid; // register pid
- adapter->pid_rc[adapter->pid_count] = 1;
- adapter->pid_count++;
- // hardware setting
- add_hw_pid(adapter, pid);
-
- return 1;
- }
-
-/* Removes a PID from the filters. */
-static int remove_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid > 0x1ffe && pid != 0x2000)
- return -1;
-
- // check if the pid is present (it must be!)
- for (i = 0; i < adapter->pid_count; i++) {
- if (adapter->pid_list[i] == pid) {
- adapter->pid_rc[i]--;
- if (adapter->pid_rc[i] <= 0) {
- // remove from the list
- adapter->pid_count--;
- adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
- adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
- // hardware setting
- remove_hw_pid(adapter, pid);
- }
- return 1;
- }
- }
-
- return -1;
-}
-
-
-/* dma & irq */
-static void ctrl_enable_smc(struct adapter *adapter, u32 op)
-{
- write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
-}
-
-static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
-{
- adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
-
- if (flag1 == 0) {
- if (flag2 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
-
- if (flag3 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
-
- } else {
-
- if (flag2 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
-
- if (flag3 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
- }
-}
-
-static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
-{
- u32 value;
-
- value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
-
- if (op != 0)
- value = value | (adapter->dma_ctrl & 0x000f0000);
-
- write_reg_dw(adapter, 0x208, value);
-}
-
-/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
- system memory.
-
- The DMA1 buffer is divided in 2 subbuffers of equal size.
- FlexCopII will transfer TS data to one subbuffer, signal an interrupt
- when the subbuffer is full and continue fillig the second subbuffer.
-
- For DMA1:
- subbuffer size in 32-bit words is stored in the first 24 bits of
- register 0x004. The last 8 bits of register 0x004 contain the number
- of subbuffers.
-
- the first 30 bits of register 0x000 contain the address of the first
- subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
- when dma1 is enabled.
-
- the first 30 bits of register 0x00c contain the address of the second
- subbuffer. the last 2 bits contain 1.
-
- register 0x008 will contain the address of the subbuffer that was filled
- with TS data, when FlexCopII will generate an interrupt.
-
- For DMA2:
- subbuffer size in 32-bit words is stored in the first 24 bits of
- register 0x014. The last 8 bits of register 0x014 contain the number
- of subbuffers.
-
- the first 30 bits of register 0x010 contain the address of the first
- subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
- when dma1 is enabled.
-
- the first 30 bits of register 0x01c contain the address of the second
- subbuffer. the last 2 bits contain 1.
-
- register 0x018 contains the address of the subbuffer that was filled
- with TS data, when FlexCopII generates an interrupt.
-*/
-static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
-{
- u32 subbuffers, subbufsize, subbuf0, subbuf1;
-
- if (dma_channel == 0) {
- dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
-
- subbuffers = 2;
-
- subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
-
- subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
-
- subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
-
- dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
- udelay(1000);
- write_reg_dw(adapter, 0x000, subbuf0);
-
- dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
- udelay(1000);
- write_reg_dw(adapter, 0x004, subbufsize);
-
- dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
- udelay(1000);
- write_reg_dw(adapter, 0x00c, subbuf1);
-
- dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
- write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
- udelay(1000);
-
- dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
-
- irq_dma_enable_disable_irq(adapter, 1);
-
- sram_set_media_dest(adapter, 1);
- sram_set_net_dest(adapter, 1);
- sram_set_cai_dest(adapter, 2);
- sram_set_cao_dest(adapter, 2);
- }
-
- if (dma_channel == 1) {
- dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
-
- subbuffers = 2;
-
- subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
-
- subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
-
- subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
-
- dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
- udelay(1000);
- write_reg_dw(adapter, 0x010, subbuf0);
-
- dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
- udelay(1000);
- write_reg_dw(adapter, 0x014, subbufsize);
-
- dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
- udelay(1000);
- write_reg_dw(adapter, 0x01c, subbuf1);
-
- sram_set_cai_dest(adapter, 2);
- }
-
- return 0;
-}
-
-static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
-{
- if (op == 0) {
- write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
- adapter->dma_status = adapter->dma_status & ~0x00000004;
- } else {
- write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
- adapter->dma_status = adapter->dma_status | 0x00000004;
- }
-}
-
-/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
- bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
-*/
-static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
-{
- u32 dma_enable, dma1_enable, dma2_enable;
-
- dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
-
- if (start_stop == 1) {
- dprintk("%s: starting dma\n", __FUNCTION__);
-
- dma1_enable = 0;
- dma2_enable = 0;
-
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
- adapter->dma_status = adapter->dma_status | 1;
- dma1_enable = 1;
- }
-
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
- adapter->dma_status = adapter->dma_status | 2;
- dma2_enable = 1;
- }
- // enable dma1 and dma2
- if ((dma1_enable == 1) && (dma2_enable == 1)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // enable dma1
- if ((dma1_enable == 1) && (dma2_enable == 0)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // enable dma2
- if ((dma1_enable == 0) && (dma2_enable == 1)) {
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // start dma
- if ((dma1_enable == 0) && (dma2_enable == 0)) {
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
-
- } else {
-
- dprintk("%s: stopping dma\n", __FUNCTION__);
-
- dma_enable = adapter->dma_status & 0x00000003;
-
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
- dma_enable = dma_enable & 0xfffffffe;
- }
-
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
- dma_enable = dma_enable & 0xfffffffd;
- }
- //stop dma
- if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
- ctrl_enable_receive_data(adapter, 0);
-
- udelay(3000);
- }
- //disable dma1
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
- adapter->dma_status = adapter->dma_status & ~0x00000001;
- }
- //disable dma2
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
-
- adapter->dma_status = adapter->dma_status & ~0x00000002;
- }
- }
-}
-
-static void open_stream(struct adapter *adapter, u16 pid)
-{
- u32 dma_mask;
-
- ++adapter->capturing;
-
- filter_enable_mask_filter(adapter, 1);
-
- add_pid(adapter, pid);
-
- dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
- if ((adapter->dma_status & 7) != 7) {
- dma_mask = 0;
-
- if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
- dma_mask = dma_mask | 1;
-
- adapter->dmaq1.head = 0;
- adapter->dmaq1.tail = 0;
-
- memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
- }
-
- if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
- dma_mask = dma_mask | 2;
-
- adapter->dmaq2.head = 0;
- adapter->dmaq2.tail = 0;
- }
-
- if (dma_mask != 0) {
- irq_dma_enable_disable_irq(adapter, 1);
-
- dma_start_stop(adapter, dma_mask, 1);
- }
- }
-}
-
-static void close_stream(struct adapter *adapter, u16 pid)
-{
- if (adapter->capturing > 0)
- --adapter->capturing;
-
- dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
- if (adapter->capturing == 0) {
- u32 dma_mask = 0;
-
- if ((adapter->dma_status & 1) != 0)
- dma_mask = dma_mask | 0x00000001;
- if ((adapter->dma_status & 2) != 0)
- dma_mask = dma_mask | 0x00000002;
-
- if (dma_mask != 0) {
- dma_start_stop(adapter, dma_mask, 0);
- }
- }
- remove_pid(adapter, pid);
-}
-
-static void interrupt_service_dma1(struct adapter *adapter)
-{
- struct dvb_demux *dvbdmx = &adapter->demux;
-
- int n_cur_dma_counter;
- u32 n_num_bytes_parsed;
- u32 n_num_new_bytes_transferred;
- u32 dw_default_packet_size = 188;
- u8 gb_tmp_buffer[188];
- u8 *pb_dma_buf_cur_pos;
-
- n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
- n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
-
- if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
- dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
- return;
- }
-
- adapter->dmaq1.head = n_cur_dma_counter;
-
- if (adapter->dmaq1.tail <= n_cur_dma_counter) {
- n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
-
- } else {
-
- n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
- }
-
- ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
- ddprintk("%s: dmaq1.tail = %d\n", __FUNCTION__, adapter->dmaq1.tail);
- ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
-
- if (n_num_new_bytes_transferred < dw_default_packet_size)
- return;
-
- n_num_bytes_parsed = 0;
-
- while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
- pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
-
- if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
- memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
- adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
- memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
- (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
-
- pb_dma_buf_cur_pos = gb_tmp_buffer;
- }
-
- if (adapter->capturing != 0) {
- dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
- }
-
- n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
-
- adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
-
- if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
- adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
- };
-}
-
-static void interrupt_service_dma2(struct adapter *adapter)
-{
- printk("%s:\n", __FUNCTION__);
-}
-
-static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct adapter *tmp = dev_id;
-
- u32 value;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- spin_lock_irq(&tmp->lock);
-
- if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
- spin_unlock_irq(&tmp->lock);
- return IRQ_NONE;
- }
-
- while (value != 0) {
- if ((value & 0x03) != 0)
- interrupt_service_dma1(tmp);
- if ((value & 0x0c) != 0)
- interrupt_service_dma2(tmp);
- value = read_reg_dw(tmp, 0x20c) & 0x0f;
- }
-
- spin_unlock_irq(&tmp->lock);
- return IRQ_HANDLED;
-}
-
-static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
- int size, int dmaq_offset)
-{
- struct pci_dev *pdev = adapter->pdev;
- dma_addr_t dma_addr;
-
- dmaq->head = 0;
- dmaq->tail = 0;
-
- dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
- if (!dmaq->buffer)
- return -ENOMEM;
-
- dmaq->bus_addr = dma_addr;
- dmaq->buffer_size = size;
-
- dma_init_dma(adapter, dmaq_offset);
-
- ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
- __FUNCTION__, dmaq->buffer, size);
-
- return 0;
- }
-
-static int init_dma_queue(struct adapter *adapter)
-{
- struct {
- struct dmaq *dmaq;
- u32 dma_status;
- int size;
- } dmaq_desc[] = {
- { &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
- { &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
- }, *p = dmaq_desc;
- int i;
-
- for (i = 0; i < 2; i++, p++) {
- if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
- adapter->dma_status &= ~p->dma_status;
- else
- adapter->dma_status |= p->dma_status;
- }
- return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
-}
-
-static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
-{
- if (dmaq->buffer) {
- pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
- dmaq->buffer, dmaq->bus_addr);
- memset(dmaq, 0, sizeof(*dmaq));
- }
-}
-
-static void free_dma_queue(struct adapter *adapter)
-{
- struct dmaq *dmaq[] = {
- &adapter->dmaq1,
- &adapter->dmaq2,
- NULL
- }, **p;
-
- for (p = dmaq; *p; p++)
- free_dma_queue_one(adapter, *p);
- }
-
-static void release_adapter(struct adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
-
- iounmap(adapter->io_mem);
- pci_disable_device(pdev);
- pci_release_region(pdev, 0);
- pci_release_region(pdev, 1);
-}
-
-static void free_adapter_object(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
-
- close_stream(adapter, 0);
- free_irq(adapter->irq, adapter);
- free_dma_queue(adapter);
- release_adapter(adapter);
- kfree(adapter);
-}
-
-static struct pci_driver skystar2_pci_driver;
-
-static int claim_adapter(struct adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- u16 var;
- int ret;
-
- ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
- if (ret < 0)
- goto out;
-
- ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
- if (ret < 0)
- goto err_pci_release_1;
-
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
-
- dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
-
- ret = pci_enable_device(pdev);
- if (ret < 0)
- goto err_pci_release_0;
-
- pci_read_config_word(pdev, 4, &var);
-
- if ((var & 4) == 0)
- pci_set_master(pdev);
-
- adapter->io_port = pdev->resource[1].start;
-
- adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
-
- if (!adapter->io_mem) {
- dprintk("%s: can not map io memory\n", __FUNCTION__);
- ret = -EIO;
- goto err_pci_disable;
- }
-
- dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
-
- ret = 1;
-out:
- return ret;
-
-err_pci_disable:
- pci_disable_device(pdev);
-err_pci_release_0:
- pci_release_region(pdev, 0);
-err_pci_release_1:
- pci_release_region(pdev, 1);
- goto out;
-}
-
-/*
-static int sll_reset_flexcop(struct adapter *adapter)
-{
- write_reg_dw(adapter, 0x208, 0);
- write_reg_dw(adapter, 0x210, 0xb2ff);
-
- return 0;
-}
-*/
-
-static void decide_how_many_hw_filters(struct adapter *adapter)
-{
- int hw_filters;
- int mod_option_hw_filters;
-
- // FlexCop IIb & III have 6+32 hw filters
- // FlexCop II has 6 hw filters, every other should have at least 6
- switch (adapter->b2c2_revision) {
- case 0x82: /* II */
- hw_filters = 6;
- break;
- case 0xc3: /* IIB */
- hw_filters = 6 + 32;
- break;
- case 0xc0: /* III */
- hw_filters = 6 + 32;
- break;
- default:
- hw_filters = 6;
- break;
- }
- printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
-
- mod_option_hw_filters = 0;
- if (enable_hw_filters >= 1)
- mod_option_hw_filters += 6;
- if (enable_hw_filters >= 2)
- mod_option_hw_filters += 32;
-
- if (mod_option_hw_filters >= hw_filters) {
- adapter->useable_hw_filters = hw_filters;
- } else {
- adapter->useable_hw_filters = mod_option_hw_filters;
- printk(", but only %d will be used because of module option", mod_option_hw_filters);
- }
- printk("\n");
- dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
-}
-
-static int driver_initialize(struct pci_dev *pdev)
-{
- struct adapter *adapter;
- u32 tmp;
- int ret = -ENOMEM;
-
- adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
- if (!adapter) {
- dprintk("%s: out of memory!\n", __FUNCTION__);
- goto out;
- }
-
- memset(adapter, 0, sizeof(struct adapter));
-
- pci_set_drvdata(pdev,adapter);
-
- adapter->pdev = pdev;
- adapter->irq = pdev->irq;
-
- ret = claim_adapter(adapter);
- if (ret < 0)
- goto err_kfree;
-
- irq_dma_enable_disable_irq(adapter, 0);
-
- ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
- if (ret < 0) {
- dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
- goto err_release_adapter;
- }
-
- read_reg_dw(adapter, 0x208);
- write_reg_dw(adapter, 0x208, 0);
- write_reg_dw(adapter, 0x210, 0xb2ff);
- write_reg_dw(adapter, 0x208, 0x40);
-
- ret = init_dma_queue(adapter);
- if (ret < 0)
- goto err_free_irq;
-
- adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
-
- switch (adapter->b2c2_revision) {
- case 0x82:
- printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
- break;
- case 0xc3:
- printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
- break;
- case 0xc0:
- printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
- break;
- default:
- printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
- printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
- ret = -ENODEV;
- goto err_free_dma_queue;
- }
-
- decide_how_many_hw_filters(adapter);
-
- init_pids(adapter);
-
- tmp = read_reg_dw(adapter, 0x204);
-
- write_reg_dw(adapter, 0x204, 0);
- mdelay(20);
-
- write_reg_dw(adapter, 0x204, tmp);
- mdelay(10);
-
- tmp = read_reg_dw(adapter, 0x308);
- write_reg_dw(adapter, 0x308, 0x4000 | tmp);
-
- adapter->dw_sram_type = 0x10000;
-
- sll_detect_sram_size(adapter);
-
- dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
-
- sram_set_media_dest(adapter, 1);
- sram_set_net_dest(adapter, 1);
-
- ctrl_enable_smc(adapter, 0);
-
- sram_set_cai_dest(adapter, 2);
- sram_set_cao_dest(adapter, 2);
-
- dma_enable_disable_irq(adapter, 1, 0, 0);
-
- if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
- printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
- adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
- adapter->mac_addr[6], adapter->mac_addr[7]
- );
-
- ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
- ctrl_enable_mac(adapter, 1);
- }
-
- spin_lock_init(&adapter->lock);
-
-out:
- return ret;
-
-err_free_dma_queue:
- free_dma_queue(adapter);
-err_free_irq:
- free_irq(pdev->irq, adapter);
-err_release_adapter:
- release_adapter(adapter);
-err_kfree:
- pci_set_drvdata(pdev, NULL);
- kfree(adapter);
- goto out;
-}
-
-static void driver_halt(struct pci_dev *pdev)
-{
- struct adapter *adapter = pci_get_drvdata(pdev);
-
- irq_dma_enable_disable_irq(adapter, 0);
-
- ctrl_enable_receive_data(adapter, 0);
-
- free_adapter_object(adapter);
-
- pci_set_drvdata(pdev, NULL);
-}
-
-static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
- dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
- open_stream(adapter, dvbdmxfeed->pid);
-
- return 0;
-}
-
-static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
- dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
- close_stream(adapter, dvbdmxfeed->pid);
-
- return 0;
-}
-
-/* lnb control */
-static void set_tuner_tone(struct adapter *adapter, u8 tone)
-{
- u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
- u16 ax;
-
- dprintk("%s: %u\n", __FUNCTION__, tone);
-
- switch (tone) {
- case 1:
- ax = wz_half_period_for_45_mhz[0];
- break;
- case 2:
- ax = wz_half_period_for_45_mhz[1];
- break;
- case 3:
- ax = wz_half_period_for_45_mhz[2];
- break;
- case 4:
- ax = wz_half_period_for_45_mhz[3];
- break;
-
- default:
- ax = 0;
- }
-
- if (ax != 0) {
- write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
-
- } else {
-
- write_reg_dw(adapter, 0x200, 0x40ff8000);
- }
-}
-
-static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
-{
- u32 var;
-
- dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
-
- var = read_reg_dw(adapter, 0x204);
-
- if (polarity == 0) {
- dprintk("%s: LNB power off\n", __FUNCTION__);
- var = var | 1;
- };
-
- if (polarity == 1) {
- var = var & ~1;
- var = var & ~4;
- };
-
- if (polarity == 2) {
- var = var & ~1;
- var = var | 4;
- }
-
- write_reg_dw(adapter, 0x204, var);
-}
-
-static void diseqc_send_bit(struct adapter *adapter, int data)
-{
- set_tuner_tone(adapter, 1);
- udelay(data ? 500 : 1000);
- set_tuner_tone(adapter, 0);
- udelay(data ? 1000 : 500);
-}
-
-
-static void diseqc_send_byte(struct adapter *adapter, int data)
- {
- int i, par = 1, d;
-
- for (i = 7; i >= 0; i--) {
- d = (data >> i) & 1;
- par ^= d;
- diseqc_send_bit(adapter, d);
- }
-
- diseqc_send_bit(adapter, par);
- }
-
-
-static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
-{
- int i;
-
- set_tuner_tone(adapter, 0);
- mdelay(16);
-
- for (i = 0; i < len; i++)
- diseqc_send_byte(adapter, msg[i]);
-
- mdelay(16);
-
- if (burst != -1) {
- if (burst)
- diseqc_send_byte(adapter, 0xff);
- else {
- set_tuner_tone(adapter, 1);
- udelay(12500);
- set_tuner_tone(adapter, 0);
- }
- msleep(20);
- }
-
- return 0;
-}
-
-static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- switch(tone) {
- case SEC_TONE_ON:
- set_tuner_tone(adapter, 1);
- break;
- case SEC_TONE_OFF:
- set_tuner_tone(adapter, 0);
- break;
- default:
- return -EINVAL;
- };
-
- return 0;
-}
-
-static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
-
- return 0;
- }
-
-static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- send_diseqc_msg(adapter, 0, NULL, minicmd);
-
- return 0;
-}
-
-static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
-
- switch (voltage) {
- case SEC_VOLTAGE_13:
- dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
- set_tuner_polarity(adapter, 1);
- return 0;
-
- case SEC_VOLTAGE_18:
- dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
- set_tuner_polarity(adapter, 2);
- return 0;
-
- default:
- return -EINVAL;
- }
- }
-
-static int flexcop_sleep(struct dvb_frontend* fe)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- dprintk("%s: FE_SLEEP\n", __FUNCTION__);
- set_tuner_polarity(adapter, 0);
-
- if (adapter->fe_sleep) return adapter->fe_sleep(fe);
- return 0;
- }
-
-static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
- {
- printk("flexcop_i2c_func\n");
-
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm flexcop_algo = {
- .name = "flexcop i2c algorithm",
- .id = I2C_ALGO_BIT,
- .master_xfer = master_xfer,
- .functionality = flexcop_i2c_func,
-};
-
-
-
-
-static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
- u8 aclk = 0;
- u8 bclk = 0;
-
- if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
- else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
- else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
- else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
- else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
- else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
- stv0299_writereg (fe, 0x13, aclk);
- stv0299_writereg (fe, 0x14, bclk);
- stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
- stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
- stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
-
- return 0;
-}
-
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- u8 buf[4];
- u32 div;
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- div = params->frequency / 125;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = div & 0xff;
- buf[2] = 0x84; // 0xC4
- buf[3] = 0x08;
-
- if (params->frequency < 1500000) buf[3] |= 0x10;
-
- if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
- return 0;
-}
-
-static u8 samsung_tbmu24112_inittab[] = {
- 0x01, 0x15,
- 0x02, 0x30,
- 0x03, 0x00,
- 0x04, 0x7D,
- 0x05, 0x35,
- 0x06, 0x02,
- 0x07, 0x00,
- 0x08, 0xC3,
- 0x0C, 0x00,
- 0x0D, 0x81,
- 0x0E, 0x23,
- 0x0F, 0x12,
- 0x10, 0x7E,
- 0x11, 0x84,
- 0x12, 0xB9,
- 0x13, 0x88,
- 0x14, 0x89,
- 0x15, 0xC9,
- 0x16, 0x00,
- 0x17, 0x5C,
- 0x18, 0x00,
- 0x19, 0x00,
- 0x1A, 0x00,
- 0x1C, 0x00,
- 0x1D, 0x00,
- 0x1E, 0x00,
- 0x1F, 0x3A,
- 0x20, 0x2E,
- 0x21, 0x80,
- 0x22, 0xFF,
- 0x23, 0xC1,
- 0x28, 0x00,
- 0x29, 0x1E,
- 0x2A, 0x14,
- 0x2B, 0x0F,
- 0x2C, 0x09,
- 0x2D, 0x05,
- 0x31, 0x1F,
- 0x32, 0x19,
- 0x33, 0xFE,
- 0x34, 0x93,
- 0xff, 0xff,
- };
-
-static struct stv0299_config samsung_tbmu24112_config = {
- .demod_address = 0x68,
- .inittab = samsung_tbmu24112_inittab,
- .mclk = 88000000UL,
- .invert = 0,
- .enhanced_tuning = 0,
- .skip_reinit = 0,
- .lock_output = STV0229_LOCKOUTPUT_LK,
- .volt13_op0_op1 = STV0299_VOLT13_OP1,
- .min_delay_ms = 100,
- .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
- .pll_set = samsung_tbmu24112_pll_set,
-};
-
-
-
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- return request_firmware(fw, name, &adapter->pdev->dev);
-}
-
-
-static struct nxt2002_config samsung_tbmv_config = {
- .demod_address = 0x0A,
- .request_firmware = nxt2002_request_firmware,
-};
-
-static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
-{
- static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
- static u8 mt352_reset [] = { 0x50, 0x80 };
- static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
- static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
- mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
- udelay(2000);
- mt352_write(fe, mt352_reset, sizeof(mt352_reset));
- mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
- mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
- mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
- return 0;
-}
-
-static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
-{
- u32 div;
- unsigned char bs = 0;
-
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
- div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
- if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
- if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
- if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
-
- pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
- pllbuf[1] = div >> 8;
- pllbuf[2] = div & 0xff;
- pllbuf[3] = 0xcc;
- pllbuf[4] = bs;
-
- return 0;
-}
-
-static struct mt352_config samsung_tdtc9251dh0_config = {
-
- .demod_address = 0x0f,
- .demod_init = samsung_tdtc9251dh0_demod_init,
- .pll_set = samsung_tdtc9251dh0_pll_set,
-};
-
-static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- u8 buf[4];
- u32 div;
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- div = (params->frequency + (125/2)) / 125;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = (div >> 0) & 0xff;
- buf[2] = 0x84 | ((div >> 10) & 0x60);
- buf[3] = 0x80;
-
- if (params->frequency < 1550000)
- buf[3] |= 0x02;
-
- if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
- return 0;
-}
-
-static struct mt312_config skystar23_samsung_tbdu18132_config = {
-
- .demod_address = 0x0e,
- .pll_set = skystar23_samsung_tbdu18132_pll_set,
-};
-
-
-
-
-static void frontend_init(struct adapter *skystar2)
-{
- switch(skystar2->pdev->device) {
- case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
-
- // Attempt to load the Nextwave nxt2002 for ATSC support
- skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
- }
-
- // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
- skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->set_voltage = flexcop_set_voltage;
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
-}
-
- // try the airstar2 (mt352/Samsung tdtc9251dh0(??))
- skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->info.frequency_min = 474000000;
- skystar2->fe->ops->info.frequency_max = 858000000;
- break;
- }
-
- // try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
- skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
- skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
- skystar2->fe->ops->set_tone = flexcop_set_tone;
- skystar2->fe->ops->set_voltage = flexcop_set_voltage;
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
- }
- break;
- }
-
- if (skystar2->fe == NULL) {
- printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
- skystar2->pdev->vendor,
- skystar2->pdev->device,
- skystar2->pdev->subsystem_vendor,
- skystar2->pdev->subsystem_device);
- } else {
- if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) {
- printk("skystar2: Frontend registration failed!\n");
- if (skystar2->fe->ops->release)
- skystar2->fe->ops->release(skystar2->fe);
- skystar2->fe = NULL;
- }
- }
-}
-
-
-static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct adapter *adapter;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
- int ret = -ENODEV;
-
- if (!pdev)
- goto out;
-
- ret = driver_initialize(pdev);
- if (ret < 0)
- goto out;
-
- adapter = pci_get_drvdata(pdev);
- dvb_adapter = &adapter->dvb_adapter;
-
- ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name,
- THIS_MODULE);
- if (ret < 0) {
- printk("%s: Error registering DVB adapter\n", __FUNCTION__);
- goto err_halt;
- }
-
- dvb_adapter->priv = adapter;
-
-
- init_MUTEX(&adapter->i2c_sem);
-
-
- memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
- strcpy(adapter->i2c_adap.name, "SkyStar2");
-
- i2c_set_adapdata(&adapter->i2c_adap, adapter);
-
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- adapter->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
- adapter->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
- adapter->i2c_adap.algo = &flexcop_algo;
- adapter->i2c_adap.algo_data = NULL;
- adapter->i2c_adap.id = I2C_ALGO_BIT;
-
- ret = i2c_add_adapter(&adapter->i2c_adap);
- if (ret < 0)
- goto err_dvb_unregister;
-
- dvbdemux = &adapter->demux;
-
- dvbdemux->priv = adapter;
- dvbdemux->filternum = N_PID_SLOTS;
- dvbdemux->feednum = N_PID_SLOTS;
- dvbdemux->start_feed = dvb_start_feed;
- dvbdemux->stop_feed = dvb_stop_feed;
- dvbdemux->write_to_decoder = NULL;
- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-
- ret = dvb_dmx_init(&adapter->demux);
- if (ret < 0)
- goto err_i2c_del;
-
- dmx = &dvbdemux->dmx;
-
- adapter->hw_frontend.source = DMX_FRONTEND_0;
- adapter->dmxdev.filternum = N_PID_SLOTS;
- adapter->dmxdev.demux = dmx;
- adapter->dmxdev.capabilities = 0;
-
- ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter);
- if (ret < 0)
- goto err_dmx_release;
-
- ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
- if (ret < 0)
- goto err_dmxdev_release;
-
- adapter->mem_frontend.source = DMX_MEMORY_FE;
-
- ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
- if (ret < 0)
- goto err_remove_hw_frontend;
-
- ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
- if (ret < 0)
- goto err_remove_mem_frontend;
-
- dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
-
- frontend_init(adapter);
-out:
- return ret;
-
-err_remove_mem_frontend:
- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
-err_remove_hw_frontend:
- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-err_dmxdev_release:
- dvb_dmxdev_release(&adapter->dmxdev);
-err_dmx_release:
- dvb_dmx_release(&adapter->demux);
-err_i2c_del:
- i2c_del_adapter(&adapter->i2c_adap);
-err_dvb_unregister:
- dvb_unregister_adapter(&adapter->dvb_adapter);
-err_halt:
- driver_halt(pdev);
- goto out;
-}
-
-static void skystar2_remove(struct pci_dev *pdev)
-{
- struct adapter *adapter = pci_get_drvdata(pdev);
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
-
- if (!adapter)
- return;
-
- dvb_net_release(&adapter->dvbnet);
- dvbdemux = &adapter->demux;
- dmx = &dvbdemux->dmx;
-
- dmx->close(dmx);
- dmx->remove_frontend(dmx, &adapter->hw_frontend);
- dmx->remove_frontend(dmx, &adapter->mem_frontend);
-
- dvb_dmxdev_release(&adapter->dmxdev);
- dvb_dmx_release(dvbdemux);
-
- if (adapter->fe != NULL)
- dvb_unregister_frontend(adapter->fe);
-
- dvb_unregister_adapter(&adapter->dvb_adapter);
-
- i2c_del_adapter(&adapter->i2c_adap);
-
- driver_halt(pdev);
- }
-
-static struct pci_device_id skystar2_pci_tbl[] = {
- {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
-/* {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */ //FCIII
- {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
-
-static struct pci_driver skystar2_pci_driver = {
- .name = "SkyStar2",
- .id_table = skystar2_pci_tbl,
- .probe = skystar2_probe,
- .remove = skystar2_remove,
-};
-
-static int skystar2_init(void)
-{
- return pci_register_driver(&skystar2_pci_driver);
-}
-
-static void skystar2_cleanup(void)
-{
- pci_unregister_driver(&skystar2_pci_driver);
-}
-
-module_init(skystar2_init);
-module_exit(skystar2_cleanup);
-
-MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 1339912c308..07a0b0a968a 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -258,10 +258,10 @@ int write_dst(struct dst_state *state, u8 *data, u8 len)
if (debug && (verbose > 4)) {
u8 i;
if (verbose > 4) {
- dprintk("%s writing", __FUNCTION__);
+ dprintk("%s writing [ ", __FUNCTION__);
for (i = 0; i < len; i++)
- dprintk(" %02x", data[i]);
- dprintk("\n");
+ dprintk("%02x ", data[i]);
+ dprintk("]\n");
}
}
for (cnt = 0; cnt < 2; cnt++) {
@@ -320,10 +320,29 @@ int read_dst(struct dst_state *state, u8 * ret, u8 len)
}
EXPORT_SYMBOL(read_dst);
-static int dst_set_freq(struct dst_state *state, u32 freq)
+static int dst_set_polarization(struct dst_state *state)
{
- u8 *val;
+ switch (state->voltage) {
+ case SEC_VOLTAGE_13: // vertical
+ printk("%s: Polarization=[Vertical]\n", __FUNCTION__);
+ state->tx_tuna[8] &= ~0x40; //1
+ break;
+
+ case SEC_VOLTAGE_18: // horizontal
+ printk("%s: Polarization=[Horizontal]\n", __FUNCTION__);
+ state->tx_tuna[8] |= 0x40; // 0
+ break;
+
+ case SEC_VOLTAGE_OFF:
+
+ break;
+ }
+
+ return 0;
+}
+static int dst_set_freq(struct dst_state *state, u32 freq)
+{
state->frequency = freq;
if (debug > 4)
dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
@@ -332,46 +351,30 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
freq = freq / 1000;
if (freq < 950 || freq > 2150)
return -EINVAL;
- val = &state->tx_tuna[0];
- val[2] = (freq >> 8) & 0x7f;
- val[3] = (u8) freq;
- val[4] = 1;
- val[8] &= ~4;
- if (freq < 1531)
- val[8] |= 4;
+
+ state->tx_tuna[2] = (freq >> 8);
+ state->tx_tuna[3] = (u8) freq;
+ state->tx_tuna[4] = 0x01;
+ state->tx_tuna[8] &= ~0x04;
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+ if (freq < 1531)
+ state->tx_tuna[8] |= 0x04;
+ }
+
} else if (state->dst_type == DST_TYPE_IS_TERR) {
freq = freq / 1000;
if (freq < 137000 || freq > 858000)
return -EINVAL;
- val = &state->tx_tuna[0];
- val[2] = (freq >> 16) & 0xff;
- val[3] = (freq >> 8) & 0xff;
- val[4] = (u8) freq;
- val[5] = 0;
- switch (state->bandwidth) {
- case BANDWIDTH_6_MHZ:
- val[6] = 6;
- break;
- case BANDWIDTH_7_MHZ:
- case BANDWIDTH_AUTO:
- val[6] = 7;
- break;
+ state->tx_tuna[2] = (freq >> 16) & 0xff;
+ state->tx_tuna[3] = (freq >> 8) & 0xff;
+ state->tx_tuna[4] = (u8) freq;
- case BANDWIDTH_8_MHZ:
- val[6] = 8;
- break;
- }
-
- val[7] = 0;
- val[8] = 0;
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
- /* guess till will get one */
- freq = freq / 1000;
- val = &state->tx_tuna[0];
- val[2] = (freq >> 16) & 0xff;
- val[3] = (freq >> 8) & 0xff;
- val[4] = (u8) freq;
+ state->tx_tuna[2] = (freq >> 16) & 0xff;
+ state->tx_tuna[3] = (freq >> 8) & 0xff;
+ state->tx_tuna[4] = (u8) freq;
+
} else
return -EINVAL;
return 0;
@@ -379,51 +382,58 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
{
- u8 *val;
-
state->bandwidth = bandwidth;
if (state->dst_type != DST_TYPE_IS_TERR)
return 0;
- val = &state->tx_tuna[0];
switch (bandwidth) {
- case BANDWIDTH_6_MHZ:
- val[6] = 6;
- break;
+ case BANDWIDTH_6_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x06;
+ else {
+ state->tx_tuna[6] = 0x06;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
- case BANDWIDTH_7_MHZ:
- val[6] = 7;
- break;
+ case BANDWIDTH_7_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x07;
+ else {
+ state->tx_tuna[6] = 0x07;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
- case BANDWIDTH_8_MHZ:
- val[6] = 8;
- break;
+ case BANDWIDTH_8_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x08;
+ else {
+ state->tx_tuna[6] = 0x08;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
return 0;
}
static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
{
- u8 *val;
-
state->inversion = inversion;
-
- val = &state->tx_tuna[0];
-
- val[8] &= ~0x80;
-
switch (inversion) {
- case INVERSION_OFF:
- break;
- case INVERSION_ON:
- val[8] |= 0x80;
- break;
- default:
- return -EINVAL;
+ case INVERSION_OFF: // Inversion = Normal
+ state->tx_tuna[8] &= ~0x80;
+ break;
+
+ case INVERSION_ON:
+ state->tx_tuna[8] |= 0x80;
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
@@ -478,6 +488,52 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
return 0;
}
+
+static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
+{
+ if (state->dst_type != DST_TYPE_IS_CABLE)
+ return 0;
+
+ state->modulation = modulation;
+ switch (modulation) {
+ case QAM_16:
+ state->tx_tuna[8] = 0x10;
+ break;
+
+ case QAM_32:
+ state->tx_tuna[8] = 0x20;
+ break;
+
+ case QAM_64:
+ state->tx_tuna[8] = 0x40;
+ break;
+
+ case QAM_128:
+ state->tx_tuna[8] = 0x80;
+ break;
+
+ case QAM_256:
+ state->tx_tuna[8] = 0x00;
+ break;
+
+ case QPSK:
+ case QAM_AUTO:
+ case VSB_8:
+ case VSB_16:
+ default:
+ return -EINVAL;
+
+ }
+
+ return 0;
+}
+
+static fe_modulation_t dst_get_modulation(struct dst_state *state)
+{
+ return state->modulation;
+}
+
+
u8 dst_check_sum(u8 * buf, u32 len)
{
u32 i;
@@ -577,7 +633,7 @@ struct dst_types dst_tlist[] = {
.device_id = "200103A",
.offset = 0,
.dst_type = DST_TYPE_IS_SAT,
- .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+ .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
.dst_feature = 0
}, /* obsolete */
@@ -626,7 +682,7 @@ struct dst_types dst_tlist[] = {
.device_id = "DSTMCI",
.offset = 1,
.dst_type = DST_TYPE_IS_SAT,
- .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+ .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT,
.dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
| DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
},
@@ -872,7 +928,7 @@ static int dst_get_signal(struct dst_state* state)
{
int retval;
u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
-
+ dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
state->decode_lock = state->decode_strength = state->decode_snr = 0;
return 0;
@@ -954,15 +1010,8 @@ static int dst_get_tuna(struct dst_state* state)
state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
state->decode_lock = 1;
- /*
- dst->decode_n1 = (dst->rx_tuna[4] << 8) +
- (dst->rx_tuna[5]);
-
- dst->decode_n2 = (dst->rx_tuna[8] << 8) +
- (dst->rx_tuna[7]);
- */
state->diseq_flags |= HAS_LOCK;
- /* dst->cur_jiff = jiffies; */
+
return 1;
}
@@ -1098,7 +1147,11 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch (tone) {
case SEC_TONE_OFF:
- state->tx_tuna[2] = 0xff;
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+ state->tx_tuna[2] = 0x00;
+ else
+ state->tx_tuna[2] = 0xff;
+
break;
case SEC_TONE_ON:
@@ -1145,7 +1198,8 @@ static int dst_init(struct dvb_frontend* fe)
static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- state->inversion = INVERSION_ON;
+// state->inversion = INVERSION_ON;
+ state->inversion = INVERSION_OFF;
state->voltage = SEC_VOLTAGE_13;
state->tone = SEC_TONE_OFF;
state->symbol_rate = 29473000;
@@ -1174,7 +1228,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status = 0;
if (state->diseq_flags & HAS_LOCK) {
- dst_get_signal(state);
+// dst_get_signal(state); // don't require(?) to ask MCU
if (state->decode_lock)
*status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
}
@@ -1208,20 +1262,25 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
dst_set_freq(state, p->frequency);
if (verbose > 4)
- dprintk("Set Frequency = [%d]\n", p->frequency);
+ dprintk("Set Frequency=[%d]\n", p->frequency);
- dst_set_inversion(state, p->inversion);
+// dst_set_inversion(state, p->inversion);
if (state->dst_type == DST_TYPE_IS_SAT) {
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+ dst_set_inversion(state, p->inversion);
+
dst_set_fec(state, p->u.qpsk.fec_inner);
dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
+ dst_set_polarization(state);
if (verbose > 4)
- dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
+ dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
} else if (state->dst_type == DST_TYPE_IS_TERR) {
dst_set_bandwidth(state, p->u.ofdm.bandwidth);
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
dst_set_fec(state, p->u.qam.fec_inner);
dst_set_symbolrate(state, p->u.qam.symbol_rate);
+ dst_set_modulation(state, p->u.qam.modulation);
}
dst_write_tuna(fe);
@@ -1233,8 +1292,11 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
struct dst_state* state = fe->demodulator_priv;
p->frequency = state->decode_freq;
- p->inversion = state->inversion;
+// p->inversion = state->inversion;
if (state->dst_type == DST_TYPE_IS_SAT) {
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+ p->inversion = state->inversion;
+
p->u.qpsk.symbol_rate = state->symbol_rate;
p->u.qpsk.fec_inner = dst_get_fec(state);
} else if (state->dst_type == DST_TYPE_IS_TERR) {
@@ -1242,7 +1304,8 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
p->u.qam.symbol_rate = state->symbol_rate;
p->u.qam.fec_inner = dst_get_fec(state);
- p->u.qam.modulation = QAM_AUTO;
+// p->u.qam.modulation = QAM_AUTO;
+ p->u.qam.modulation = dst_get_modulation(state);
}
return 0;
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index d781504cc2f..bfaacd5fc20 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -32,7 +32,7 @@
#include "dst_ca.h"
#include "dst_common.h"
-static unsigned int verbose = 1;
+static unsigned int verbose = 5;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
@@ -295,34 +295,28 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
return 0;
}
-static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
+static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
{
if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
}
else {
+ hw_buffer->msg[0] = (length & 0xff) + 7;
+ hw_buffer->msg[1] = 0x40;
hw_buffer->msg[2] = 0x03;
hw_buffer->msg[3] = 0x00;
+ hw_buffer->msg[4] = 0x03;
+ hw_buffer->msg[5] = length & 0xff;
+ hw_buffer->msg[6] = 0x00;
}
return 0;
}
-static int debug_8820_buffer(struct ca_msg *hw_buffer)
-{
- unsigned int i;
-
- dprintk("%s:Debug=[", __FUNCTION__);
- for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
- dprintk(" %02x", hw_buffer->msg[i]);
- dprintk("]\n");
-
- return 0;
-}
-static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply)
+static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
{
- if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) {
+ if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
dprintk("%s: Resetting DST.\n", __FUNCTION__);
rdc_reset_state(state);
@@ -334,234 +328,141 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 r
return 0;
}
-
-static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+u32 asn_1_decode(u8 *asn_1_array)
{
- u32 hw_offset, buf_offset, i, k;
- u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0;
- u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0;
-
- if (verbose > 3)
- dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length );
-
- handle_en50221_tag(state, p_ca_message, hw_buffer); /* EN50221 tag */
-
- /* Handle the length field (variable) */
- if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */
- length = p_ca_message->msg[3] & 0x7f;
- words = 0; /* domi's suggestion */
- }
- else { /* Length = words */
- words = p_ca_message->msg[3] & 0x7f;
- for (i = 0; i < words; i++) {
- length = length << 8;
- length = length | p_ca_message->msg[4 + i];
+ u8 length_field = 0, word_count = 0, count = 0;
+ u32 length = 0;
+
+ length_field = asn_1_array[0];
+ dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field);
+ if (length_field < 0x80) {
+ length = length_field & 0x7f;
+ dprintk("%s: Length=[%02x]\n", __FUNCTION__, length);
+ } else {
+ word_count = length_field & 0x7f;
+ for (count = 0; count < word_count; count++) {
+ length = (length | asn_1_array[count + 1]) << 8;
+ dprintk("%s: Length=[%04x]\n", __FUNCTION__, length);
}
}
- if (verbose > 4) {
- dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words);
-
- /* Debug Input string */
- for (i = 0; i < length; i++)
- dprintk(" %02x", p_ca_message->msg[i]);
- dprintk("]\n");
- }
-
- hw_offset = 7;
- buf_offset = words + 4;
-
- /* Program Header */
- if (verbose > 4)
- dprintk("\n%s:Program Header=[", __FUNCTION__);
- for (i = 0; i < 6; i++) {
- hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
- if (verbose > 4)
- dprintk(" %02x", p_ca_message->msg[buf_offset]);
- hw_offset++, buf_offset++, hw_buffer_length++;
- }
- if (verbose > 4)
- dprintk("]\n");
+ return length;
+}
- program_info_length = 0;
- program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9];
- if (verbose > 4)
- dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n",
- __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset);
+static int init_buffer(u8 *buffer, u32 length)
+{
+ u32 i;
+ for (i = 0; i < length; i++)
+ buffer[i] = 0;
- if (program_info_length && (program_info_length < 256)) { /* If program_info_length */
- hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */
- hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */
+ return 0;
+}
- if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */
- found_prog_ca_desc = 1;
- if (verbose > 4)
- dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
- }
+static int debug_string(u8 *msg, u32 length, u32 offset)
+{
+ u32 i;
- if (found_prog_ca_desc) { /* Command only if CA descriptor */
- hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */
- hw_offset++, buf_offset++, hw_buffer_length++;
- }
+ dprintk(" String=[ ");
+ for (i = offset; i < length; i++)
+ dprintk("%02x ", msg[i]);
+ dprintk("]\n");
- /* Program descriptors */
- if (verbose > 4) {
- dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
- dprintk("%s:Program descriptors=[", __FUNCTION__);
- }
- while (program_info_length && !error_condition) { /* Copy prog descriptors */
- if (program_info_length > p_ca_message->length) { /* Error situation */
- dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
- __FUNCTION__, __LINE__, program_info_length);
- dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
- error_condition = 1;
- break;
- }
+ return 0;
+}
- hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
- dprintk(" %02x", p_ca_message->msg[buf_offset]);
- hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--;
- }
- if (verbose > 4) {
- dprintk("]\n");
- dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
- }
- if (found_prog_ca_desc) {
- if (!reply) {
- hw_buffer->msg[13] = 0x01; /* OK descrambling */
- if (verbose > 1)
- dprintk("CA PMT Command = OK Descrambling\n");
- }
- else {
- hw_buffer->msg[13] = 0x02; /* Ok MMI */
- if (verbose > 1)
- dprintk("CA PMT Command = Ok MMI\n");
- }
- if (query) {
- hw_buffer->msg[13] = 0x03; /* Query */
- if (verbose > 1)
- dprintk("CA PMT Command = CA PMT query\n");
- }
- }
- }
- else {
- hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */
- hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
+static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
+{
+ u32 i;
+ dprintk("%s: Copying [", __FUNCTION__);
+ for (i = 0; i < length; i++) {
+ destination[i + dest_offset] = source[i + source_offset];
+ dprintk(" %02x", source[i + source_offset]);
}
- if (verbose > 4)
- dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
- __FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
-
- while ((buf_offset < p_ca_message->length) && !error_condition) {
- /* Bail out in case of an indefinite loop */
- if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
- dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
- __FUNCTION__, __LINE__, program_info_length, buf_offset);
-
- dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
- error_condition = 1;
- break;
- }
-
- /* Stream Header */
-
- for (k = 0; k < 5; k++) {
- hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
- }
+ dprintk("]\n");
- es_info_length = 0;
- es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4];
+ return i;
+}
- if (verbose > 4) {
- dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__,
- p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1],
- p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
- p_ca_message->msg[buf_offset + 4]);
+static int modify_4_bits(u8 *message, u32 pos)
+{
+ message[pos] &= 0x0f;
- dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__,
- p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length,
- p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
- }
+ return 0;
+}
- hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */
- if (found_prog_ca_desc) {
- hw_buffer->msg[hw_offset + 3] = 0x00;
- hw_buffer->msg[hw_offset + 4] = 0x00;
- }
- hw_offset += 5, buf_offset += 5, hw_buffer_length += 5;
+static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+{
+ u32 length = 0, count = 0;
+ u8 asn_1_words, program_header_length;
+ u16 program_info_length = 0, es_info_length = 0;
+ u32 hw_offset = 0, buf_offset = 0, i;
+ u8 dst_tag_length;
- /* Check for CA descriptor */
- if (p_ca_message->msg[buf_offset + 1] == 0x09) {
- if (verbose > 4)
- dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__);
- found_stream_ca_desc = 1;
- }
+ length = asn_1_decode(&p_ca_message->msg[3]);
+ dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
+ dprintk("%s: ASN.1 ", __FUNCTION__);
+ debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
- /* ES descriptors */
-
- if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
-// if (!ca_pmt_done) {
- hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */
- if (verbose > 4)
- printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
-// hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
- hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
-// }
- if (verbose > 4)
- dprintk("%s:----->ES descriptors=[", __FUNCTION__);
-
- while (es_info_length && !error_condition) { /* ES descriptors */
- if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
- if (verbose > 4) {
- dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
- __FUNCTION__, __LINE__, es_info_length, buf_offset);
-
- dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
- }
- error_condition = 1;
- break;
- }
+ init_buffer(hw_buffer->msg, length);
+ handle_dst_tag(state, p_ca_message, hw_buffer, length);
- hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
- if (verbose > 3)
- dprintk("%02x ", hw_buffer->msg[hw_offset]);
- hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
- }
- found_stream_ca_desc = 0; /* unset for new streams */
- dprintk("]\n");
+ hw_offset = 7;
+ asn_1_words = 1; // just a hack to test, should compute this one
+ buf_offset = 3;
+ program_header_length = 6;
+ dst_tag_length = 7;
+
+// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
+// dprintk("%s: Program Header(BUF)", __FUNCTION__);
+// debug_string(&p_ca_message->msg[4], program_header_length, 0);
+// dprintk("%s: Copying Program header\n", __FUNCTION__);
+ copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
+ buf_offset += program_header_length, hw_offset += program_header_length;
+ modify_4_bits(hw_buffer->msg, (hw_offset - 2));
+ if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
+ dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
+ debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
+ hw_buffer->msg[hw_offset - 1] += 1;
+ }
+
+// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
+// debug_string(hw_buffer->msg, hw_offset, 0);
+
+ program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
+ dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
+ if (program_info_length) {
+ count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
+ buf_offset += count, hw_offset += count;
+// dprintk("%s: Program level ", __FUNCTION__);
+// debug_string(hw_buffer->msg, hw_offset, 0);
+ }
+
+ buf_offset += 1;// hw_offset += 1;
+ for (i = buf_offset; i < length; i++) {
+// dprintk("%s: Stream Header ", __FUNCTION__);
+ count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
+ modify_4_bits(hw_buffer->msg, (hw_offset + 3));
+
+ hw_offset += 5, buf_offset += 5, i += 4;
+// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
+ es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
+ dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
+ if (es_info_length) {
+ // copy descriptors @ STREAM level
+ dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
}
- }
-
- /* MCU Magic words */
-
- hw_buffer_length += 7;
- hw_buffer->msg[0] = hw_buffer_length;
- hw_buffer->msg[1] = 64;
- hw_buffer->msg[4] = 3;
- hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
- hw_buffer->msg[6] = 0;
-
- /* Fix length */
- hw_buffer->length = hw_buffer->msg[0];
-
- put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
- /* Do the actual write */
- if (verbose > 4) {
- dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
- dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
}
- /* Only for debugging! */
- if (verbose > 2)
- debug_8820_buffer(hw_buffer);
- if (verbose > 3)
- dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
- write_to_8820(state, hw_buffer, reply);
+ hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
+// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
+ debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
+ write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
return 0;
}
+
/* Board supports CA PMT reply ? */
static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
{
@@ -605,7 +506,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer;
if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- printk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk("%s: Memory allocation failure\n", __FUNCTION__);
return -ENOMEM;
}
if (verbose > 3)
@@ -630,8 +531,10 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
switch (command) {
case CA_PMT:
if (verbose > 3)
+// dprintk("Command = SEND_CA_PMT\n");
dprintk("Command = SEND_CA_PMT\n");
- if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
+// if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
+ if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
return -1;
}
@@ -664,7 +567,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
return -1;
}
if (verbose > 3)
- printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
+ dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
break;
}
@@ -681,17 +584,17 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct ca_msg *p_ca_message;
if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- printk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk("%s: Memory allocation failure\n", __FUNCTION__);
return -ENOMEM;
}
if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
- printk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk("%s: Memory allocation failure\n", __FUNCTION__);
return -ENOMEM;
}
if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
- printk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk("%s: Memory allocation failure\n", __FUNCTION__);
return -ENOMEM;
}
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 0b3da29245f..ef532a6acea 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -47,6 +47,8 @@
#define DST_TYPE_HAS_FW_2 16
#define DST_TYPE_HAS_FW_3 32
#define DST_TYPE_HAS_FW_BUILD 64
+#define DST_TYPE_HAS_OBS_REGS 128
+#define DST_TYPE_HAS_INC_COUNT 256
/* Card capability list */
@@ -110,6 +112,7 @@ struct dst_state {
u32 dst_hw_cap;
u8 dst_fw_version;
fe_sec_mini_cmd_t minicmd;
+ fe_modulation_t modulation;
u8 messages[256];
};
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 96c57fde95a..7d8b3cad350 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -699,6 +699,8 @@ static void cinergyt2_query_rc (void *data)
for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
int i;
+/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/
+
if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
rc_events[n].value == ~0)
{
@@ -714,7 +716,7 @@ static void cinergyt2_query_rc (void *data)
cinergyt2->rc_input_event = KEY_MAX;
for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
if (rc_keys[i+0] == rc_events[n].type &&
- rc_keys[i+1] == rc_events[n].value)
+ rc_keys[i+1] == le32_to_cpu(rc_events[n].value))
{
cinergyt2->rc_input_event = rc_keys[i+2];
break;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index c225de7ffd8..68050cd527c 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -42,12 +42,6 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
#define dprintk if (debug) printk
-static inline struct dmxdev_filter *
-dvb_dmxdev_file_to_filter(struct file *file)
-{
- return (struct dmxdev_filter *) file->private_data;
-}
-
static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
{
buffer->data=NULL;
@@ -669,8 +663,10 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
ret = filter->feed.ts->start_filtering(filter->feed.ts);
- if (ret < 0)
+ if (ret < 0) {
+ dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
return ret;
+ }
break;
}
@@ -842,7 +838,7 @@ static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
static ssize_t
dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
- struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
+ struct dmxdev_filter *dmxdevfilter= file->private_data;
int ret=0;
if (down_interruptible(&dmxdevfilter->mutex))
@@ -863,7 +859,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
+ struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev=dmxdevfilter->dev;
unsigned long arg=(unsigned long) parg;
int ret=0;
@@ -960,7 +956,7 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file,
static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
{
- struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
+ struct dmxdev_filter *dmxdevfilter = file->private_data;
unsigned int mask = 0;
if (!dmxdevfilter)
@@ -985,7 +981,7 @@ static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
static int dvb_demux_release(struct inode *inode, struct file *file)
{
- struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
+ struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
@@ -1109,7 +1105,6 @@ dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
dmxdev->dvr[i].dev=dmxdev;
dmxdev->dvr[i].buffer.data=NULL;
- dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
}
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f11daae91cd..a8bc84240b5 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,6 +42,8 @@
#include "dvb_frontend.h"
#include "dvbdev.h"
+// #define DEBUG_LOCKLOSS 1
+
static int dvb_frontend_debug;
static int dvb_shutdown_timeout = 5;
static int dvb_force_auto_inversion;
@@ -113,6 +115,7 @@ struct dvb_frontend_private {
int exit;
int wakeup;
fe_status_t status;
+ fe_sec_tone_mode_t tone;
};
@@ -434,9 +437,26 @@ static int dvb_frontend_thread(void *data)
/* we're tuned, and the lock is still good... */
if (s & FE_HAS_LOCK)
continue;
- else {
- /* if we _WERE_ tuned, but now don't have a lock,
- * need to zigzag */
+ else { /* if we _WERE_ tuned, but now don't have a lock */
+#ifdef DEBUG_LOCKLOSS
+ /* first of all try setting the tone again if it was on - this
+ * sometimes works around problems with noisy power supplies */
+ if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
+ fe->ops->set_tone(fe, fepriv->tone);
+ mdelay(100);
+ s = 0;
+ fe->ops->read_status(fe, &s);
+ if (s & FE_HAS_LOCK) {
+ printk("DVB%i: Lock was lost, but regained by setting "
+ "the tone. This may indicate your power supply "
+ "is noisy/slightly incompatable with this DVB-S "
+ "adapter\n", fe->dvb->num);
+ fepriv->state = FESTATE_TUNED;
+ continue;
+ }
+ }
+#endif
+ /* some other reason for losing the lock - start zigzagging */
fepriv->state = FESTATE_ZIGZAG_FAST;
fepriv->started_auto_step = fepriv->auto_step;
check_wrapped = 0;
@@ -626,11 +646,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
break;
}
- case FE_READ_STATUS:
+ case FE_READ_STATUS: {
+ fe_status_t* status = parg;
+
+ /* if retune was requested but hasn't occured yet, prevent
+ * that user get signal state from previous tuning */
+ if(fepriv->state == FESTATE_RETUNE) {
+ err=0;
+ *status = 0;
+ break;
+ }
+
if (fe->ops->read_status)
- err = fe->ops->read_status(fe, (fe_status_t*) parg);
+ err = fe->ops->read_status(fe, status);
break;
-
+ }
case FE_READ_BER:
if (fe->ops->read_ber)
err = fe->ops->read_ber(fe, (__u32*) parg);
@@ -681,6 +711,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
+ fepriv->tone = (fe_sec_tone_mode_t) parg;
}
break;
@@ -883,6 +914,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
init_MUTEX (&fepriv->events.sem);
fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF;
+ fepriv->tone = SEC_TONE_OFF;
printk ("DVB: registering frontend %i (%s)...\n",
fe->dvb->num,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index d2b02179279..9c2c1d1136b 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -40,28 +40,6 @@
#include "dvbdev.h"
-/* FIXME: Move to i2c-id.h */
-#define I2C_DRIVERID_DVBFE_SP8870 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX22700 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_MT312 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_MT352 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_NXT6000 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_SP887X I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_STV0299 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA1004X I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA8083 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_VES1820 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_VES1X93 I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA80XX I2C_DRIVERID_EXP2
-
-
struct dvb_frontend_tune_settings {
int min_delay_ms;
int step_size;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 8aa32f6e447..612e5b087b1 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -3,30 +3,35 @@ config DVB_USB
depends on DVB_CORE && USB
select FW_LOADER
help
- By enabling this you will be able to choose the various USB 1.1 and
- USB2.0 DVB devices.
+ By enabling this you will be able to choose the various supported
+ USB1.1 and USB2.0 DVB devices.
Almost every USB device needs a firmware, please look into
- <file:Documentation/dvb/README.dvb-usb>
+ <file:Documentation/dvb/README.dvb-usb>.
- Say Y if you own an USB DVB device.
+ For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+ <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+ Say Y if you own a USB DVB device.
config DVB_USB_DEBUG
bool "Enable extended debug support for all DVB-USB devices"
depends on DVB_USB
help
- Say Y if you want to enable debuging. See modinfo dvb-usb (and the
+ Say Y if you want to enable debugging. See modinfo dvb-usb (and the
appropriate drivers) for debug levels.
config DVB_USB_A800
tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
depends on DVB_USB
+ select DVB_DIB3000MC
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
config DVB_USB_DIBUSB_MB
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
depends on DVB_USB
+ select DVB_DIB3000MB
help
Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -52,6 +57,7 @@ config DVB_USB_DIBUSB_MB
config DVB_USB_DIBUSB_MC
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
depends on DVB_USB
+ select DVB_DIB3000MC
help
Support for 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -66,12 +72,23 @@ config DVB_USB_DIBUSB_MC
config DVB_USB_UMT_010
tristate "HanfTek UMT-010 DVB-T USB2.0 support"
depends on DVB_USB
+ select DVB_DIB3000MC
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
+config DVB_USB_CXUSB
+ tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+ depends on DVB_USB
+ select DVB_CX22702
+ help
+ Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
+ only the DVB-T part is supported.
+
config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB
+ select DVB_NXT6000
+ select DVB_MT352
help
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
@@ -87,13 +104,16 @@ config DVB_USB_VP7045
config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
depends on DVB_USB
+ select DVB_DIB3000MC
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
config DVB_USB_DTT200U
- tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support"
+ tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
depends on DVB_USB
help
- Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
+ Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
+
+ The WT-220U and its clones are pen-sized.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index d65b50f9abb..746d87ed6f3 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -27,4 +27,7 @@ obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
dvb-usb-digitv-objs = digitv.o
obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
+dvb-usb-cxusb-objs = cxusb.o
+obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
+
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index a3542935604..f2fcc2f1f84 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -61,6 +61,12 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
{ 0x02, 0x04, KEY_EPG }, /* EPG */
{ 0x02, 0x15, KEY_MENU }, /* MENU */
+
+ { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */
+ { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
+ { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */
+ { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */
+
};
int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -68,7 +74,7 @@ int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
u8 key[5];
if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
- 2*HZ) != 5)
+ 2000) != 5)
return -ENODEV;
/* call the universal NEC remote processor, to find out the key's state and event */
@@ -143,7 +149,7 @@ static struct dvb_usb_properties a800_properties = {
static struct usb_driver a800_driver = {
.owner = THIS_MODULE,
- .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)",
+ .name = "dvb_usb_a800",
.probe = a800_probe,
.disconnect = dvb_usb_device_exit,
.id_table = a800_table,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
new file mode 100644
index 00000000000..c3e1b661aae
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -0,0 +1,295 @@
+/* DVB USB compliant linux driver for Conexant USB reference design.
+ *
+ * The Conexant reference design I saw on their website was only for analogue
+ * capturing (using the cx25842). The box I took to write this driver (reverse
+ * engineered) is the one labeled Medion MD95700. In addition to the cx25842
+ * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
+ * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
+ *
+ * Maybe it is a little bit premature to call this driver cxusb, but I assume
+ * the USB protocol is identical or at least inherited from the reference
+ * design, so it can be reused for the "analogue-only" device (if it will
+ * appear at all).
+ *
+ * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue
+ * part
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "cxusb.h"
+
+#include "cx22702.h"
+
+/* debug */
+int dvb_usb_cxusb_debug;
+module_param_named(debug,dvb_usb_cxusb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int cxusb_ctrl_msg(struct dvb_usb_device *d,
+ u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ int wo = (rbuf == NULL || rlen == 0); /* write-only */
+ u8 sndbuf[1+wlen];
+ memset(sndbuf,0,1+wlen);
+
+ sndbuf[0] = cmd;
+ memcpy(&sndbuf[1],wbuf,wlen);
+ if (wo)
+ dvb_usb_generic_write(d,sndbuf,1+wlen);
+ else
+ dvb_usb_generic_rw(d,sndbuf,1+wlen,rbuf,rlen,0);
+
+ return 0;
+}
+
+/* I2C */
+static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
+{
+ struct cxusb_state *st = d->priv;
+ u8 o[2],i;
+
+ if (path == st->cur_i2c_path)
+ return;
+
+ o[0] = IOCTL_SET_I2C_PATH;
+ switch (path) {
+ case PATH_CX22702:
+ o[1] = 0;
+ break;
+ case PATH_TUNER_OTHER:
+ o[1] = 1;
+ break;
+ default:
+ err("unkown i2c path");
+ return;
+ }
+ cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
+
+ if (i != 0x01)
+ deb_info("i2c_path setting failed.\n");
+
+ st->cur_i2c_path = path;
+}
+
+static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i;
+
+ if (down_interruptible(&d->i2c_sem) < 0)
+ return -EAGAIN;
+
+ if (num > 2)
+ warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+
+ switch (msg[i].addr) {
+ case 0x63:
+ cxusb_set_i2c_path(d,PATH_CX22702);
+ break;
+ default:
+ cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+ break;
+ }
+
+ /* read request */
+ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+ u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
+ obuf[0] = msg[i].len;
+ obuf[1] = msg[i+1].len;
+ obuf[2] = msg[i].addr;
+ memcpy(&obuf[3],msg[i].buf,msg[i].len);
+
+ if (cxusb_ctrl_msg(d, CMD_I2C_READ,
+ obuf, 3+msg[i].len,
+ ibuf, 1+msg[i+1].len) < 0)
+ break;
+
+ if (ibuf[0] != 0x08)
+ deb_info("i2c read could have been failed\n");
+
+ memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
+
+ i++;
+ } else { /* write */
+ u8 obuf[2+msg[i].len], ibuf;
+ obuf[0] = msg[i].addr;
+ obuf[1] = msg[i].len;
+ memcpy(&obuf[2],msg[i].buf,msg[i].len);
+
+ if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
+ break;
+ if (ibuf != 0x08)
+ deb_info("i2c write could have been failed\n");
+ }
+ }
+
+ up(&d->i2c_sem);
+ return i;
+}
+
+static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cxusb_i2c_algo = {
+ .name = "Conexant USB I2C algorithm",
+ .id = I2C_ALGO_BIT,
+ .master_xfer = cxusb_i2c_xfer,
+ .functionality = cxusb_i2c_func,
+};
+
+static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ return 0;
+}
+
+static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 buf[2] = { 0x03, 0x00 };
+ if (onoff)
+ cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+ else
+ cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
+
+ return 0;
+}
+
+struct cx22702_config cxusb_cx22702_config = {
+ .demod_address = 0x63,
+
+ .output_mode = CX22702_PARALLEL_OUTPUT,
+
+ .pll_init = dvb_usb_pll_init_i2c,
+ .pll_set = dvb_usb_pll_set_i2c,
+};
+
+/* Callbacks for DVB USB */
+static int cxusb_tuner_attach(struct dvb_usb_device *d)
+{
+ u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+ d->pll_addr = 0x61;
+ memcpy(d->pll_init,bpll,4);
+ d->pll_desc = &dvb_pll_fmd1216me;
+ return 0;
+}
+
+static int cxusb_frontend_attach(struct dvb_usb_device *d)
+{
+ u8 buf[2] = { 0x03, 0x00 };
+ u8 b = 0;
+
+ if (usb_set_interface(d->udev,0,0) < 0)
+ err("set interface to alts=0 failed");
+
+ cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
+ cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+ cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
+
+ if (usb_set_interface(d->udev,0,6) < 0)
+ err("set interface failed");
+
+ cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+ cxusb_set_i2c_path(d,PATH_CX22702);
+ cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
+
+ if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
+ return 0;
+
+ return -EIO;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_properties cxusb_properties;
+
+static int cxusb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
+}
+
+static struct usb_device_id cxusb_table [] = {
+ { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
+ {} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, cxusb_table);
+
+static struct dvb_usb_properties cxusb_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+ .power_ctrl = cxusb_power_ctrl,
+ .frontend_attach = cxusb_frontend_attach,
+ .tuner_attach = cxusb_tuner_attach,
+
+ .i2c_algo = &cxusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_ISOC,
+ .count = 5,
+ .endpoint = 0x02,
+ .u = {
+ .isoc = {
+ .framesperurb = 32,
+ .framesize = 940,
+ .interval = 5,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Medion MD95700 (MDUSBTV-HYBRID)",
+ { NULL },
+ { &cxusb_table[0], NULL },
+ },
+ }
+};
+
+static struct usb_driver cxusb_driver = {
+ .owner = THIS_MODULE,
+ .name = "dvb_usb_cxusb",
+ .probe = cxusb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = cxusb_table,
+};
+
+/* module stuff */
+static int __init cxusb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&cxusb_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit cxusb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&cxusb_driver);
+}
+
+module_init (cxusb_module_init);
+module_exit (cxusb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
new file mode 100644
index 00000000000..1d79016e319
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -0,0 +1,30 @@
+#ifndef _DVB_USB_CXUSB_H_
+#define _DVB_USB_CXUSB_H_
+
+#define DVB_USB_LOG_PREFIX "digitv"
+#include "dvb-usb.h"
+
+extern int dvb_usb_cxusb_debug;
+#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
+
+/* usb commands - some of it are guesses, don't have a reference yet */
+#define CMD_I2C_WRITE 0x08
+#define CMD_I2C_READ 0x09
+
+#define CMD_IOCTL 0x0e
+#define IOCTL_SET_I2C_PATH 0x02
+
+#define CMD_POWER_OFF 0x50
+#define CMD_POWER_ON 0x51
+
+enum cxusb_i2c_pathes {
+ PATH_UNDEF = 0x00,
+ PATH_CX22702 = 0x01,
+ PATH_TUNER_OTHER = 0x02,
+};
+
+struct cxusb_state {
+ enum cxusb_i2c_pathes cur_i2c_path;
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index a0ffbb59fa1..828b5182e16 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -31,10 +31,17 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
return 0;
}
-/* some of the dibusb 1.1 device aren't equipped with the default tuner
+static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
+{
+ d->pll_addr = 0x61;
+ d->pll_desc = &dvb_pll_tua6010xs;
+ return 0;
+}
+
+/* Some of the Artec 1.1 device aren't equipped with the default tuner
* (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
* this out. */
-static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d)
+static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
{
u8 b[2] = { 0,0 }, b2[1];
int ret = 0;
@@ -59,8 +66,7 @@ static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d)
if (b2[0] == 0xfe) {
info("this device has the Thomson Cable onboard. Which is default.");
- d->pll_addr = 0x61;
- d->pll_desc = &dvb_pll_tua6010xs;
+ dibusb_thomson_tuner_attach(d);
} else {
u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
info("this device has the Panasonic ENV77H11D5 onboard.");
@@ -90,8 +96,8 @@ static int dibusb_probe(struct usb_interface *intf,
/* do not change the order of the ID table */
static struct usb_device_id dibusb_dib3000mb_table [] = {
-/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
+/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
@@ -114,7 +120,17 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
+
+/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
+/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
+/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
+
+// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+#endif
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
@@ -134,7 +150,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
.pid_filter_ctrl = dibusb_pid_filter_ctrl,
.power_ctrl = dibusb_power_ctrl,
.frontend_attach = dibusb_dib3000mb_frontend_attach,
- .tuner_attach = dibusb_dib3000mb_tuner_attach,
+ .tuner_attach = dibusb_tuner_probe_and_attach,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
@@ -156,7 +172,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
}
},
- .num_device_descs = 8,
+ .num_device_descs = 9,
.devices = {
{ "AVerMedia AverTV DVBT USB1.1",
{ &dibusb_dib3000mb_table[0], NULL },
@@ -190,11 +206,17 @@ static struct dvb_usb_properties dibusb1_1_properties = {
{ &dibusb_dib3000mb_table[19], NULL },
{ &dibusb_dib3000mb_table[20], NULL },
},
+ { "VideoWalker DVB-T USB",
+ { &dibusb_dib3000mb_table[25], NULL },
+ { &dibusb_dib3000mb_table[26], NULL },
+ },
}
};
static struct dvb_usb_properties dibusb1_1_an2235_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 16,
+
.usb_ctrl = CYPRESS_AN2235,
.firmware = "dvb-usb-dibusb-an2235-01.fw",
@@ -206,7 +228,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
.pid_filter_ctrl = dibusb_pid_filter_ctrl,
.power_ctrl = dibusb_power_ctrl,
.frontend_attach = dibusb_dib3000mb_frontend_attach,
- .tuner_attach = dibusb_dib3000mb_tuner_attach,
+ .tuner_attach = dibusb_tuner_probe_and_attach,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
@@ -228,20 +250,32 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
}
},
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+ .num_device_descs = 2,
+#else
.num_device_descs = 1,
+#endif
.devices = {
{ "Artec T1 USB1.1 TVBOX with AN2235",
{ &dibusb_dib3000mb_table[20], NULL },
{ &dibusb_dib3000mb_table[21], NULL },
},
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+ { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
+ { &dibusb_dib3000mb_table[27], NULL },
+ { NULL },
+ },
+#endif
}
};
static struct dvb_usb_properties dibusb2_0b_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 32,
+
.usb_ctrl = CYPRESS_FX2,
- .firmware = "dvb-usb-adstech-usb2-01.fw",
+ .firmware = "dvb-usb-adstech-usb2-02.fw",
.size_of_priv = sizeof(struct dibusb_state),
@@ -250,7 +284,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
.pid_filter_ctrl = dibusb_pid_filter_ctrl,
.power_ctrl = dibusb2_0_power_ctrl,
.frontend_attach = dibusb_dib3000mb_frontend_attach,
- .tuner_attach = dibusb_dib3000mb_tuner_attach,
+ .tuner_attach = dibusb_thomson_tuner_attach,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
@@ -272,18 +306,18 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
}
},
- .num_device_descs = 2,
+ .num_device_descs = 1,
.devices = {
{ "KWorld/ADSTech Instant DVB-T USB 2.0",
{ &dibusb_dib3000mb_table[23], NULL },
- { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */
+ { &dibusb_dib3000mb_table[24], NULL },
},
}
};
static struct usb_driver dibusb_driver = {
.owner = THIS_MODULE,
- .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)",
+ .name = "dvb_usb_dibusb_mb",
.probe = dibusb_probe,
.disconnect = dvb_usb_device_exit,
.id_table = dibusb_dib3000mb_table,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index aad8ed3fe00..e9dac430f37 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -83,7 +83,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
static struct usb_driver dibusb_mc_driver = {
.owner = THIS_MODULE,
- .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices",
+ .name = "dvb_usb_dibusb_mc",
.probe = dibusb_mc_probe,
.disconnect = dvb_usb_device_exit,
.id_table = dibusb_dib3000mc_table,
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 5acf3fde952..9a676afc1d6 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -1,10 +1,9 @@
/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
* receiver
*
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and
- * Allan Third (allan.third@cs.man.ac.uk)
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
*
- * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?)
+ * partly based on the SDK published by Nebula Electronics
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -38,7 +37,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
dvb_usb_generic_write(d,sndbuf,7);
} else {
dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
- memcpy(&rbuf,&rcvbuf[3],rlen);
+ memcpy(rbuf,&rcvbuf[3],rlen);
}
return 0;
}
@@ -95,41 +94,20 @@ static int digitv_identify_state (struct usb_device *udev, struct
static int digitv_mt352_demod_init(struct dvb_frontend *fe)
{
- static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d };
- static u8 mt352_reset[] = { 0x50, 0x80 };
- static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
-
- static u8 mt352_agc_cfg[] = { 0x68, 0xa0 };
- static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 };
- static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
- static u8 mt352_agc_target[] = { 0x67, 0x20 };
-
- static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 };
- static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 };
-
- static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 };
+ static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 };
+ static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50,
+ 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00,
+ 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f,
+ 0x75, 0x32 };
+ int i;
- static u8 mt352_scan_ctl[] = { 0x88, 0x0f };
- static u8 mt352_capt_range[] = { 0x75, 0x32 };
+ for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
+ mt352_write(fe, &reset_buf[i], 2);
- mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
- mt352_write(fe, mt352_reset, sizeof(mt352_reset));
msleep(1);
- mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
-
- mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
- mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
- mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
- mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target));
-
-
- mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per));
- mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select));
- mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
-
- mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl));
- mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range));
+ for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
+ mt352_write(fe, &init_buf[i], 2);
return 0;
}
@@ -137,7 +115,7 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
static struct mt352_config digitv_mt352_config = {
.demod_address = 0x0, /* ignored by the digitv anyway */
.demod_init = digitv_mt352_demod_init,
- .pll_set = NULL, /* TODO */
+ .pll_set = dvb_usb_pll_set,
};
static struct nxt6000_config digitv_nxt6000_config = {
@@ -150,9 +128,9 @@ static struct nxt6000_config digitv_nxt6000_config = {
static int digitv_frontend_attach(struct dvb_usb_device *d)
{
- if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL)
+ if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
return 0;
- if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) {
+ if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
warn("nxt6000 support is not done yet, in fact you are one of the first "
"person who wants to use this device in Linux. Please report to "
@@ -163,6 +141,13 @@ static int digitv_frontend_attach(struct dvb_usb_device *d)
return -EIO;
}
+static int digitv_tuner_attach(struct dvb_usb_device *d)
+{
+ d->pll_addr = 0x60;
+ d->pll_desc = &dvb_pll_tded4;
+ return 0;
+}
+
static struct dvb_usb_rc_key digitv_rc_keys[] = {
{ 0x00, 0x16, KEY_POWER }, /* dummy key */
};
@@ -184,7 +169,6 @@ int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
-
/* DVB USB Driver stuff */
static struct dvb_usb_properties digitv_properties;
@@ -208,13 +192,8 @@ static struct dvb_usb_properties digitv_properties = {
.size_of_priv = 0,
- .streaming_ctrl = NULL,
- .pid_filter = NULL,
- .pid_filter_ctrl = NULL,
- .power_ctrl = NULL,
.frontend_attach = digitv_frontend_attach,
- .tuner_attach = NULL, // digitv_tuner_attach,
- .read_mac_address = NULL,
+ .tuner_attach = digitv_tuner_attach,
.rc_interval = 1000,
.rc_key_map = digitv_rc_keys,
@@ -238,7 +217,7 @@ static struct dvb_usb_properties digitv_properties = {
}
},
- .num_device_descs = 2,
+ .num_device_descs = 1,
.devices = {
{ "Nebula Electronics uDigiTV DVB-T USB2.0)",
{ &digitv_table[0], NULL },
@@ -249,7 +228,7 @@ static struct dvb_usb_properties digitv_properties = {
static struct usb_driver digitv_driver = {
.owner = THIS_MODULE,
- .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device",
+ .name = "dvb_usb_digitv",
.probe = digitv_probe,
.disconnect = dvb_usb_device_exit,
.id_table = digitv_table,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index d17d768038c..b032523b07b 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -1,5 +1,5 @@
-/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T
- * USB2.0 receiver.
+/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
*
* Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
*
@@ -14,61 +14,58 @@
struct dtt200u_fe_state {
struct dvb_usb_device *d;
+ fe_status_t stat;
+
struct dvb_frontend_parameters fep;
struct dvb_frontend frontend;
};
-#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
-
static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw = GET_TUNE_STAT;
- u8 br[3] = { 0 };
-// u8 bdeb[5] = { 0 };
+ u8 st = GET_TUNE_STATUS, b[3];
+
+ dvb_usb_generic_rw(state->d,&st,1,b,3,0);
- dvb_usb_generic_rw(state->d,&bw,1,br,3,0);
- switch (br[0]) {
+ switch (b[0]) {
case 0x01:
- *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
break;
- case 0x00:
- *stat = 0;
+ case 0x00: /* pending */
+ *stat = FE_TIMEDOUT; /* during set_frontend */
break;
default:
- moan("br[0]",GET_TUNE_STAT);
+ case 0x02: /* failed */
+ *stat = 0;
break;
}
-
-// bw[0] = 0x88;
-// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);
-
-// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
-
return 0;
}
+
static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw = GET_BER;
- *ber = 0;
- dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0);
+ u8 bw = GET_VIT_ERR_CNT,b[3];
+ dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
+ *ber = (b[0] << 16) | (b[1] << 8) | b[2];
return 0;
}
static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw = GET_UNK;
- *unc = 0;
- dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0);
+ u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
+
+ dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
+ *unc = (b[0] << 8) | b[1];
return 0;
}
static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw = GET_SIG_STRENGTH, b;
+ u8 bw = GET_AGC, b;
dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
*strength = (b << 8) | b;
return 0;
@@ -86,7 +83,7 @@ static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
static int dtt200u_fe_init(struct dvb_frontend* fe)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 b = RESET_DEMOD;
+ u8 b = SET_INIT;
return dvb_usb_generic_write(state->d,&b,1);
}
@@ -98,8 +95,8 @@ static int dtt200u_fe_sleep(struct dvb_frontend* fe)
static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1500;
- tune->step_size = 166667;
- tune->max_drift = 166667 * 2;
+ tune->step_size = 0;
+ tune->max_drift = 0;
return 0;
}
@@ -107,27 +104,32 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
+ int i;
+ fe_status_t st;
u16 freq = fep->frequency / 250000;
- u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 };
+ u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
switch (fep->u.ofdm.bandwidth) {
- case BANDWIDTH_8_MHZ: bw = 8; break;
- case BANDWIDTH_7_MHZ: bw = 7; break;
- case BANDWIDTH_6_MHZ: bw = 6; break;
+ case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
+ case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
+ case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
case BANDWIDTH_AUTO: return -EOPNOTSUPP;
default:
return -EINVAL;
}
- deb_info("set_frontend\n");
- bwbuf[1] = bw;
dvb_usb_generic_write(state->d,bwbuf,2);
freqbuf[1] = freq & 0xff;
freqbuf[2] = (freq >> 8) & 0xff;
dvb_usb_generic_write(state->d,freqbuf,3);
- memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
+ for (i = 0; i < 30; i++) {
+ msleep(20);
+ dtt200u_fe_read_status(fe, &st);
+ if (st & FE_TIMEDOUT)
+ continue;
+ }
return 0;
}
@@ -174,7 +176,7 @@ success:
static struct dvb_frontend_ops dtt200u_fe_ops = {
.info = {
- .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
+ .name = "WideView USB DVB-T",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index fb2b5a2da13..47dba6e4596 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -1,8 +1,10 @@
-/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T
- * USB2.0 receiver.
+/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
+ * Thanks to Steve Chang from WideView for providing support for the WT-220U.
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 2.
@@ -16,14 +18,24 @@ int dvb_usb_dtt200u_debug;
module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
+static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b = SET_INIT;
+
+ if (onoff)
+ dvb_usb_generic_write(d,&b,2);
+
+ return 0;
+}
+
static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
- u8 b_streaming[2] = { SET_TS_CTRL, onoff };
+ u8 b_streaming[2] = { SET_STREAMING, onoff };
u8 b_rst_pid = RESET_PID_FILTER;
dvb_usb_generic_write(d,b_streaming,2);
- if (!onoff)
+ if (onoff == 0)
dvb_usb_generic_write(d,&b_rst_pid,1);
return 0;
}
@@ -36,7 +48,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int
b_pid[0] = SET_PID_FILTER;
b_pid[1] = index;
b_pid[2] = pid & 0xff;
- b_pid[3] = (pid >> 8) & 0xff;
+ b_pid[3] = (pid >> 8) & 0x1f;
return dvb_usb_generic_write(d,b_pid,4);
}
@@ -54,9 +66,9 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
{ 0x80, 0x08, KEY_5 },
{ 0x80, 0x09, KEY_6 },
{ 0x80, 0x0a, KEY_7 },
- { 0x00, 0x0c, KEY_ZOOM },
+ { 0x80, 0x0c, KEY_ZOOM },
{ 0x80, 0x0d, KEY_0 },
- { 0x00, 0x0e, KEY_SELECT },
+ { 0x80, 0x0e, KEY_SELECT },
{ 0x80, 0x12, KEY_POWER },
{ 0x80, 0x1a, KEY_CHANNELUP },
{ 0x80, 0x1b, KEY_8 },
@@ -66,7 +78,7 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- u8 key[5],cmd = GET_RC_KEY;
+ u8 key[5],cmd = GET_RC_CODE;
dvb_usb_generic_rw(d,&cmd,1,key,5,0);
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
@@ -81,32 +93,41 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
}
static struct dvb_usb_properties dtt200u_properties;
+static struct dvb_usb_properties wt220u_properties;
static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE);
+ if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
+ dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
+ return 0;
+
+ return -ENODEV;
}
static struct usb_device_id dtt200u_usb_table [] = {
- { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) },
- { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) },
+// { USB_DEVICE(0x04b4,0x8613) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
static struct dvb_usb_properties dtt200u_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
- .pid_filter_count = 255, /* It is a guess, but there are at least 10 */
+ .pid_filter_count = 15,
.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-dtt200u-01.fw",
+ .power_ctrl = dtt200u_power_ctrl,
.streaming_ctrl = dtt200u_streaming_ctrl,
.pid_filter = dtt200u_pid_filter,
.frontend_attach = dtt200u_frontend_attach,
- .rc_interval = 200,
+ .rc_interval = 300,
.rc_key_map = dtt200u_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
.rc_query = dtt200u_rc_query,
@@ -127,18 +148,59 @@ static struct dvb_usb_properties dtt200u_properties = {
.num_device_descs = 1,
.devices = {
- { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)",
- .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] },
+ { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
+ .cold_ids = { &dtt200u_usb_table[0], NULL },
.warm_ids = { &dtt200u_usb_table[1], NULL },
},
{ 0 },
}
};
+static struct dvb_usb_properties wt220u_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 15,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-wt220u-01.fw",
+
+ .power_ctrl = dtt200u_power_ctrl,
+ .streaming_ctrl = dtt200u_streaming_ctrl,
+ .pid_filter = dtt200u_pid_filter,
+ .frontend_attach = dtt200u_frontend_attach,
+
+ .rc_interval = 300,
+ .rc_key_map = dtt200u_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+ .rc_query = dtt200u_rc_query,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "WideView WT-220U PenType Receiver (and clones)",
+ .cold_ids = { &dtt200u_usb_table[2], NULL },
+ .warm_ids = { &dtt200u_usb_table[3], NULL },
+ },
+ { 0 },
+ }
+};
+
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = {
.owner = THIS_MODULE,
- .name = "Yakumo/Hama/Typhoon DVB-T USB2.0",
+ .name = "dvb_usb_dtt200u",
.probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit,
.id_table = dtt200u_usb_table,
@@ -166,6 +228,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit);
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device");
+MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
index ed414207151..6f1f3042e21 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.h
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -1,5 +1,5 @@
-/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T
- * USB2.0 receiver.
+/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
@@ -22,44 +22,34 @@ extern int dvb_usb_dtt200u_debug;
/* guessed protocol description (reverse engineered):
* read
* 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
- * 81 - <TS_LOCK> <current frequency divided by 250000>
- * 82 - crash - do not touch
- * 83 - crash - do not touch
- * 84 - remote control
- * 85 - crash - do not touch (OK, stop testing here)
* 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
- * 89 - noise-to-signal
- * 8a - unkown 1 byte - signal_strength
- * 8c - ber ???
- * 8d - ber
- * 8e - unc
*/
-#define GET_SPEED 0x00
-#define GET_TUNE_STAT 0x81
-#define GET_RC_KEY 0x84
-#define GET_STATUS 0x88
-#define GET_SNR 0x89
-#define GET_SIG_STRENGTH 0x8a
-#define GET_UNK 0x8c
-#define GET_BER 0x8d
-#define GET_UNC 0x8e
+#define GET_SPEED 0x00
+#define GET_TUNE_STATUS 0x81
+#define GET_RC_CODE 0x84
+#define GET_CONFIGURATION 0x88
+#define GET_AGC 0x89
+#define GET_SNR 0x8a
+#define GET_VIT_ERR_CNT 0x8c
+#define GET_RS_ERR_CNT 0x8d
+#define GET_RS_UNCOR_BLK_CNT 0x8e
/* write
- * 01 - reset the demod
+ * 01 - init
* 02 - frequency (divided by 250000)
* 03 - bandwidth
* 04 - pid table (index pid(7:0) pid(12:8))
* 05 - reset the pid table
- * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
+ * 08 - transfer switch
*/
-#define RESET_DEMOD 0x01
-#define SET_FREQUENCY 0x02
+#define SET_INIT 0x01
+#define SET_RF_FREQ 0x02
#define SET_BANDWIDTH 0x03
#define SET_PID_FILTER 0x04
#define RESET_PID_FILTER 0x05
-#define SET_TS_CTRL 0x08
+#define SET_STREAMING 0x08
extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index 67e0d73fbce..7300489d3e2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -12,14 +12,16 @@
#include "dvb-usb.h"
extern int dvb_usb_debug;
+extern int dvb_usb_disable_rc_polling;
#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
-#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
+#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
+#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args)
/* commonly used methods */
extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index bdd72f77970..3491ff40885 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -175,7 +175,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
int dvb_usb_fe_init(struct dvb_usb_device* d)
{
if (d->props.frontend_attach == NULL) {
- err("strange '%s' don't want to attach a frontend.",d->desc->name);
+ err("strange '%s' doesn't want to attach a frontend.",d->desc->name);
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index bcb34191868..794d513a848 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -12,7 +12,7 @@
/* Vendor IDs */
#define USB_VID_ADSTECH 0x06e1
#define USB_VID_ANCHOR 0x0547
-#define USB_VID_AVERMEDIA_UNK 0x14aa
+#define USB_VID_WIDEVIEW 0x14aa
#define USB_VID_AVERMEDIA 0x07ca
#define USB_VID_COMPRO 0x185b
#define USB_VID_COMPRO_UNK 0x145f
@@ -24,6 +24,8 @@
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_KYE 0x0458
+#define USB_VID_MEDION 0x1660
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -70,6 +72,8 @@
#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
#define USB_PID_DTT200U_COLD 0x0201
#define USB_PID_DTT200U_WARM 0x0301
+#define USB_PID_WT220U_COLD 0x0222
+#define USB_PID_WT220U_WARM 0x0221
#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
#define USB_PID_NEBULA_DIGITV 0x0201
@@ -78,6 +82,8 @@
#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01
#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11
-
+#define USB_PID_MEDION_MD95700 0x0932
+#define USB_PID_KYE_DVB_T_COLD 0x701e
+#define USB_PID_KYE_DVB_T_WARM 0x701f
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 3aadec974cf..65f0c095abc 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -18,6 +18,10 @@ int dvb_usb_debug;
module_param_named(debug,dvb_usb_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
+int dvb_usb_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
+
/* general initialization functions */
int dvb_usb_exit(struct dvb_usb_device *d)
{
@@ -47,17 +51,17 @@ static int dvb_usb_init(struct dvb_usb_device *d)
/* speed - when running at FULL speed we need a HW PID filter */
if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
- err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)");
+ err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
return -ENODEV;
}
if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
(d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
- info("will use the device's hw PID filter.");
+ info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count);
d->pid_filtering = 1;
d->max_feed_count = d->props.pid_filter_count;
} else {
- info("will pass the complete MPEG2 transport stream to the demuxer.");
+ info("will pass the complete MPEG2 transport stream to the software demuxer.");
d->pid_filtering = 0;
d->max_feed_count = 255;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 9f1e23f82ba..fc7800f1743 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -21,6 +21,10 @@ static void dvb_usb_read_remote_control(void *data)
/* TODO: need a lock here. We can simply skip checking for the remote control
if we're busy. */
+ /* when the parameter has been set to 1 via sysfs while the driver was running */
+ if (dvb_usb_disable_rc_polling)
+ return;
+
if (d->props.rc_query(d,&event,&state)) {
err("error while querying for an remote control event.");
goto schedule;
@@ -35,7 +39,7 @@ static void dvb_usb_read_remote_control(void *data)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(&d->rc_input_dev, EV_KEY, event, 1);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
input_sync(&d->rc_input_dev);
break;
@@ -85,7 +89,9 @@ schedule:
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i;
- if (d->props.rc_key_map == NULL)
+ if (d->props.rc_key_map == NULL ||
+ d->props.rc_query == NULL ||
+ dvb_usb_disable_rc_polling)
return 0;
/* Initialise the remote-control structures.*/
@@ -154,12 +160,12 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
break;
}
/* See if we can match the raw key code. */
- for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++)
+ for (i = 0; i < d->props.rc_key_map_size; i++)
if (keymap[i].custom == keybuf[1] &&
keymap[i].data == keybuf[3]) {
*event = keymap[i].event;
*state = REMOTE_KEY_PRESSED;
- break;
+ return 0;
}
deb_err("key mapping failed - no appropriate key found in keymapping\n");
break;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index 83d476fb410..f5799a4c228 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -24,11 +24,12 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
if ((ret = down_interruptible(&d->usb_sem)))
return ret;
+ deb_xfer(">>> ");
debug_dump(wbuf,wlen,deb_xfer);
ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
- 2*HZ);
+ 2000);
if (ret)
err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
@@ -42,12 +43,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
- 2*HZ);
+ 2000);
if (ret)
err("recv bulk message failed: %d",ret);
- else
+ else {
+ deb_xfer("<<< ");
debug_dump(rbuf,actlen,deb_xfer);
+ }
}
up(&d->usb_sem);
@@ -61,12 +64,19 @@ int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
}
EXPORT_SYMBOL(dvb_usb_generic_write);
-static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+
+/* URB stuff for streaming */
+static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
{
struct dvb_usb_device *d = urb->context;
+ int ptype = usb_pipetype(urb->pipe);
+ int i;
+ u8 *b;
- deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status,
- urb->actual_length);
+ deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+ ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
+ urb->status,urb->actual_length,urb->transfer_buffer_length,
+ urb->number_of_packets,urb->error_count);
switch (urb->status) {
case 0: /* success */
@@ -81,11 +91,33 @@ static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
break;
}
- if (d->feedcount > 0 && urb->actual_length > 0) {
- if (d->state & DVB_USB_STATE_DVB)
- dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length);
- } else
- deb_ts("URB dropped because of feedcount.\n");
+ if (d->feedcount > 0) {
+ if (d->state & DVB_USB_STATE_DVB) {
+ switch (ptype) {
+ case PIPE_ISOCHRONOUS:
+ b = (u8 *) urb->transfer_buffer;
+ for (i = 0; i < urb->number_of_packets; i++) {
+ if (urb->iso_frame_desc[i].status != 0)
+ deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+ else if (urb->iso_frame_desc[i].actual_length > 0) {
+ dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
+ urb->iso_frame_desc[i].actual_length);
+ }
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ debug_dump(b,20,deb_ts);
+ break;
+ case PIPE_BULK:
+ if (urb->actual_length > 0)
+ dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
+ break;
+ default:
+ err("unkown endpoint type in completition handler.");
+ return;
+ }
+ }
+ }
usb_submit_urb(urb,GFP_ATOMIC);
}
@@ -94,7 +126,7 @@ int dvb_usb_urb_kill(struct dvb_usb_device *d)
{
int i;
for (i = 0; i < d->urbs_submitted; i++) {
- deb_info("killing URB no. %d.\n",i);
+ deb_ts("killing URB no. %d.\n",i);
/* stop the URB */
usb_kill_urb(d->urb_list[i]);
@@ -107,9 +139,9 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d)
{
int i,ret;
for (i = 0; i < d->urbs_initialized; i++) {
- deb_info("submitting URB no. %d\n",i);
+ deb_ts("submitting URB no. %d\n",i);
if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
- err("could not submit URB no. %d - get them all back\n",i);
+ err("could not submit URB no. %d - get them all back",i);
dvb_usb_urb_kill(d);
return ret;
}
@@ -118,32 +150,78 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d)
return 0;
}
-static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
{
- int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize;
+ if (d->state & DVB_USB_STATE_URB_BUF) {
+ while (d->buf_num) {
+ d->buf_num--;
+ deb_mem("freeing buffer %d\n",d->buf_num);
+ usb_buffer_free(d->udev, d->buf_size,
+ d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
+ }
+ kfree(d->buf_list);
+ kfree(d->dma_addr);
+ }
+
+ d->state &= ~DVB_USB_STATE_URB_BUF;
- deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
- /* allocate the actual buffer for the URBs */
- if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) {
- deb_info("not enough memory for urb-buffer allocation.\n");
+ return 0;
+}
+
+static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
+{
+ d->buf_num = 0;
+ d->buf_size = size;
+
+ deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
+
+ if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
+ return -ENOMEM;
+
+ if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
+ kfree(d->buf_list);
return -ENOMEM;
}
- deb_info("allocation successful\n");
- memset(d->buffer,0,bufsize);
+ memset(d->buf_list,0,num*sizeof(u8 *));
+ memset(d->dma_addr,0,num*sizeof(dma_addr_t));
d->state |= DVB_USB_STATE_URB_BUF;
+ for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
+ deb_mem("allocating buffer %d\n",d->buf_num);
+ if (( d->buf_list[d->buf_num] =
+ usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
+ &d->dma_addr[d->buf_num]) ) == NULL) {
+ deb_mem("not enough memory for urb-buffer allocation.\n");
+ dvb_usb_free_stream_buffers(d);
+ return -ENOMEM;
+ }
+ deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
+ memset(d->buf_list[d->buf_num],0,size);
+ }
+ deb_mem("allocation successful\n");
+
+ return 0;
+}
+
+static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+{
+ int i;
+
+ if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+ d->props.urb.u.bulk.buffersize)) < 0)
+ return i;
+
/* allocate the URBs */
for (i = 0; i < d->props.urb.count; i++) {
- if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
+ if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
return -ENOMEM;
- }
usb_fill_bulk_urb( d->urb_list[i], d->udev,
usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
- &d->buffer[i*d->props.urb.u.bulk.buffersize],
+ d->buf_list[i],
d->props.urb.u.bulk.buffersize,
- dvb_usb_bulk_urb_complete, d);
+ dvb_usb_urb_complete, d);
d->urb_list[i]->transfer_flags = 0;
d->urbs_initialized++;
@@ -151,6 +229,47 @@ static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
return 0;
}
+static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
+{
+ int i,j;
+
+ if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+ d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
+ return i;
+
+ /* allocate the URBs */
+ for (i = 0; i < d->props.urb.count; i++) {
+ struct urb *urb;
+ int frame_offset = 0;
+ if ((d->urb_list[i] =
+ usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
+ return -ENOMEM;
+
+ urb = d->urb_list[i];
+
+ urb->dev = d->udev;
+ urb->context = d;
+ urb->complete = dvb_usb_urb_complete;
+ urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = d->props.urb.u.isoc.interval;
+ urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
+ urb->transfer_buffer_length = d->buf_size;
+ urb->transfer_buffer = d->buf_list[i];
+ urb->transfer_dma = d->dma_addr[i];
+
+ for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
+ urb->iso_frame_desc[j].offset = frame_offset;
+ urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
+ frame_offset += d->props.urb.u.isoc.framesize;
+ }
+
+ d->urbs_initialized++;
+ }
+ return 0;
+
+}
+
int dvb_usb_urb_init(struct dvb_usb_device *d)
{
/*
@@ -174,8 +293,7 @@ int dvb_usb_urb_init(struct dvb_usb_device *d)
case DVB_USB_BULK:
return dvb_usb_bulk_urb_init(d);
case DVB_USB_ISOC:
- err("isochronous transfer not yet implemented in dvb-usb.");
- return -EINVAL;
+ return dvb_usb_isoc_urb_init(d);
default:
err("unkown URB-type for data transfer.");
return -EINVAL;
@@ -191,7 +309,7 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d)
if (d->state & DVB_USB_STATE_URB_LIST) {
for (i = 0; i < d->urbs_initialized; i++) {
if (d->urb_list[i] != NULL) {
- deb_info("freeing URB no. %d.\n",i);
+ deb_mem("freeing URB no. %d.\n",i);
/* free the URBs */
usb_free_urb(d->urb_list[i]);
}
@@ -202,10 +320,6 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d)
d->state &= ~DVB_USB_STATE_URB_LIST;
}
- if (d->state & DVB_USB_STATE_URB_BUF)
- usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count,
- d->buffer, d->dma_handle);
-
- d->state &= ~DVB_USB_STATE_URB_BUF;
+ dvb_usb_free_stream_buffers(d);
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index abcee1943f6..a80567caf50 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -189,12 +189,13 @@ struct dvb_usb_properties {
struct {
int framesperurb;
int framesize;
+ int interval;
} isoc;
} u;
} urb;
int num_device_descs;
- struct dvb_usb_device_description devices[8];
+ struct dvb_usb_device_description devices[9];
};
@@ -207,19 +208,28 @@ struct dvb_usb_properties {
* @udev: pointer to the device's struct usb_device.
* @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
* streaming.
- * @buffer: buffer used to streaming.
- * @dma_handle: dma_addr_t for buffer.
+ *
+ * @buf_num: number of buffer allocated.
+ * @buf_size: size of each buffer in buf_list.
+ * @buf_list: array containing all allocate buffers for streaming.
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list.
+ *
* @urbs_initialized: number of URBs initialized.
* @urbs_submitted: number of URBs submitted.
+ *
* @feedcount: number of reqested feeds (used for streaming-activation)
* @pid_filtering: is hardware pid_filtering used or not.
+ *
* @usb_sem: semaphore of USB control messages (reading needs two messages)
* @i2c_sem: semaphore for i2c-transfers
+ *
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
* @pll_addr: I2C address of the tuner for programming
* @pll_init: array containing the initialization buffer
* @pll_desc: pointer to the appropriate struct dvb_pll_desc
- * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod
+ *
+ * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
+ *
* @dvb_adap: device's dvb_adapter.
* @dmxdev: device's dmxdev.
* @demux: device's software demuxer.
@@ -253,8 +263,12 @@ struct dvb_usb_device {
/* usb */
struct usb_device *udev;
struct urb **urb_list;
- u8 *buffer;
- dma_addr_t dma_handle;
+
+ int buf_num;
+ unsigned long buf_size;
+ u8 **buf_list;
+ dma_addr_t *dma_addr;
+
int urbs_initialized;
int urbs_submitted;
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 9d83781aef9..258a92bfbcc 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -203,7 +203,7 @@ static struct dvb_usb_properties nova_t_properties = {
static struct usb_driver nova_t_driver = {
.owner = THIS_MODULE,
- .name = "Hauppauge WinTV-NOVA-T usb2",
+ .name = "dvb_usb_nova_t_usb2",
.probe = nova_t_probe,
.disconnect = dvb_usb_device_exit,
.id_table = nova_t_table,
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index aa560422ce7..2112ac3cf5e 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -129,7 +129,7 @@ static struct dvb_usb_properties umt_properties = {
static struct usb_driver umt_driver = {
.owner = THIS_MODULE,
- .name = "HanfTek UMT-010 USB2.0 DVB-T devices",
+ .name = "dvb_usb_umt_010",
.probe = umt_probe,
.disconnect = dvb_usb_device_exit,
.id_table = umt_table,
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 02ecc9a8e3b..9ac95f54f9f 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -44,7 +44,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
if (usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev,0),
TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
- outbuf, 20, 2*HZ) != 20) {
+ outbuf, 20, 2000) != 20) {
err("USB control message 'out' went wrong.");
ret = -EIO;
goto unlock;
@@ -55,7 +55,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
if (usb_control_msg(d->udev,
usb_rcvctrlpipe(d->udev,0),
TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
- inbuf, 12, 2*HZ) != 12) {
+ inbuf, 12, 2000) != 12) {
err("USB control message 'in' went wrong.");
ret = -EIO;
goto unlock;
@@ -94,16 +94,41 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded. */
static struct dvb_usb_rc_key vp7045_rc_keys[] = {
- /* insert the keys like this. to make the raw keys visible, enable
- * debug=0x04 when loading dvb-usb-vp7045. */
-
- /* these keys are probably wrong. I don't have a working IR-receiver on my
- * vp7045, so I can't test it. Patches are welcome. */
- { 0x00, 0x01, KEY_1 },
- { 0x00, 0x02, KEY_2 },
+ { 0x00, 0x16, KEY_POWER },
+ { 0x00, 0x10, KEY_MUTE },
+ { 0x00, 0x03, KEY_1 },
+ { 0x00, 0x01, KEY_2 },
+ { 0x00, 0x06, KEY_3 },
+ { 0x00, 0x09, KEY_4 },
+ { 0x00, 0x1d, KEY_5 },
+ { 0x00, 0x1f, KEY_6 },
+ { 0x00, 0x0d, KEY_7 },
+ { 0x00, 0x19, KEY_8 },
+ { 0x00, 0x1b, KEY_9 },
+ { 0x00, 0x15, KEY_0 },
+ { 0x00, 0x05, KEY_CHANNELUP },
+ { 0x00, 0x02, KEY_CHANNELDOWN },
+ { 0x00, 0x1e, KEY_VOLUMEUP },
+ { 0x00, 0x0a, KEY_VOLUMEDOWN },
+ { 0x00, 0x11, KEY_RECORD },
+ { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+ { 0x00, 0x14, KEY_PLAY },
+ { 0x00, 0x1a, KEY_STOP },
+ { 0x00, 0x40, KEY_REWIND },
+ { 0x00, 0x12, KEY_FASTFORWARD },
+ { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+ { 0x00, 0x4c, KEY_PAUSE },
+ { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
+ { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+ { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
+ { 0x00, 0x1c, KEY_EPG }, /* EPG */
+ { 0x00, 0x00, KEY_TAB }, /* Tab */
+ { 0x00, 0x48, KEY_INFO }, /* Preview */
+ { 0x00, 0x04, KEY_LIST }, /* RecordList */
+ { 0x00, 0x0f, KEY_TEXT } /* Teletext */
};
-static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
+static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
u8 key;
int i;
@@ -119,7 +144,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
if (vp7045_rc_keys[i].data == key) {
*state = REMOTE_KEY_PRESSED;
- *key_buf = vp7045_rc_keys[i].event;
+ *event = vp7045_rc_keys[i].event;
break;
}
return 0;
@@ -230,7 +255,7 @@ static struct dvb_usb_properties vp7045_properties = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver vp7045_usb_driver = {
.owner = THIS_MODULE,
- .name = "dvb-usb-vp7045",
+ .name = "dvb_usb_vp7045",
.probe = vp7045_usb_probe,
.disconnect = dvb_usb_device_exit,
.id_table = vp7045_usb_table,
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b4fddf513eb..d847c62bd83 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -40,6 +40,12 @@ config DVB_VES1X93
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_S5H1420
+ tristate "Samsung S5H1420 based"
+ depends on DVB_CORE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
comment "DVB-T (terrestrial) frontends"
depends on DVB_CORE
@@ -181,4 +187,11 @@ config DVB_BCM3510
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
support this frontend.
+config DVB_LGDT3302
+ tristate "LGDT3302 based (DViCO FusionHDTV3 Gold)"
+ depends on DVB_CORE
+ help
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
+
endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 91d6d3576d3..de5e240cba7 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -29,3 +29,5 @@ obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
obj-$(CONFIG_DVB_OR51132) += or51132.o
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
+obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
+obj-$(CONFIG_DVB_LGDT3302) += lgdt3302.o
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index f4aa44136c7..9f639297a9f 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -76,7 +76,6 @@ static u8 init_tab [] = {
0x49, 0x56,
0x6b, 0x1e,
0xc8, 0x02,
- 0xf8, 0x02,
0xf9, 0x00,
0xfa, 0x00,
0xfb, 0x00,
@@ -203,7 +202,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
struct cx22702_state* state = fe->demodulator_priv;
/* set PLL */
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+ cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
if (state->config->pll_set) {
state->config->pll_set(fe, p);
} else if (state->config->pll_desc) {
@@ -217,7 +216,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
} else {
BUG();
}
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
+ cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
/* set inversion */
cx22702_set_inversion (state, p->inversion);
@@ -256,7 +255,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
- printk("%s: Autodetecting\n",__FUNCTION__);
+ dprintk("%s: Autodetecting\n",__FUNCTION__);
return 0;
}
@@ -347,10 +346,11 @@ static int cx22702_init (struct dvb_frontend* fe)
for (i=0; i<sizeof(init_tab); i+=2)
cx22702_writereg (state, init_tab[i], init_tab[i+1]);
+ cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
/* init PLL */
if (state->config->pll_init) {
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+ cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
state->config->pll_init(fe);
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
}
@@ -440,8 +440,10 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
/* RS Uncorrectable Packet Count then reset */
_ucblocks = cx22702_readreg (state, 0xE3);
- if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks);
- else *ucblocks = state->prevUCBlocks - _ucblocks;
+ if (state->prevUCBlocks < _ucblocks)
+ *ucblocks = (_ucblocks - state->prevUCBlocks);
+ else
+ *ucblocks = state->prevUCBlocks - _ucblocks;
state->prevUCBlocks = _ucblocks;
return 0;
@@ -457,6 +459,12 @@ static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
return cx22702_get_tps (state, &p->u.ofdm);
}
+static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 1000;
+ return 0;
+}
+
static void cx22702_release(struct dvb_frontend* fe)
{
struct cx22702_state* state = fe->demodulator_priv;
@@ -472,7 +480,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (state == NULL)
+ goto error;
/* setup the state */
state->config = config;
@@ -481,7 +490,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
state->prevUCBlocks = 0;
/* check if the demod is there */
- if (cx22702_readreg(state, 0x1f) != 0x3) goto error;
+ if (cx22702_readreg(state, 0x1f) != 0x3)
+ goto error;
/* create dvb_frontend */
state->frontend.ops = &state->ops;
@@ -514,6 +524,7 @@ static struct dvb_frontend_ops cx22702_ops = {
.set_frontend = cx22702_set_tps,
.get_frontend = cx22702_get_frontend,
+ .get_tune_settings = cx22702_get_tune_settings,
.read_status = cx22702_read_status,
.read_ber = cx22702_read_ber,
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 559fdb90666..11f86806756 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -35,6 +35,11 @@ struct cx22702_config
/* the demodulator's i2c address */
u8 demod_address;
+ /* serial/parallel output */
+#define CX22702_PARALLEL_OUTPUT 0
+#define CX22702_SERIAL_OUTPUT 1
+ u8 output_mode;
+
/* PLL maintenance */
u8 pll_address;
struct dvb_pll_desc *pll_desc;
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index f73b5f48e23..5afeaa9b43b 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -55,7 +55,7 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
-static void thomson_dtt759x_bw(u8 *buf, int bandwidth)
+static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth)
{
if (BANDWIDTH_7_MHZ == bandwidth)
buf[3] |= 0x10;
@@ -93,6 +93,32 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
};
EXPORT_SYMBOL(dvb_pll_lg_z201);
+struct dvb_pll_desc dvb_pll_microtune_4042 = {
+ .name = "Microtune 4042 FI5",
+ .min = 57000000,
+ .max = 858000000,
+ .count = 3,
+ .entries = {
+ { 162000000, 44000000, 62500, 0x8e, 0xa1 },
+ { 457000000, 44000000, 62500, 0x8e, 0x91 },
+ { 999999999, 44000000, 62500, 0x8e, 0x31 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_microtune_4042);
+
+struct dvb_pll_desc dvb_pll_thomson_dtt7611 = {
+ .name = "Thomson dtt7611",
+ .min = 44000000,
+ .max = 958000000,
+ .count = 3,
+ .entries = {
+ { 157250000, 44000000, 62500, 0x8e, 0x39 },
+ { 454000000, 44000000, 62500, 0x8e, 0x3a },
+ { 999999999, 44000000, 62500, 0x8e, 0x3c },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_thomson_dtt7611);
+
struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174000000,
@@ -146,7 +172,7 @@ EXPORT_SYMBOL(dvb_pll_env57h1xd5);
/* Philips TDA6650/TDA6651
* used in Panasonic ENV77H11D5
*/
-static void tda665x_bw(u8 *buf, int bandwidth)
+static void tda665x_bw(u8 *buf, u32 freq, int bandwidth)
{
if (bandwidth == BANDWIDTH_8_MHZ)
buf[3] |= 0x08;
@@ -178,7 +204,7 @@ EXPORT_SYMBOL(dvb_pll_tda665x);
/* Infineon TUA6034
* used in LG TDTP E102P
*/
-static void tua6034_bw(u8 *buf, int bandwidth)
+static void tua6034_bw(u8 *buf, u32 freq, int bandwidth)
{
if (BANDWIDTH_7_MHZ != bandwidth)
buf[3] |= 0x08;
@@ -198,6 +224,57 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
};
EXPORT_SYMBOL(dvb_pll_tua6034);
+/* Philips FMD1216ME
+ * used in Medion Hybrid PCMCIA card and USB Box
+ */
+static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth)
+{
+ if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000)
+ buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_fmd1216me = {
+ .name = "Philips FMD1216ME",
+ .min = 50870000,
+ .max = 858000000,
+ .setbw = fmd1216me_bw,
+ .count = 7,
+ .entries = {
+ { 143870000, 36213333, 166667, 0xbc, 0x41 },
+ { 158870000, 36213333, 166667, 0xf4, 0x41 },
+ { 329870000, 36213333, 166667, 0xbc, 0x42 },
+ { 441870000, 36213333, 166667, 0xf4, 0x42 },
+ { 625870000, 36213333, 166667, 0xbc, 0x44 },
+ { 803870000, 36213333, 166667, 0xf4, 0x44 },
+ { 999999999, 36213333, 166667, 0xfc, 0x44 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_fmd1216me);
+
+/* ALPS TDED4
+ * used in Nebula-Cards and USB boxes
+ */
+static void tded4_bw(u8 *buf, u32 freq, int bandwidth)
+{
+ if (bandwidth == BANDWIDTH_8_MHZ)
+ buf[3] |= 0x04;
+}
+
+struct dvb_pll_desc dvb_pll_tded4 = {
+ .name = "ALPS TDED4",
+ .min = 47000000,
+ .max = 863000000,
+ .setbw = tded4_bw,
+ .count = 4,
+ .entries = {
+ { 153000000, 36166667, 166667, 0x85, 0x01 },
+ { 470000000, 36166667, 166667, 0x85, 0x02 },
+ { 823000000, 36166667, 166667, 0x85, 0x08 },
+ { 999999999, 36166667, 166667, 0x85, 0x88 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_tded4);
+
/* ----------------------------------------------------------- */
/* code */
@@ -231,7 +308,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
buf[3] = desc->entries[i].cb2;
if (desc->setbw)
- desc->setbw(buf, bandwidth);
+ desc->setbw(buf, freq, bandwidth);
if (debug)
printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index b796778624b..cb794759d89 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -9,7 +9,7 @@ struct dvb_pll_desc {
char *name;
u32 min;
u32 max;
- void (*setbw)(u8 *buf, int bandwidth);
+ void (*setbw)(u8 *buf, u32 freq, int bandwidth);
int count;
struct {
u32 limit;
@@ -24,12 +24,16 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
extern struct dvb_pll_desc dvb_pll_lg_z201;
+extern struct dvb_pll_desc dvb_pll_microtune_4042;
+extern struct dvb_pll_desc dvb_pll_thomson_dtt7611;
extern struct dvb_pll_desc dvb_pll_unknown_1;
extern struct dvb_pll_desc dvb_pll_tua6010xs;
extern struct dvb_pll_desc dvb_pll_env57h1xd5;
extern struct dvb_pll_desc dvb_pll_tua6034;
extern struct dvb_pll_desc dvb_pll_tda665x;
+extern struct dvb_pll_desc dvb_pll_fmd1216me;
+extern struct dvb_pll_desc dvb_pll_tded4;
int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 031a1ddc7d1..faaad1ae855 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -474,11 +474,12 @@ static int l64781_init(struct dvb_frontend* fe)
return 0;
}
-static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+static int l64781_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings)
{
- fesettings->min_delay_ms = 200;
- fesettings->step_size = 166667;
- fesettings->max_drift = 166667*2;
+ fesettings->min_delay_ms = 4000;
+ fesettings->step_size = 0;
+ fesettings->max_drift = 0;
return 0;
}
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
new file mode 100644
index 00000000000..2eea03d218c
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.c
@@ -0,0 +1,609 @@
+/*
+ * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
+ *
+ * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
+ * Copyright (C) 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * NOTES ABOUT THIS DRIVER
+ *
+ * This driver supports DViCO FusionHDTV 3 Gold under Linux.
+ *
+ * TODO:
+ * BER and signal strength always return 0.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+
+#include "dvb_frontend.h"
+#include "dvb-pll.h"
+#include "lgdt3302_priv.h"
+#include "lgdt3302.h"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
+#define dprintk(args...) \
+do { \
+if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
+} while (0)
+
+struct lgdt3302_state
+{
+ struct i2c_adapter* i2c;
+ struct dvb_frontend_ops ops;
+
+ /* Configuration settings */
+ const struct lgdt3302_config* config;
+
+ struct dvb_frontend frontend;
+
+ /* Demodulator private data */
+ fe_modulation_t current_modulation;
+
+ /* Tuner private data */
+ u32 current_frequency;
+};
+
+static int i2c_writebytes (struct lgdt3302_state* state,
+ u8 addr, /* demod_address or pll_address */
+ u8 *buf, /* data bytes to send */
+ int len /* number of bytes to send */ )
+{
+ if (addr == state->config->pll_address) {
+ struct i2c_msg msg =
+ { .addr = addr, .flags = 0, .buf = buf, .len = len };
+ int err;
+
+ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+ } else {
+ u8 tmp[] = { buf[0], buf[1] };
+ struct i2c_msg msg =
+ { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
+ int err;
+ int i;
+
+ for (i=1; i<len; i++) {
+ tmp[1] = buf[i];
+ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+ tmp[0]++;
+ }
+ }
+ return 0;
+}
+static int i2c_readbytes (struct lgdt3302_state* state,
+ u8 addr, /* demod_address or pll_address */
+ u8 *buf, /* holds data bytes read */
+ int len /* number of bytes to read */ )
+{
+ struct i2c_msg msg =
+ { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
+ int err;
+
+ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+/*
+ * This routine writes the register (reg) to the demod bus
+ * then reads the data returned for (len) bytes.
+ */
+
+static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
+ enum I2C_REG reg, u8* buf, int len)
+{
+ u8 wr [] = { reg };
+ struct i2c_msg msg [] = {
+ { .addr = state->config->demod_address,
+ .flags = 0, .buf = wr, .len = 1 },
+ { .addr = state->config->demod_address,
+ .flags = I2C_M_RD, .buf = buf, .len = len },
+ };
+ int ret;
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2) {
+ printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
+ } else {
+ ret = 0;
+ }
+ return ret;
+}
+
+/* Software reset */
+int lgdt3302_SwReset(struct lgdt3302_state* state)
+{
+ u8 ret;
+ u8 reset[] = {
+ IRQ_MASK,
+ 0x00 /* bit 6 is active low software reset
+ * bits 5-0 are 1 to mask interrupts */
+ };
+
+ ret = i2c_writebytes(state,
+ state->config->demod_address,
+ reset, sizeof(reset));
+ if (ret == 0) {
+ /* spec says reset takes 100 ns why wait */
+ /* mdelay(100); */ /* keep low for 100mS */
+ reset[1] = 0x7f; /* force reset high (inactive)
+ * and unmask interrupts */
+ ret = i2c_writebytes(state,
+ state->config->demod_address,
+ reset, sizeof(reset));
+ }
+ /* Spec does not indicate a need for this either */
+ /*mdelay(5); */ /* wait 5 msec before doing more */
+ return ret;
+}
+
+static int lgdt3302_init(struct dvb_frontend* fe)
+{
+ /* Hardware reset is done using gpio[0] of cx23880x chip.
+ * I'd like to do it here, but don't know how to find chip address.
+ * cx88-cards.c arranges for the reset bit to be inactive (high).
+ * Maybe there needs to be a callable function in cx88-core or
+ * the caller of this function needs to do it. */
+
+ dprintk("%s entered\n", __FUNCTION__);
+ return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
+}
+
+static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ *ber = 0; /* Dummy out for now */
+ return 0;
+}
+
+static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
+ u8 buf[2];
+
+ i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
+
+ *ucblocks = (buf[0] << 8) | buf[1];
+ return 0;
+}
+
+static int lgdt3302_set_parameters(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *param)
+{
+ u8 buf[4];
+ struct lgdt3302_state* state =
+ (struct lgdt3302_state*) fe->demodulator_priv;
+
+ /* Use 50MHz parameter values from spec sheet since xtal is 50 */
+ static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
+ static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
+ static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
+ static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
+ static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
+ static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };
+ static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
+
+ /* Change only if we are actually changing the modulation */
+ if (state->current_modulation != param->u.vsb.modulation) {
+ int value;
+
+ switch(param->u.vsb.modulation) {
+ case VSB_8:
+ dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
+
+ /* Select VSB mode and serial MPEG interface */
+ top_ctrl_cfg[1] = 0x07;
+ break;
+
+ case QAM_64:
+ dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
+
+ /* Select QAM_64 mode and serial MPEG interface */
+ top_ctrl_cfg[1] = 0x04;
+ break;
+
+ case QAM_256:
+ dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
+
+ /* Select QAM_256 mode and serial MPEG interface */
+ top_ctrl_cfg[1] = 0x05;
+ break;
+ default:
+ printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
+ return -1;
+ }
+ /* Initializations common to all modes */
+
+ /* Select the requested mode */
+ i2c_writebytes(state, state->config->demod_address,
+ top_ctrl_cfg, sizeof(top_ctrl_cfg));
+
+ /* Change the value of IFBW[11:0]
+ of AGC IF/RF loop filter bandwidth register */
+ i2c_writebytes(state, state->config->demod_address,
+ agc_rf_cfg, sizeof(agc_rf_cfg));
+
+ /* Change the value of bit 6, 'nINAGCBY' and
+ 'NSSEL[1:0] of ACG function control register 2 */
+ /* Change the value of bit 6 'RFFIX'
+ of AGC function control register 3 */
+ i2c_writebytes(state, state->config->demod_address,
+ agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
+
+ /* Change the TPCLK pin polarity
+ data is valid on falling clock */
+ i2c_writebytes(state, state->config->demod_address,
+ demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
+
+ /* Change the value of NCOCTFV[25:0] of carrier
+ recovery center frequency register */
+ i2c_writebytes(state, state->config->demod_address,
+ vsb_freq_cfg, sizeof(vsb_freq_cfg));
+ /* Set the value of 'INLVTHD' register 0x2a/0x2c
+ to value from 'IFACC' register 0x39/0x3b -1 */
+ i2c_selectreadbytes(state, AGC_RFIF_ACC0,
+ &agc_delay_cfg[1], 3);
+ value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
+ value = value -1;
+ dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
+ agc_delay_cfg[1] = (value >> 8) & 0x0f;
+ agc_delay_cfg[2] = 0x00;
+ agc_delay_cfg[3] = value & 0xff;
+ i2c_writebytes(state, state->config->demod_address,
+ agc_delay_cfg, sizeof(agc_delay_cfg));
+
+ /* Change the value of IAGCBW[15:8]
+ of inner AGC loop filter bandwith */
+ i2c_writebytes(state, state->config->demod_address,
+ agc_loop_cfg, sizeof(agc_loop_cfg));
+
+ state->config->set_ts_params(fe, 0);
+ state->current_modulation = param->u.vsb.modulation;
+ }
+
+ /* Change only if we are actually changing the channel */
+ if (state->current_frequency != param->frequency) {
+ dvb_pll_configure(state->config->pll_desc, buf,
+ param->frequency, 0);
+ dprintk("%s: tuner bytes: 0x%02x 0x%02x "
+ "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
+ i2c_writebytes(state, state->config->pll_address ,buf, 4);
+
+ /* Check the status of the tuner pll */
+ i2c_readbytes(state, state->config->pll_address, buf, 1);
+ dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
+
+ /* Update current frequency */
+ state->current_frequency = param->frequency;
+ }
+ lgdt3302_SwReset(state);
+ return 0;
+}
+
+static int lgdt3302_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters* param)
+{
+ struct lgdt3302_state *state = fe->demodulator_priv;
+ param->frequency = state->current_frequency;
+ return 0;
+}
+
+static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
+ u8 buf[3];
+
+ *status = 0; /* Reset status result */
+
+ /* Check the status of the tuner pll */
+ i2c_readbytes(state, state->config->pll_address, buf, 1);
+ dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
+ if ((buf[0] & 0xc0) != 0x40)
+ return 0; /* Tuner PLL not locked or not powered on */
+
+ /*
+ * You must set the Mask bits to 1 in the IRQ_MASK in order
+ * to see that status bit in the IRQ_STATUS register.
+ * This is done in SwReset();
+ */
+
+ /* AGC status register */
+ i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
+ dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+ if ((buf[0] & 0x0c) == 0x8){
+ /* Test signal does not exist flag */
+ /* as well as the AGC lock flag. */
+ *status |= FE_HAS_SIGNAL;
+ } else {
+ /* Without a signal all other status bits are meaningless */
+ return 0;
+ }
+
+ /* signal status */
+ i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
+ dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
+
+#if 0
+ /* Alternative method to check for a signal */
+ /* using the SNR good/bad interrupts. */
+ if ((buf[2] & 0x30) == 0x10)
+ *status |= FE_HAS_SIGNAL;
+#endif
+
+ /* sync status */
+ if ((buf[2] & 0x03) == 0x01) {
+ *status |= FE_HAS_SYNC;
+ }
+
+ /* FEC error status */
+ if ((buf[2] & 0x0c) == 0x08) {
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_VITERBI;
+ }
+
+ /* Carrier Recovery Lock Status Register */
+ i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
+ dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ /* Need to undestand why there are 3 lock levels here */
+ if ((buf[0] & 0x07) == 0x07)
+ *status |= FE_HAS_CARRIER;
+ break;
+ case VSB_8:
+ if ((buf[0] & 0x80) == 0x80)
+ *status |= FE_HAS_CARRIER;
+ break;
+ default:
+ printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ }
+
+ return 0;
+}
+
+static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ /* not directly available. */
+ return 0;
+}
+
+static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+#ifdef SNR_IN_DB
+ /*
+ * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
+ * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
+ * respectively. The following tables are built on these formulas.
+ * The usual definition is SNR = 20 log10(signal/noise)
+ * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
+ *
+ * This table is a an ordered list of noise values computed by the
+ * formula from the spec sheet such that the index into the table
+ * starting at 43 or 45 is the SNR value in db. There are duplicate noise
+ * value entries at the beginning because the SNR varies more than
+ * 1 db for a change of 1 digit in noise at very small values of noise.
+ *
+ * Examples from SNR_EQ table:
+ * noise SNR
+ * 0 43
+ * 1 42
+ * 2 39
+ * 3 37
+ * 4 36
+ * 5 35
+ * 6 34
+ * 7 33
+ * 8 33
+ * 9 32
+ * 10 32
+ * 11 31
+ * 12 31
+ * 13 30
+ */
+
+ static const u32 SNR_EQ[] =
+ { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
+ 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
+ 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
+ 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
+ 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
+ 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
+ };
+
+ static const u32 SNR_PH[] =
+ { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
+ 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
+ 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
+ 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
+ 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
+ 90833, 114351, 143960, 181235, 228161, 0x040000
+ };
+
+ static u8 buf[5];/* read data buffer */
+ static u32 noise; /* noise value */
+ static u32 snr_db; /* index into SNR_EQ[] */
+ struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
+
+ /* read both equalizer and pase tracker noise data */
+ i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
+
+ if (state->current_modulation == VSB_8) {
+ /* Equalizer Mean-Square Error Register for VSB */
+ noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
+
+ /*
+ * Look up noise value in table.
+ * A better search algorithm could be used...
+ * watch out there are duplicate entries.
+ */
+ for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
+ if (noise < SNR_EQ[snr_db]) {
+ *snr = 43 - snr_db;
+ break;
+ }
+ }
+ } else {
+ /* Phase Tracker Mean-Square Error Register for QAM */
+ noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+
+ /* Look up noise value in table. */
+ for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
+ if (noise < SNR_PH[snr_db]) {
+ *snr = 45 - snr_db;
+ break;
+ }
+ }
+ }
+#else
+ /* Return the raw noise value */
+ static u8 buf[5];/* read data buffer */
+ static u32 noise; /* noise value */
+ struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
+
+ /* read both equalizer and pase tracker noise data */
+ i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
+
+ if (state->current_modulation == VSB_8) {
+ /* Equalizer Mean-Square Error Register for VSB */
+ noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
+ } else {
+ /* Phase Tracker Mean-Square Error Register for QAM */
+ noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+ }
+
+ /* Small values for noise mean signal is better so invert noise */
+ /* Noise is 19 bit value so discard 3 LSB*/
+ *snr = ~noise>>3;
+#endif
+
+ dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
+
+ return 0;
+}
+
+static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
+{
+ /* I have no idea about this - it may not be needed */
+ fe_tune_settings->min_delay_ms = 500;
+ fe_tune_settings->step_size = 0;
+ fe_tune_settings->max_drift = 0;
+ return 0;
+}
+
+static void lgdt3302_release(struct dvb_frontend* fe)
+{
+ struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3302_ops;
+
+struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
+ struct i2c_adapter* i2c)
+{
+ struct lgdt3302_state* state = NULL;
+ u8 buf[1];
+
+ /* Allocate memory for the internal state */
+ state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+ memset(state,0,sizeof(*state));
+
+ /* Setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
+ /* Verify communication with demod chip */
+ if (i2c_selectreadbytes(state, 2, buf, 1))
+ goto error;
+
+ state->current_frequency = -1;
+ state->current_modulation = -1;
+
+ /* Create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ if (state)
+ kfree(state);
+ dprintk("%s: ERROR\n",__FUNCTION__);
+ return NULL;
+}
+
+static struct dvb_frontend_ops lgdt3302_ops = {
+ .info = {
+ .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
+ .type = FE_ATSC,
+ .frequency_min= 54000000,
+ .frequency_max= 858000000,
+ .frequency_stepsize= 62500,
+ /* Symbol rate is for all VSB modes need to check QAM */
+ .symbol_rate_min = 10762000,
+ .symbol_rate_max = 10762000,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .init = lgdt3302_init,
+ .set_frontend = lgdt3302_set_parameters,
+ .get_frontend = lgdt3302_get_frontend,
+ .get_tune_settings = lgdt3302_get_tune_settings,
+ .read_status = lgdt3302_read_status,
+ .read_ber = lgdt3302_read_ber,
+ .read_signal_strength = lgdt3302_read_signal_strength,
+ .read_snr = lgdt3302_read_snr,
+ .read_ucblocks = lgdt3302_read_ucblocks,
+ .release = lgdt3302_release,
+};
+
+MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_AUTHOR("Wilson Michaels");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(lgdt3302_attach);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * compile-command: "make DVB=1"
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt3302.h b/drivers/media/dvb/frontends/lgdt3302.h
new file mode 100644
index 00000000000..81587a40032
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.h
@@ -0,0 +1,49 @@
+/*
+ * $Id: lgdt3302.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
+ *
+ * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
+ *
+ * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef LGDT3302_H
+#define LGDT3302_H
+
+#include <linux/dvb/frontend.h>
+
+struct lgdt3302_config
+{
+ /* The demodulator's i2c address */
+ u8 demod_address;
+ u8 pll_address;
+ struct dvb_pll_desc *pll_desc;
+
+ /* Need to set device param for start_dma */
+ int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+};
+
+extern struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
+ struct i2c_adapter* i2c);
+
+#endif /* LGDT3302_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt3302_priv.h b/drivers/media/dvb/frontends/lgdt3302_priv.h
new file mode 100644
index 00000000000..6193fa7a569
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302_priv.h
@@ -0,0 +1,72 @@
+/*
+ * $Id: lgdt3302_priv.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
+ *
+ * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
+ *
+ * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT3302_PRIV_
+#define _LGDT3302_PRIV_
+
+/* i2c control register addresses */
+enum I2C_REG {
+ TOP_CONTROL= 0x00,
+ IRQ_MASK= 0x01,
+ IRQ_STATUS= 0x02,
+ VSB_CARRIER_FREQ0= 0x16,
+ VSB_CARRIER_FREQ1= 0x17,
+ VSB_CARRIER_FREQ2= 0x18,
+ VSB_CARRIER_FREQ3= 0x19,
+ CARRIER_MSEQAM1= 0x1a,
+ CARRIER_MSEQAM2= 0x1b,
+ CARRIER_LOCK= 0x1c,
+ TIMING_RECOVERY= 0x1d,
+ AGC_DELAY0= 0x2a,
+ AGC_DELAY1= 0x2b,
+ AGC_DELAY2= 0x2c,
+ AGC_RF_BANDWIDTH0= 0x2d,
+ AGC_RF_BANDWIDTH1= 0x2e,
+ AGC_RF_BANDWIDTH2= 0x2f,
+ AGC_LOOP_BANDWIDTH0= 0x30,
+ AGC_LOOP_BANDWIDTH1= 0x31,
+ AGC_FUNC_CTRL1= 0x32,
+ AGC_FUNC_CTRL2= 0x33,
+ AGC_FUNC_CTRL3= 0x34,
+ AGC_RFIF_ACC0= 0x39,
+ AGC_RFIF_ACC1= 0x3a,
+ AGC_RFIF_ACC2= 0x3b,
+ AGC_STATUS= 0x3f,
+ SYNC_STATUS_VSB= 0x43,
+ EQPH_ERR0= 0x47,
+ EQ_ERR1= 0x48,
+ EQ_ERR2= 0x49,
+ PH_ERR1= 0x4a,
+ PH_ERR2= 0x4b,
+ DEMUX_CONTROL= 0x66,
+ PACKET_ERR_COUNTER1= 0x6a,
+ PACKET_ERR_COUNTER2= 0x6b,
+};
+
+#endif /* _LGDT3302_PRIV_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
new file mode 100644
index 00000000000..4f396ac8de7
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -0,0 +1,800 @@
+/*
+Driver for Samsung S5H1420 QPSK Demodulator
+
+Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include "dvb_frontend.h"
+#include "s5h1420.h"
+
+
+
+#define TONE_FREQ 22000
+
+struct s5h1420_state {
+ struct i2c_adapter* i2c;
+ struct dvb_frontend_ops ops;
+ const struct s5h1420_config* config;
+ struct dvb_frontend frontend;
+
+ u8 postlocked:1;
+ u32 fclk;
+ u32 tunedfreq;
+ fe_code_rate_t fec_inner;
+ u32 symbol_rate;
+};
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
+
+
+static int debug = 0;
+#define dprintk if (debug) printk
+
+static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
+{
+ u8 buf [] = { reg, data };
+ struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+ int err;
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg)
+{
+ int ret;
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 };
+ struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 };
+
+ if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1)
+ return ret;
+
+ if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1)
+ return ret;
+
+ return b1[0];
+}
+
+static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ switch(voltage) {
+ case SEC_VOLTAGE_13:
+ s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
+ break;
+
+ case SEC_VOLTAGE_18:
+ s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
+ break;
+
+ case SEC_VOLTAGE_OFF:
+ s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
+ break;
+ }
+
+ return 0;
+}
+
+static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ switch(tone) {
+ case SEC_TONE_ON:
+ s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
+ break;
+
+ case SEC_TONE_OFF:
+ s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
+ break;
+ }
+
+ return 0;
+}
+
+static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ u8 val;
+ int i;
+ unsigned long timeout;
+ int result = 0;
+
+ /* setup for DISEQC */
+ val = s5h1420_readreg(state, 0x3b);
+ s5h1420_writereg(state, 0x3b, 0x02);
+ msleep(15);
+
+ /* write the DISEQC command bytes */
+ for(i=0; i< cmd->msg_len; i++) {
+ s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
+ }
+
+ /* kick off transmission */
+ s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
+
+ /* wait for transmission to complete */
+ timeout = jiffies + ((100*HZ) / 1000);
+ while(time_before(jiffies, timeout)) {
+ if (s5h1420_readreg(state, 0x3b) & 0x08)
+ break;
+
+ msleep(5);
+ }
+ if (time_after(jiffies, timeout))
+ result = -ETIMEDOUT;
+
+ /* restore original settings */
+ s5h1420_writereg(state, 0x3b, val);
+ msleep(15);
+ return result;
+}
+
+static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ u8 val;
+ int i;
+ int length;
+ unsigned long timeout;
+ int result = 0;
+
+ /* setup for DISEQC recieve */
+ val = s5h1420_readreg(state, 0x3b);
+ s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
+ msleep(15);
+
+ /* wait for reception to complete */
+ timeout = jiffies + ((reply->timeout*HZ) / 1000);
+ while(time_before(jiffies, timeout)) {
+ if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
+ break;
+
+ msleep(5);
+ }
+ if (time_after(jiffies, timeout)) {
+ result = -ETIMEDOUT;
+ goto exit;
+ }
+
+ /* check error flag - FIXME: not sure what this does - docs do not describe
+ * beyond "error flag for diseqc receive data :( */
+ if (s5h1420_readreg(state, 0x49)) {
+ result = -EIO;
+ goto exit;
+ }
+
+ /* check length */
+ length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
+ if (length > sizeof(reply->msg)) {
+ result = -EOVERFLOW;
+ goto exit;
+ }
+ reply->msg_len = length;
+
+ /* extract data */
+ for(i=0; i< length; i++) {
+ reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
+ }
+
+exit:
+ /* restore original settings */
+ s5h1420_writereg(state, 0x3b, val);
+ msleep(15);
+ return result;
+}
+
+static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ u8 val;
+ int result = 0;
+ unsigned long timeout;
+
+ /* setup for tone burst */
+ val = s5h1420_readreg(state, 0x3b);
+ s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
+
+ /* set value for B position if requested */
+ if (minicmd == SEC_MINI_B) {
+ s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
+ }
+ msleep(15);
+
+ /* start transmission */
+ s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
+
+ /* wait for transmission to complete */
+ timeout = jiffies + ((20*HZ) / 1000);
+ while(time_before(jiffies, timeout)) {
+ if (!(s5h1420_readreg(state, 0x3b) & 0x08))
+ break;
+
+ msleep(5);
+ }
+ if (time_after(jiffies, timeout))
+ result = -ETIMEDOUT;
+
+ /* restore original settings */
+ s5h1420_writereg(state, 0x3b, val);
+ msleep(15);
+ return result;
+}
+
+static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
+{
+ u8 val;
+ fe_status_t status = 0;
+
+ val = s5h1420_readreg(state, 0x14);
+ if (val & 0x02)
+ status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right
+ if (val & 0x01)
+ status |= FE_HAS_CARRIER; // FIXME: not sure if this is right
+ val = s5h1420_readreg(state, 0x36);
+ if (val & 0x01)
+ status |= FE_HAS_VITERBI;
+ if (val & 0x20)
+ status |= FE_HAS_SYNC;
+ if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
+ status |= FE_HAS_LOCK;
+
+ return status;
+}
+
+static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ u8 val;
+
+ if (status == NULL)
+ return -EINVAL;
+
+ /* determine lock state */
+ *status = s5h1420_get_status_bits(state);
+
+ /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
+ wait a bit and check again */
+ if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
+ val = s5h1420_readreg(state, 0x32);
+ if ((val & 0x07) == 0x03) {
+ if (val & 0x08)
+ s5h1420_writereg(state, 0x31, 0x13);
+ else
+ s5h1420_writereg(state, 0x31, 0x1b);
+
+ /* wait a bit then update lock status */
+ mdelay(200);
+ *status = s5h1420_get_status_bits(state);
+ }
+ }
+
+ /* perform post lock setup */
+ if ((*status & FE_HAS_LOCK) && (!state->postlocked)) {
+
+ /* calculate the data rate */
+ u32 tmp = s5h1420_getsymbolrate(state);
+ switch(s5h1420_readreg(state, 0x32) & 0x07) {
+ case 0:
+ tmp = (tmp * 2 * 1) / 2;
+ break;
+
+ case 1:
+ tmp = (tmp * 2 * 2) / 3;
+ break;
+
+ case 2:
+ tmp = (tmp * 2 * 3) / 4;
+ break;
+
+ case 3:
+ tmp = (tmp * 2 * 5) / 6;
+ break;
+
+ case 4:
+ tmp = (tmp * 2 * 6) / 7;
+ break;
+
+ case 5:
+ tmp = (tmp * 2 * 7) / 8;
+ break;
+ }
+ tmp = state->fclk / tmp;
+
+ /* set the MPEG_CLK_INTL for the calculated data rate */
+ if (tmp < 4)
+ val = 0x00;
+ else if (tmp < 8)
+ val = 0x01;
+ else if (tmp < 12)
+ val = 0x02;
+ else if (tmp < 16)
+ val = 0x03;
+ else if (tmp < 24)
+ val = 0x04;
+ else if (tmp < 32)
+ val = 0x05;
+ else
+ val = 0x06;
+ s5h1420_writereg(state, 0x22, val);
+
+ /* DC freeze */
+ s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01);
+
+ /* kicker disable + remove DC offset */
+ s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f);
+
+ /* post-lock processing has been done! */
+ state->postlocked = 1;
+ }
+
+ return 0;
+}
+
+static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ s5h1420_writereg(state, 0x46, 0x1d);
+ mdelay(25);
+ return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+}
+
+static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ u8 val = 0xff - s5h1420_readreg(state, 0x15);
+
+ return (int) ((val << 8) | val);
+}
+
+static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ s5h1420_writereg(state, 0x46, 0x1f);
+ mdelay(25);
+ return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+}
+
+static void s5h1420_reset(struct s5h1420_state* state)
+{
+ s5h1420_writereg (state, 0x01, 0x08);
+ s5h1420_writereg (state, 0x01, 0x00);
+ udelay(10);
+}
+
+static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+ u64 val;
+
+ val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
+ if (p->u.qpsk.symbol_rate <= 21000000) {
+ val *= 2;
+ }
+ do_div(val, (state->fclk / 1000));
+
+ s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f);
+ s5h1420_writereg(state, 0x11, val >> 16);
+ s5h1420_writereg(state, 0x12, val >> 8);
+ s5h1420_writereg(state, 0x13, val & 0xff);
+ s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80);
+}
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
+{
+ u64 val;
+ int sampling = 2;
+
+ if (s5h1420_readreg(state, 0x05) & 0x2)
+ sampling = 1;
+
+ s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
+ val = s5h1420_readreg(state, 0x11) << 16;
+ val |= s5h1420_readreg(state, 0x12) << 8;
+ val |= s5h1420_readreg(state, 0x13);
+ s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+
+ val *= (state->fclk / 1000);
+ do_div(val, ((1<<24) * sampling));
+
+ return (u32) (val * 1000);
+}
+
+static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
+{
+ int val;
+
+ /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+ * divide fclk by 1000000 to get the correct value. */
+ val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
+
+ s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf);
+ s5h1420_writereg(state, 0x0e, val >> 16);
+ s5h1420_writereg(state, 0x0f, val >> 8);
+ s5h1420_writereg(state, 0x10, val & 0xff);
+ s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40);
+}
+
+static int s5h1420_getfreqoffset(struct s5h1420_state* state)
+{
+ int val;
+
+ s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
+ val = s5h1420_readreg(state, 0x0e) << 16;
+ val |= s5h1420_readreg(state, 0x0f) << 8;
+ val |= s5h1420_readreg(state, 0x10);
+ s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+
+ if (val & 0x800000)
+ val |= 0xff000000;
+
+ /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+ * divide fclk by 1000000 to get the correct value. */
+ val = - ((val * (state->fclk/1000000)) / (1<<24));
+
+ return val;
+}
+
+static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+ if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
+ s5h1420_writereg(state, 0x31, 0x00);
+ s5h1420_writereg(state, 0x30, 0x3f);
+ } else {
+ switch(p->u.qpsk.fec_inner) {
+ case FEC_1_2:
+ s5h1420_writereg(state, 0x31, 0x10);
+ s5h1420_writereg(state, 0x30, 0x01);
+ break;
+
+ case FEC_2_3:
+ s5h1420_writereg(state, 0x31, 0x11);
+ s5h1420_writereg(state, 0x30, 0x02);
+ break;
+
+ case FEC_3_4:
+ s5h1420_writereg(state, 0x31, 0x12);
+ s5h1420_writereg(state, 0x30, 0x04);
+ break;
+
+ case FEC_5_6:
+ s5h1420_writereg(state, 0x31, 0x13);
+ s5h1420_writereg(state, 0x30, 0x08);
+ break;
+
+ case FEC_6_7:
+ s5h1420_writereg(state, 0x31, 0x14);
+ s5h1420_writereg(state, 0x30, 0x10);
+ break;
+
+ case FEC_7_8:
+ s5h1420_writereg(state, 0x31, 0x15);
+ s5h1420_writereg(state, 0x30, 0x20);
+ break;
+
+ default:
+ return;
+ }
+ }
+}
+
+static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
+{
+ switch(s5h1420_readreg(state, 0x32) & 0x07) {
+ case 0:
+ return FEC_1_2;
+
+ case 1:
+ return FEC_2_3;
+
+ case 2:
+ return FEC_3_4;
+
+ case 3:
+ return FEC_5_6;
+
+ case 4:
+ return FEC_6_7;
+
+ case 5:
+ return FEC_7_8;
+ }
+
+ return FEC_NONE;
+}
+
+static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+ if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
+ s5h1420_writereg(state, 0x31, 0x00);
+ s5h1420_writereg(state, 0x30, 0x3f);
+ } else {
+ u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
+ tmp |= 0x10;
+
+ if (p->inversion == INVERSION_ON)
+ tmp |= 0x80;
+
+ s5h1420_writereg(state, 0x31, tmp);
+ }
+}
+
+static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
+{
+ if (s5h1420_readreg(state, 0x32) & 0x08)
+ return INVERSION_ON;
+
+ return INVERSION_OFF;
+}
+
+static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ u32 frequency_delta;
+ struct dvb_frontend_tune_settings fesettings;
+
+ /* check if we should do a fast-tune */
+ memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
+ s5h1420_get_tune_settings(fe, &fesettings);
+ frequency_delta = p->frequency - state->tunedfreq;
+ if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
+ (frequency_delta != 0) &&
+ (state->fec_inner == p->u.qpsk.fec_inner) &&
+ (state->symbol_rate == p->u.qpsk.symbol_rate)) {
+
+ s5h1420_setfreqoffset(state, frequency_delta);
+ return 0;
+ }
+
+ /* first of all, software reset */
+ s5h1420_reset(state);
+
+ /* set tuner PLL */
+ if (state->config->pll_set) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_set(fe, p, &state->tunedfreq);
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
+ }
+
+ /* set s5h1420 fclk PLL according to desired symbol rate */
+ if (p->u.qpsk.symbol_rate > 28000000) {
+ state->fclk = 88000000;
+ s5h1420_writereg(state, 0x03, 0x50);
+ s5h1420_writereg(state, 0x04, 0x40);
+ s5h1420_writereg(state, 0x05, 0xae);
+ } else if (p->u.qpsk.symbol_rate > 21000000) {
+ state->fclk = 59000000;
+ s5h1420_writereg(state, 0x03, 0x33);
+ s5h1420_writereg(state, 0x04, 0x40);
+ s5h1420_writereg(state, 0x05, 0xae);
+ } else {
+ state->fclk = 88000000;
+ s5h1420_writereg(state, 0x03, 0x50);
+ s5h1420_writereg(state, 0x04, 0x40);
+ s5h1420_writereg(state, 0x05, 0xac);
+ }
+
+ /* set misc registers */
+ s5h1420_writereg(state, 0x02, 0x00);
+ s5h1420_writereg(state, 0x07, 0xb0);
+ s5h1420_writereg(state, 0x0a, 0x67);
+ s5h1420_writereg(state, 0x0b, 0x78);
+ s5h1420_writereg(state, 0x0c, 0x48);
+ s5h1420_writereg(state, 0x0d, 0x6b);
+ s5h1420_writereg(state, 0x2e, 0x8e);
+ s5h1420_writereg(state, 0x35, 0x33);
+ s5h1420_writereg(state, 0x38, 0x01);
+ s5h1420_writereg(state, 0x39, 0x7d);
+ s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
+ s5h1420_writereg(state, 0x3c, 0x00);
+ s5h1420_writereg(state, 0x45, 0x61);
+ s5h1420_writereg(state, 0x46, 0x1d);
+
+ /* start QPSK */
+ s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
+
+ /* set the frequency offset to adjust for PLL inaccuracy */
+ s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
+
+ /* set the reset of the parameters */
+ s5h1420_setsymbolrate(state, p);
+ s5h1420_setinversion(state, p);
+ s5h1420_setfec(state, p);
+
+ state->fec_inner = p->u.qpsk.fec_inner;
+ state->symbol_rate = p->u.qpsk.symbol_rate;
+ state->postlocked = 0;
+ return 0;
+}
+
+static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
+ p->inversion = s5h1420_getinversion(state);
+ p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state);
+ p->u.qpsk.fec_inner = s5h1420_getfec(state);
+
+ return 0;
+}
+
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+ if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
+ fesettings->min_delay_ms = 50;
+ fesettings->step_size = 2000;
+ fesettings->max_drift = 8000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 1500;
+ fesettings->max_drift = 9000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 1000;
+ fesettings->max_drift = 8000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
+ fesettings->min_delay_ms = 100;
+ fesettings->step_size = 500;
+ fesettings->max_drift = 7000;
+ } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
+ fesettings->min_delay_ms = 200;
+ fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+ fesettings->max_drift = 14 * fesettings->step_size;
+ } else {
+ fesettings->min_delay_ms = 200;
+ fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+ fesettings->max_drift = 18 * fesettings->step_size;
+ }
+
+ return 0;
+}
+
+static int s5h1420_init (struct dvb_frontend* fe)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ /* disable power down and do reset */
+ s5h1420_writereg(state, 0x02, 0x10);
+ msleep(10);
+ s5h1420_reset(state);
+
+ /* init PLL */
+ if (state->config->pll_init) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_init(fe);
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
+ }
+
+ return 0;
+}
+
+static int s5h1420_sleep(struct dvb_frontend* fe)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+
+ return s5h1420_writereg(state, 0x02, 0x12);
+}
+
+static void s5h1420_release(struct dvb_frontend* fe)
+{
+ struct s5h1420_state* state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1420_ops;
+
+struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
+{
+ struct s5h1420_state* state = NULL;
+ u8 identity;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
+ state->postlocked = 0;
+ state->fclk = 88000000;
+ state->tunedfreq = 0;
+ state->fec_inner = FEC_NONE;
+ state->symbol_rate = 0;
+
+ /* check if the demod is there + identify it */
+ identity = s5h1420_readreg(state, 0x00);
+ if (identity != 0x03)
+ goto error;
+
+ /* create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+
+static struct dvb_frontend_ops s5h1420_ops = {
+
+ .info = {
+ .name = "Samsung S5H1420 DVB-S",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125, /* kHz for QPSK frontends */
+ .frequency_tolerance = 29500,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ /* .symbol_rate_tolerance = ???,*/
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK
+ },
+
+ .release = s5h1420_release,
+
+ .init = s5h1420_init,
+ .sleep = s5h1420_sleep,
+
+ .set_frontend = s5h1420_set_frontend,
+ .get_frontend = s5h1420_get_frontend,
+ .get_tune_settings = s5h1420_get_tune_settings,
+
+ .read_status = s5h1420_read_status,
+ .read_ber = s5h1420_read_ber,
+ .read_signal_strength = s5h1420_read_signal_strength,
+ .read_ucblocks = s5h1420_read_ucblocks,
+
+ .diseqc_send_master_cmd = s5h1420_send_master_cmd,
+ .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
+ .diseqc_send_burst = s5h1420_send_burst,
+ .set_tone = s5h1420_set_tone,
+ .set_voltage = s5h1420_set_voltage,
+};
+
+module_param(debug, int, 0644);
+
+MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(s5h1420_attach);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
new file mode 100644
index 00000000000..b687fc77ceb
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -0,0 +1,41 @@
+/*
+ Driver for S5H1420 QPSK Demodulators
+
+ Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef S5H1420_H
+#define S5H1420_H
+
+#include <linux/dvb/frontend.h>
+
+struct s5h1420_config
+{
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* PLL maintenance */
+ int (*pll_init)(struct dvb_frontend* fe);
+ int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
+};
+
+extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
+ struct i2c_adapter* i2c);
+
+#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index e681263bf07..928aca052af 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -617,7 +617,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
/* wait for WGAGC lock */
starttime = jiffies;
- timeout = jiffies + (200 * HZ) / 1000;
+ timeout = jiffies + msecs_to_jiffies(2000);
while (time_before(jiffies, timeout)) {
msleep(10);
if (stv0297_readreg(state, 0x43) & 0x08)
@@ -629,7 +629,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
msleep(20);
/* wait for equaliser partial convergence */
- timeout = jiffies + (50 * HZ) / 1000;
+ timeout = jiffies + msecs_to_jiffies(500);
while (time_before(jiffies, timeout)) {
msleep(10);
@@ -642,7 +642,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
}
/* wait for equaliser full convergence */
- timeout = jiffies + (delay * HZ) / 1000;
+ timeout = jiffies + msecs_to_jiffies(delay);
while (time_before(jiffies, timeout)) {
msleep(10);
@@ -659,7 +659,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
stv0297_writereg_mask(state, 0x88, 8, 0);
/* wait for main lock */
- timeout = jiffies + (20 * HZ) / 1000;
+ timeout = jiffies + msecs_to_jiffies(20);
while (time_before(jiffies, timeout)) {
msleep(10);
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 0beb370792a..ab0c032472c 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -49,10 +49,8 @@ struct tda1004x_state {
/* private demod data */
u8 initialised;
enum tda1004x_demod demod_type;
- u8 fw_version;
};
-
static int debug;
#define dprintk(args...) \
do { \
@@ -122,6 +120,8 @@ static int debug;
#define TDA10046H_GPIO_OUT_SEL 0x41
#define TDA10046H_GPIO_SELECT 0x42
#define TDA10046H_AGC_CONF 0x43
+#define TDA10046H_AGC_THR 0x44
+#define TDA10046H_AGC_RENORM 0x45
#define TDA10046H_AGC_GAINS 0x46
#define TDA10046H_AGC_TUN_MIN 0x47
#define TDA10046H_AGC_TUN_MAX 0x48
@@ -274,14 +274,26 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state,
switch (bandwidth) {
case BANDWIDTH_6_MHZ:
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+ if (state->config->if_freq == TDA10046_FREQ_045) {
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f);
+ }
break;
case BANDWIDTH_7_MHZ:
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+ if (state->config->if_freq == TDA10046_FREQ_045) {
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79);
+ }
break;
case BANDWIDTH_8_MHZ:
tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+ if (state->config->if_freq == TDA10046_FREQ_045) {
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+ }
break;
default:
@@ -315,20 +327,35 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
memcpy(buf + 1, mem + pos, tx_size);
fw_msg.len = tx_size + 1;
if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
- printk("tda1004x: Error during firmware upload\n");
+ printk(KERN_ERR "tda1004x: Error during firmware upload\n");
return -EIO;
}
pos += tx_size;
dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
}
+ // give the DSP a chance to settle 03/10/05 Hac
+ msleep(100);
return 0;
}
-static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
+static int tda1004x_check_upload_ok(struct tda1004x_state *state)
{
u8 data1, data2;
+ unsigned long timeout;
+
+ if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
+ timeout = jiffies + 2 * HZ;
+ while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
+ break;
+ }
+ msleep(1);
+ }
+ } else
+ msleep(100);
// check upload was OK
tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
@@ -336,9 +363,11 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
- if ((data1 != 0x67) || (data2 != dspVersion))
+ if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
+ printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
return -EIO;
-
+ }
+ printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
return 0;
}
@@ -349,14 +378,14 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
const struct firmware *fw;
/* don't re-upload unless necessary */
- if (tda1004x_check_upload_ok(state, 0x2c) == 0)
+ if (tda1004x_check_upload_ok(state) == 0)
return 0;
/* request the firmware, this will block until someone uploads it */
- printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
+ printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
if (ret) {
- printk("tda1004x: no firmware upload (timeout or file not found?)\n");
+ printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
return ret;
}
@@ -370,95 +399,93 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
+ release_firmware(fw);
if (ret)
return ret;
- printk("tda1004x: firmware upload complete\n");
+ printk(KERN_INFO "tda1004x: firmware upload complete\n");
/* wait for DSP to initialise */
/* DSPREADY doesn't seem to work on the TDA10045H */
msleep(100);
- return tda1004x_check_upload_ok(state, 0x2c);
+ return tda1004x_check_upload_ok(state);
}
-static int tda10046_get_fw_version(struct tda1004x_state *state,
- const struct firmware *fw)
+static void tda10046_init_plls(struct dvb_frontend* fe)
{
- const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 };
- unsigned int i;
-
- /* area guessed from firmware v20, v21 and v25 */
- for (i = 0x660; i < 0x700; i++) {
- if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) {
- state->fw_version = fw->data[i + sizeof(pattern)];
- printk(KERN_INFO "tda1004x: using firmware v%02x\n",
- state->fw_version);
- return 0;
- }
- }
+ struct tda1004x_state* state = fe->demodulator_priv;
- return -EINVAL;
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
+ if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
+ dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
+ } else {
+ dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
+ }
+ tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
+ switch (state->config->if_freq) {
+ case TDA10046_FREQ_3617:
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
+ break;
+ case TDA10046_FREQ_3613:
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
+ break;
+ case TDA10046_FREQ_045:
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+ break;
+ case TDA10046_FREQ_052:
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);
+ break;
+ }
+ tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
}
static int tda10046_fwupload(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- unsigned long timeout;
int ret;
const struct firmware *fw;
/* reset + wake up chip */
- tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
- msleep(100);
+ /* let the clocks recover from sleep */
+ msleep(5);
/* don't re-upload unless necessary */
- if (tda1004x_check_upload_ok(state, state->fw_version) == 0)
+ if (tda1004x_check_upload_ok(state) == 0)
return 0;
- /* request the firmware, this will block until someone uploads it */
- printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
- ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
- if (ret) {
- printk("tda1004x: no firmware upload (timeout or file not found?)\n");
- return ret;
- }
-
- if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */
- printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size);
- return -EINVAL;
- }
-
- ret = tda10046_get_fw_version(state, fw);
- if (ret < 0) {
- printk("tda1004x: unable to find firmware version\n");
- return ret;
- }
-
/* set parameters */
- tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
- tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c);
- tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
- tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
- tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
- tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
-
- ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
- if (ret)
- return ret;
- printk("tda1004x: firmware upload complete\n");
-
- /* wait for DSP to initialise */
- timeout = jiffies + HZ;
- while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
- if (time_after(jiffies, timeout)) {
- printk("tda1004x: DSP failed to initialised.\n");
- return -EIO;
+ tda10046_init_plls(fe);
+
+ if (state->config->request_firmware != NULL) {
+ /* request the firmware, this will block until someone uploads it */
+ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
+ ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
+ if (ret) {
+ printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
+ return ret;
}
- msleep(1);
+ tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+ ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
+ release_firmware(fw);
+ if (ret)
+ return ret;
+ } else {
+ /* boot from firmware eeprom */
+ /* Hac Note: we might need to do some GPIO Magic here */
+ printk(KERN_INFO "tda1004x: booting from eeprom\n");
+ tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+ msleep(300);
}
-
- return tda1004x_check_upload_ok(state, state->fw_version);
+ return tda1004x_check_upload_ok(state);
}
static int tda1004x_encode_fec(int fec)
@@ -560,12 +587,10 @@ static int tda10046_init(struct dvb_frontend* fe)
if (tda10046_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n");
- return -EIO;
+ return -EIO;
}
- tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip
-
- // Init the PLL
+ // Init the tuner PLL
if (state->config->pll_init) {
tda1004x_enable_tuner_i2c(state);
state->config->pll_init(fe);
@@ -574,32 +599,44 @@ static int tda10046_init(struct dvb_frontend* fe)
// tda setup
tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
- tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40);
- tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
- tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
- tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
- tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0
- tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
- tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
- tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
- tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup
- tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
+ tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream
+ tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
+
+ tda10046_init_plls(fe);
+ switch (state->config->agc_config) {
+ case TDA10046_AGC_DEFAULT:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+ break;
+ case TDA10046_AGC_IFO_AUTO_NEG:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+ break;
+ case TDA10046_AGC_IFO_AUTO_POS:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
+ break;
+ case TDA10046_AGC_TDA827X:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
+ tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+ break;
+ }
+ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
- tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
- tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
+ tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
- tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
- tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
+ tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+ tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
+
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
- tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
- tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
-
- tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
+ tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
state->initialised = 1;
return 0;
@@ -629,9 +666,6 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
state->config->pll_set(fe, fe_params);
tda1004x_disable_tuner_i2c(state);
- if (state->demod_type == TDA1004X_DEMOD_TDA10046)
- tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
-
// Hardcoded to use auto as much as possible on the TDA10045 as it
// is very unreliable if AUTO mode is _not_ used.
if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
@@ -1089,6 +1123,11 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
break;
case TDA1004X_DEMOD_TDA10046:
+ if (state->config->pll_sleep != NULL) {
+ tda1004x_enable_tuner_i2c(state);
+ state->config->pll_sleep(fe);
+ tda1004x_disable_tuner_i2c(state);
+ }
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break;
}
@@ -1100,8 +1139,9 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
{
fesettings->min_delay_ms = 800;
- fesettings->step_size = 166667;
- fesettings->max_drift = 166667*2;
+ /* Drift compensation makes no sense for DVB-T */
+ fesettings->step_size = 0;
+ fesettings->max_drift = 0;
return 0;
}
@@ -1216,7 +1256,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
state->initialised = 0;
state->demod_type = TDA1004X_DEMOD_TDA10046;
- state->fw_version = 0x20; /* dummy default value */
/* check if the demod is there */
if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index c8e1d54ff26..8659c52647a 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -26,6 +26,25 @@
#include <linux/dvb/frontend.h>
#include <linux/firmware.h>
+enum tda10046_xtal {
+ TDA10046_XTAL_4M,
+ TDA10046_XTAL_16M,
+};
+
+enum tda10046_agc {
+ TDA10046_AGC_DEFAULT, /* original configuration */
+ TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
+ TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
+ TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
+};
+
+enum tda10046_if {
+ TDA10046_FREQ_3617, /* original config, 36,166 MHZ */
+ TDA10046_FREQ_3613, /* 36,13 MHZ */
+ TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */
+ TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
+};
+
struct tda1004x_config
{
/* the demodulator's i2c address */
@@ -37,14 +56,22 @@ struct tda1004x_config
/* Does the OCLK signal need inverted? */
u8 invert_oclk;
- /* value of N_I2C of the CONF_PLL3 register */
- u8 n_i2c;
+ /* Xtal frequency, 4 or 16MHz*/
+ enum tda10046_xtal xtal_freq;
+
+ /* IF frequency */
+ enum tda10046_if if_freq;
+
+ /* AGC configuration */
+ enum tda10046_agc agc_config;
/* PLL maintenance */
int (*pll_init)(struct dvb_frontend* fe);
+ void (*pll_sleep)(struct dvb_frontend* fe);
int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
/* request firmware for device */
+ /* set this to NULL if the card has a firmware EEPROM */
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
};
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
index 032d348dafb..88e125079ca 100644
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -27,7 +27,6 @@
#include <linux/spinlock.h>
#include <linux/threads.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
new file mode 100644
index 00000000000..f02842be0d6
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -0,0 +1,16 @@
+config DVB_PLUTO2
+ tristate "Pluto2 cards"
+ depends on DVB_CORE && PCI
+ select I2C
+ select I2C_ALGOBIT
+ select DVB_TDA1004X
+ help
+ Support for PCI cards based on the Pluto2 FPGA like the Satelco
+ Easywatch Mobile Terrestrial DVB-T Receiver.
+
+ Since these cards have no MPEG decoder onboard, they transmit
+ only compressed MPEG data over the PCI bus, so you need
+ an external software decoder to watch TV on your computer.
+
+ Say Y or M if you own such a device and want to use it.
+
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile
new file mode 100644
index 00000000000..86ca84b2be6
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_PLUTO2) = pluto2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
new file mode 100644
index 00000000000..706e0bcb5ed
--- /dev/null
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -0,0 +1,809 @@
+/*
+ * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
+ *
+ * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
+ *
+ * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
+ * by Dany Salman <salmandany@yahoo.fr>
+ * Copyright (c) 2004 TDF
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+
+#include "demux.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include "dvbdev.h"
+#include "tda1004x.h"
+
+#define DRIVER_NAME "pluto2"
+
+#define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */
+#define REG_PCAR 0x0020 /* PC address register */
+#define REG_TSCR 0x0024 /* TS ctrl & status */
+#define REG_MISC 0x0028 /* miscellaneous */
+#define REG_MMAC 0x002c /* MSB MAC address */
+#define REG_IMAC 0x0030 /* ISB MAC address */
+#define REG_LMAC 0x0034 /* LSB MAC address */
+#define REG_SPID 0x0038 /* SPI data */
+#define REG_SLCS 0x003c /* serial links ctrl/status */
+
+#define PID0_NOFIL (0x0001 << 16)
+#define PIDn_ENP (0x0001 << 15)
+#define PID0_END (0x0001 << 14)
+#define PID0_AFIL (0x0001 << 13)
+#define PIDn_PID (0x1fff << 0)
+
+#define TSCR_NBPACKETS (0x00ff << 24)
+#define TSCR_DEM (0x0001 << 17)
+#define TSCR_DE (0x0001 << 16)
+#define TSCR_RSTN (0x0001 << 15)
+#define TSCR_MSKO (0x0001 << 14)
+#define TSCR_MSKA (0x0001 << 13)
+#define TSCR_MSKL (0x0001 << 12)
+#define TSCR_OVR (0x0001 << 11)
+#define TSCR_AFUL (0x0001 << 10)
+#define TSCR_LOCK (0x0001 << 9)
+#define TSCR_IACK (0x0001 << 8)
+#define TSCR_ADEF (0x007f << 0)
+
+#define MISC_DVR (0x0fff << 4)
+#define MISC_ALED (0x0001 << 3)
+#define MISC_FRST (0x0001 << 2)
+#define MISC_LED1 (0x0001 << 1)
+#define MISC_LED0 (0x0001 << 0)
+
+#define SPID_SPIDR (0x00ff << 0)
+
+#define SLCS_SCL (0x0001 << 7)
+#define SLCS_SDA (0x0001 << 6)
+#define SLCS_CSN (0x0001 << 2)
+#define SLCS_OVR (0x0001 << 1)
+#define SLCS_SWC (0x0001 << 0)
+
+#define TS_DMA_PACKETS (8)
+#define TS_DMA_BYTES (188 * TS_DMA_PACKETS)
+
+#define I2C_ADDR_TDA10046 0x10
+#define I2C_ADDR_TUA6034 0xc2
+#define NHWFILTERS 8
+
+struct pluto {
+ /* pci */
+ struct pci_dev *pdev;
+ u8 __iomem *io_mem;
+
+ /* dvb */
+ struct dmx_frontend hw_frontend;
+ struct dmx_frontend mem_frontend;
+ struct dmxdev dmxdev;
+ struct dvb_adapter dvb_adapter;
+ struct dvb_demux demux;
+ struct dvb_frontend *fe;
+ struct dvb_net dvbnet;
+ unsigned int full_ts_users;
+ unsigned int users;
+
+ /* i2c */
+ struct i2c_algo_bit_data i2c_bit;
+ struct i2c_adapter i2c_adap;
+ unsigned int i2cbug;
+
+ /* irq */
+ unsigned int overflow;
+
+ /* dma */
+ dma_addr_t dma_addr;
+ u8 dma_buf[TS_DMA_BYTES];
+ u8 dummy[4096];
+};
+
+static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
+{
+ return container_of(feed->demux, struct pluto, demux);
+}
+
+static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
+{
+ return container_of(fe->dvb, struct pluto, dvb_adapter);
+}
+
+static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
+{
+ return readl(&pluto->io_mem[reg]);
+}
+
+static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
+{
+ writel(val, &pluto->io_mem[reg]);
+}
+
+static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
+{
+ u32 val = readl(&pluto->io_mem[reg]);
+ val &= ~mask;
+ val |= bits;
+ writel(val, &pluto->io_mem[reg]);
+}
+
+static void pluto_setsda(void *data, int state)
+{
+ struct pluto *pluto = data;
+
+ if (state)
+ pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
+ else
+ pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
+}
+
+static void pluto_setscl(void *data, int state)
+{
+ struct pluto *pluto = data;
+
+ if (state)
+ pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
+ else
+ pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
+
+ /* try to detect i2c_inb() to workaround hardware bug:
+ * reset SDA to high after SCL has been set to low */
+ if ((state) && (pluto->i2cbug == 0)) {
+ pluto->i2cbug = 1;
+ } else {
+ if ((!state) && (pluto->i2cbug == 1))
+ pluto_setsda(pluto, 1);
+ pluto->i2cbug = 0;
+ }
+}
+
+static int pluto_getsda(void *data)
+{
+ struct pluto *pluto = data;
+
+ return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
+}
+
+static int pluto_getscl(void *data)
+{
+ struct pluto *pluto = data;
+
+ return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
+}
+
+static void pluto_reset_frontend(struct pluto *pluto, int reenable)
+{
+ u32 val = pluto_readreg(pluto, REG_MISC);
+
+ if (val & MISC_FRST) {
+ val &= ~MISC_FRST;
+ pluto_writereg(pluto, REG_MISC, val);
+ }
+ if (reenable) {
+ val |= MISC_FRST;
+ pluto_writereg(pluto, REG_MISC, val);
+ }
+}
+
+static void pluto_reset_ts(struct pluto *pluto, int reenable)
+{
+ u32 val = pluto_readreg(pluto, REG_TSCR);
+
+ if (val & TSCR_RSTN) {
+ val &= ~TSCR_RSTN;
+ pluto_writereg(pluto, REG_TSCR, val);
+ }
+ if (reenable) {
+ val |= TSCR_RSTN;
+ pluto_writereg(pluto, REG_TSCR, val);
+ }
+}
+
+static void pluto_set_dma_addr(struct pluto *pluto)
+{
+ pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr));
+}
+
+static int __devinit pluto_dma_map(struct pluto *pluto)
+{
+ pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
+ TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+ return pci_dma_mapping_error(pluto->dma_addr);
+}
+
+static void pluto_dma_unmap(struct pluto *pluto)
+{
+ pci_unmap_single(pluto->pdev, pluto->dma_addr,
+ TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static int pluto_start_feed(struct dvb_demux_feed *f)
+{
+ struct pluto *pluto = feed_to_pluto(f);
+
+ /* enable PID filtering */
+ if (pluto->users++ == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
+
+ if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+ pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
+ else if (pluto->full_ts_users++ == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
+
+ return 0;
+}
+
+static int pluto_stop_feed(struct dvb_demux_feed *f)
+{
+ struct pluto *pluto = feed_to_pluto(f);
+
+ /* disable PID filtering */
+ if (--pluto->users == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
+
+ if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+ pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
+ else if (--pluto->full_ts_users == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
+
+ return 0;
+}
+
+static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
+{
+ /* synchronize the DMA transfer with the CPU
+ * first so that we see updated contents. */
+ pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
+ TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+ /* Workaround for broken hardware:
+ * [1] On startup NBPACKETS seems to contain an uninitialized value,
+ * but no packets have been transfered.
+ * [2] Sometimes (actually very often) NBPACKETS stays at zero
+ * although one packet has been transfered.
+ */
+ if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
+ unsigned int i = 0, valid;
+ while (pluto->dma_buf[i] == 0x47)
+ i += 188;
+ valid = i / 188;
+ if (nbpackets != valid) {
+ dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
+ nbpackets, valid);
+ nbpackets = valid;
+ }
+ }
+
+ dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
+
+ /* clear the dma buffer. this is needed to be able to identify
+ * new valid ts packets above */
+ memset(pluto->dma_buf, 0, nbpackets * 188);
+
+ /* reset the dma address */
+ pluto_set_dma_addr(pluto);
+
+ /* sync the buffer and give it back to the card */
+ pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
+ TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pluto *pluto = dev_id;
+ u32 tscr;
+
+ /* check whether an interrupt occured on this device */
+ tscr = pluto_readreg(pluto, REG_TSCR);
+ if (!(tscr & (TSCR_DE | TSCR_OVR)))
+ return IRQ_NONE;
+
+ if (tscr == 0xffffffff) {
+ // FIXME: maybe recover somehow
+ dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ return IRQ_HANDLED;
+ }
+
+ /* dma end interrupt */
+ if (tscr & TSCR_DE) {
+ pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
+ /* overflow interrupt */
+ if (tscr & TSCR_OVR)
+ pluto->overflow++;
+ if (pluto->overflow) {
+ dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
+ pluto->overflow);
+ pluto_reset_ts(pluto, 1);
+ pluto->overflow = 0;
+ }
+ } else if (tscr & TSCR_OVR) {
+ pluto->overflow++;
+ }
+
+ /* ACK the interrupt */
+ pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+
+ return IRQ_HANDLED;
+}
+
+static void __devinit pluto_enable_irqs(struct pluto *pluto)
+{
+ u32 val = pluto_readreg(pluto, REG_TSCR);
+
+ /* set the number of packets */
+ val &= ~TSCR_ADEF;
+ val |= TS_DMA_PACKETS / 2;
+ /* disable AFUL and LOCK interrupts */
+ val |= (TSCR_MSKA | TSCR_MSKL);
+ /* enable DMA and OVERFLOW interrupts */
+ val &= ~(TSCR_DEM | TSCR_MSKO);
+ /* clear pending interrupts */
+ val |= TSCR_IACK;
+
+ pluto_writereg(pluto, REG_TSCR, val);
+}
+
+static void pluto_disable_irqs(struct pluto *pluto)
+{
+ u32 val = pluto_readreg(pluto, REG_TSCR);
+
+ /* disable all interrupts */
+ val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
+ /* clear pending interrupts */
+ val |= TSCR_IACK;
+
+ pluto_writereg(pluto, REG_TSCR, val);
+}
+
+static int __devinit pluto_hw_init(struct pluto *pluto)
+{
+ pluto_reset_frontend(pluto, 1);
+
+ /* set automatic LED control by FPGA */
+ pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
+
+ /* set data endianess */
+#ifdef __LITTLE_ENDIAN
+ pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
+#else
+ pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
+#endif
+ /* map DMA and set address */
+ pluto_dma_map(pluto);
+ pluto_set_dma_addr(pluto);
+
+ /* enable interrupts */
+ pluto_enable_irqs(pluto);
+
+ /* reset TS logic */
+ pluto_reset_ts(pluto, 1);
+
+ return 0;
+}
+
+static void pluto_hw_exit(struct pluto *pluto)
+{
+ /* disable interrupts */
+ pluto_disable_irqs(pluto);
+
+ pluto_reset_ts(pluto, 0);
+
+ /* LED: disable automatic control, enable yellow, disable green */
+ pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
+
+ /* unmap DMA */
+ pluto_dma_unmap(pluto);
+
+ pluto_reset_frontend(pluto, 0);
+}
+
+static inline u32 divide(u32 numerator, u32 denominator)
+{
+ if (denominator == 0)
+ return ~0;
+
+ return (numerator + denominator / 2) / denominator;
+}
+
+/* LG Innotek TDTE-E001P (Infineon TUA6034) */
+static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct pluto *pluto = frontend_to_pluto(fe);
+ struct i2c_msg msg;
+ int ret;
+ u8 buf[4];
+ u32 div;
+
+ // Fref = 166.667 Hz
+ // Fref * 3 = 500.000 Hz
+ // IF = 36166667
+ // IF / Fref = 217
+ //div = divide(p->frequency + 36166667, 166667);
+ div = divide(p->frequency * 3, 500000) + 217;
+ buf[0] = (div >> 8) & 0x7f;
+ buf[1] = (div >> 0) & 0xff;
+
+ if (p->frequency < 611000000)
+ buf[2] = 0xb4;
+ else if (p->frequency < 811000000)
+ buf[2] = 0xbc;
+ else
+ buf[2] = 0xf4;
+
+ // VHF: 174-230 MHz
+ // center: 350 MHz
+ // UHF: 470-862 MHz
+ if (p->frequency < 350000000)
+ buf[3] = 0x02;
+ else
+ buf[3] = 0x04;
+
+ if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
+ buf[3] |= 0x08;
+
+ if (sizeof(buf) == 6) {
+ buf[4] = buf[2];
+ buf[4] &= ~0x1c;
+ buf[4] |= 0x18;
+
+ buf[5] = (0 << 7) | (2 << 4);
+ }
+
+ msg.addr = I2C_ADDR_TUA6034 >> 1;
+ msg.flags = 0;
+ msg.buf = buf;
+ msg.len = sizeof(buf);
+
+ ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
+ if (ret < 0)
+ return ret;
+ else if (ret == 0)
+ return -EREMOTEIO;
+
+ return 0;
+}
+
+static int pluto2_request_firmware(struct dvb_frontend *fe,
+ const struct firmware **fw, char *name)
+{
+ struct pluto *pluto = frontend_to_pluto(fe);
+
+ return request_firmware(fw, name, &pluto->pdev->dev);
+}
+
+static struct tda1004x_config pluto2_fe_config __devinitdata = {
+ .demod_address = I2C_ADDR_TDA10046 >> 1,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
+ .pll_set = lg_tdtpe001p_pll_set,
+ .pll_sleep = NULL,
+ .request_firmware = pluto2_request_firmware,
+};
+
+static int __devinit frontend_init(struct pluto *pluto)
+{
+ int ret;
+
+ pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
+ if (!pluto->fe) {
+ dev_err(&pluto->pdev->dev, "could not attach frontend\n");
+ return -ENODEV;
+ }
+
+ ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
+ if (ret < 0) {
+ if (pluto->fe->ops->release)
+ pluto->fe->ops->release(pluto->fe);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __devinit pluto_read_rev(struct pluto *pluto)
+{
+ u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
+ dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
+ (val >> 12) & 0x0f, (val >> 4) & 0xff);
+}
+
+static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
+{
+ u32 val = pluto_readreg(pluto, REG_MMAC);
+ mac[0] = (val >> 8) & 0xff;
+ mac[1] = (val >> 0) & 0xff;
+
+ val = pluto_readreg(pluto, REG_IMAC);
+ mac[2] = (val >> 8) & 0xff;
+ mac[3] = (val >> 0) & 0xff;
+
+ val = pluto_readreg(pluto, REG_LMAC);
+ mac[4] = (val >> 8) & 0xff;
+ mac[5] = (val >> 0) & 0xff;
+
+ dev_info(&pluto->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static int __devinit pluto_read_serial(struct pluto *pluto)
+{
+ struct pci_dev *pdev = pluto->pdev;
+ unsigned int i, j;
+ u8 __iomem *cis;
+
+ cis = pci_iomap(pdev, 1, 0);
+ if (!cis)
+ return -EIO;
+
+ dev_info(&pdev->dev, "S/N ");
+
+ for (i = 0xe0; i < 0x100; i += 4) {
+ u32 val = readl(&cis[i]);
+ for (j = 0; j < 32; j += 8) {
+ if ((val & 0xff) == 0xff)
+ goto out;
+ printk("%c", val & 0xff);
+ val >>= 8;
+ }
+ }
+out:
+ printk("\n");
+ pci_iounmap(pdev, cis);
+
+ return 0;
+}
+
+static int __devinit pluto2_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct pluto *pluto;
+ struct dvb_adapter *dvb_adapter;
+ struct dvb_demux *dvbdemux;
+ struct dmx_demux *dmx;
+ int ret = -ENOMEM;
+
+ pluto = kmalloc(sizeof(struct pluto), GFP_KERNEL);
+ if (!pluto)
+ goto out;
+
+ memset(pluto, 0, sizeof(struct pluto));
+ pluto->pdev = pdev;
+
+ ret = pci_enable_device(pdev);
+ if (ret < 0)
+ goto err_kfree;
+
+ /* enable interrupts */
+ pci_write_config_dword(pdev, 0x6c, 0x8000);
+
+ ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (ret < 0)
+ goto err_pci_disable_device;
+
+ pci_set_master(pdev);
+
+ ret = pci_request_regions(pdev, DRIVER_NAME);
+ if (ret < 0)
+ goto err_pci_disable_device;
+
+ pluto->io_mem = pci_iomap(pdev, 0, 0x40);
+ if (!pluto->io_mem) {
+ ret = -EIO;
+ goto err_pci_release_regions;
+ }
+
+ pci_set_drvdata(pdev, pluto);
+
+ ret = request_irq(pdev->irq, pluto_irq, SA_SHIRQ, DRIVER_NAME, pluto);
+ if (ret < 0)
+ goto err_pci_iounmap;
+
+ ret = pluto_hw_init(pluto);
+ if (ret < 0)
+ goto err_free_irq;
+
+ /* i2c */
+ i2c_set_adapdata(&pluto->i2c_adap, pluto);
+ strcpy(pluto->i2c_adap.name, DRIVER_NAME);
+ pluto->i2c_adap.owner = THIS_MODULE;
+ pluto->i2c_adap.id = I2C_ALGO_BIT;
+ pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
+ pluto->i2c_adap.dev.parent = &pdev->dev;
+ pluto->i2c_adap.algo_data = &pluto->i2c_bit;
+ pluto->i2c_bit.data = pluto;
+ pluto->i2c_bit.setsda = pluto_setsda;
+ pluto->i2c_bit.setscl = pluto_setscl;
+ pluto->i2c_bit.getsda = pluto_getsda;
+ pluto->i2c_bit.getscl = pluto_getscl;
+ pluto->i2c_bit.udelay = 10;
+ pluto->i2c_bit.timeout = 10;
+
+ /* Raise SCL and SDA */
+ pluto_setsda(pluto, 1);
+ pluto_setscl(pluto, 1);
+
+ ret = i2c_bit_add_bus(&pluto->i2c_adap);
+ if (ret < 0)
+ goto err_pluto_hw_exit;
+
+ /* dvb */
+ ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE);
+ if (ret < 0)
+ goto err_i2c_bit_del_bus;
+
+ dvb_adapter = &pluto->dvb_adapter;
+
+ pluto_read_rev(pluto);
+ pluto_read_serial(pluto);
+ pluto_read_mac(pluto, dvb_adapter->proposed_mac);
+
+ dvbdemux = &pluto->demux;
+ dvbdemux->filternum = 256;
+ dvbdemux->feednum = 256;
+ dvbdemux->start_feed = pluto_start_feed;
+ dvbdemux->stop_feed = pluto_stop_feed;
+ dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+ DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+ ret = dvb_dmx_init(dvbdemux);
+ if (ret < 0)
+ goto err_dvb_unregister_adapter;
+
+ dmx = &dvbdemux->dmx;
+
+ pluto->hw_frontend.source = DMX_FRONTEND_0;
+ pluto->mem_frontend.source = DMX_MEMORY_FE;
+ pluto->dmxdev.filternum = NHWFILTERS;
+ pluto->dmxdev.demux = dmx;
+
+ ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
+ if (ret < 0)
+ goto err_dvb_dmx_release;
+
+ ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
+ if (ret < 0)
+ goto err_dvb_dmxdev_release;
+
+ ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
+ if (ret < 0)
+ goto err_remove_hw_frontend;
+
+ ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
+ if (ret < 0)
+ goto err_remove_mem_frontend;
+
+ ret = frontend_init(pluto);
+ if (ret < 0)
+ goto err_disconnect_frontend;
+
+ dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
+out:
+ return ret;
+
+err_disconnect_frontend:
+ dmx->disconnect_frontend(dmx);
+err_remove_mem_frontend:
+ dmx->remove_frontend(dmx, &pluto->mem_frontend);
+err_remove_hw_frontend:
+ dmx->remove_frontend(dmx, &pluto->hw_frontend);
+err_dvb_dmxdev_release:
+ dvb_dmxdev_release(&pluto->dmxdev);
+err_dvb_dmx_release:
+ dvb_dmx_release(dvbdemux);
+err_dvb_unregister_adapter:
+ dvb_unregister_adapter(dvb_adapter);
+err_i2c_bit_del_bus:
+ i2c_bit_del_bus(&pluto->i2c_adap);
+err_pluto_hw_exit:
+ pluto_hw_exit(pluto);
+err_free_irq:
+ free_irq(pdev->irq, pluto);
+err_pci_iounmap:
+ pci_iounmap(pdev, pluto->io_mem);
+err_pci_release_regions:
+ pci_release_regions(pdev);
+err_pci_disable_device:
+ pci_disable_device(pdev);
+err_kfree:
+ pci_set_drvdata(pdev, NULL);
+ kfree(pluto);
+ goto out;
+}
+
+static void __devexit pluto2_remove(struct pci_dev *pdev)
+{
+ struct pluto *pluto = pci_get_drvdata(pdev);
+ struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
+ struct dvb_demux *dvbdemux = &pluto->demux;
+ struct dmx_demux *dmx = &dvbdemux->dmx;
+
+ dmx->close(dmx);
+ dvb_net_release(&pluto->dvbnet);
+ if (pluto->fe)
+ dvb_unregister_frontend(pluto->fe);
+
+ dmx->disconnect_frontend(dmx);
+ dmx->remove_frontend(dmx, &pluto->mem_frontend);
+ dmx->remove_frontend(dmx, &pluto->hw_frontend);
+ dvb_dmxdev_release(&pluto->dmxdev);
+ dvb_dmx_release(dvbdemux);
+ dvb_unregister_adapter(dvb_adapter);
+ i2c_bit_del_bus(&pluto->i2c_adap);
+ pluto_hw_exit(pluto);
+ free_irq(pdev->irq, pluto);
+ pci_iounmap(pdev, pluto->io_mem);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ kfree(pluto);
+}
+
+#ifndef PCI_VENDOR_ID_SCM
+#define PCI_VENDOR_ID_SCM 0x0432
+#endif
+#ifndef PCI_DEVICE_ID_PLUTO2
+#define PCI_DEVICE_ID_PLUTO2 0x0001
+#endif
+
+static struct pci_device_id pluto2_id_table[] __devinitdata = {
+ {
+ .vendor = PCI_VENDOR_ID_SCM,
+ .device = PCI_DEVICE_ID_PLUTO2,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ }, {
+ /* empty */
+ },
+};
+
+MODULE_DEVICE_TABLE(pci, pluto2_id_table);
+
+static struct pci_driver pluto2_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pluto2_id_table,
+ .probe = pluto2_probe,
+ .remove = __devexit_p(pluto2_remove),
+};
+
+static int __init pluto2_init(void)
+{
+ return pci_register_driver(&pluto2_driver);
+}
+
+static void __exit pluto2_exit(void)
+{
+ pci_unregister_driver(&pluto2_driver);
+}
+
+module_init(pluto2_init);
+module_exit(pluto2_exit);
+
+MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_DESCRIPTION("Pluto2 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 7ffa2c7315b..bf3c011d2cf 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -12,7 +12,7 @@ config DVB_AV7110
select DVB_STV0297
select DVB_L64781
help
- Support for SAA7146 and AV7110 based DVB cards as produced
+ Support for SAA7146 and AV7110 based DVB cards as produced
by Fujitsu-Siemens, Technotrend, Hauppauge and others.
This driver only supports the fullfeatured cards with
@@ -33,7 +33,7 @@ config DVB_AV7110_FIRMWARE
If you want to compile the firmware into the driver you need to say
Y here and provide the correct path of the firmware. You need this
option if you want to compile the whole driver statically into the
- kernel.
+ kernel.
All other people say N.
@@ -66,6 +66,7 @@ config DVB_BUDGET
select DVB_L64781
select DVB_TDA8083
select DVB_TDA10021
+ select DVB_S5H1420
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
@@ -119,9 +120,9 @@ config DVB_BUDGET_PATCH
select DVB_VES1X93
select DVB_TDA8083
help
- Support for Budget Patch (full TS) modification on
+ Support for Budget Patch (full TS) modification on
SAA7146+AV7110 based cards (DVB-S cards). This
- driver doesn't use onboard MPEG2 decoder. The
+ driver doesn't use onboard MPEG2 decoder. The
card is driven in Budget-only mode. Card is
required to have loaded firmware to tune properly.
Firmware can be loaded by insertion and removal of
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 8e33a850e13..e4c6e87f6c5 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -116,13 +116,18 @@ static int av7110_num = 0;
static void init_av7110_av(struct av7110 *av7110)
{
+ int ret;
struct saa7146_dev *dev = av7110->dev;
/* set internal volume control to maximum */
av7110->adac_type = DVB_ADAC_TI;
- av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+ ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
- av7710_set_video_mode(av7110, vidmode);
+ ret = av7710_set_video_mode(av7110, vidmode);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot set video mode:%d\n",ret);
/* handle different card types */
/* remaining inits according to card and frontend type */
@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110 *av7110)
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
// switch DVB SCART on
- av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
- av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+ ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
+ ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
if (rgb_on &&
(av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110 *av7110)
}
}
- av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
- av7110_setup_irc_config(av7110, 0);
+ ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot set volume :%d\n",ret);
+ ret = av7110_setup_irc_config(av7110, 0);
+ if (ret < 0)
+ printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
}
static void recover_arm(struct av7110 *av7110)
@@ -258,8 +271,9 @@ static int arm_thread(void *data)
*
* If we want to support multiple controls we would have to do much more...
*/
-void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
+int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
{
+ int ret = 0;
static struct av7110 *last;
dprintk(4, "%p\n", av7110);
@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
last = av7110;
if (av7110) {
- av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
av7110->ir_config = ir_config;
}
+ return ret;
}
static void (*irc_handler)(u32);
@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
pcrpid, vpid, apid, ttpid, subpid);
}
-void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
+ int ret = 0;
dprintk(4, "%p\n", av7110);
if (down_interruptible(&av7110->pid_mutex))
- return;
+ return -ERESTARTSYS;
if (!(vpid & 0x8000))
av7110->pids[DMX_PES_VIDEO] = vpid;
@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
if (av7110->fe_synced) {
pcrpid = av7110->pids[DMX_PES_PCR];
- SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
+ ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
}
up(&av7110->pid_mutex);
+ return ret;
}
@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
if (ret != 0 || handle >= 32) {
printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
- "ret %x handle %04x\n",
+ "ret %d handle %04x\n",
__FUNCTION__, buf[0], buf[1], buf[2], buf[3],
ret, handle);
dvbdmxfilter->hw_handle = 0xffff;
- return -1;
+ if (!ret)
+ ret = -1;
+ return ret;
}
av7110->handle2filter[handle] = dvbdmxfilter;
@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
if (handle >= 32) {
printk("%s tried to stop invalid filter %04x, filter type = %x\n",
__FUNCTION__, handle, dvbdmxfilter->type);
- return 0;
+ return -EINVAL;
}
av7110->handle2filter[handle] = NULL;
@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
"resp %04x %04x pid %d\n",
__FUNCTION__, buf[0], buf[1], buf[2], ret,
answ[0], answ[1], dvbdmxfilter->feed->pid);
- ret = -1;
+ if (!ret)
+ ret = -1;
}
return ret;
}
-static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
+static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5];
int i;
+ int ret = 0;
dprintk(4, "%p\n", av7110);
@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
npids[i] = 0;
- ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
- StartHWFilter(dvbdmxfeed->filter);
- return;
+ ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+ if (!ret)
+ ret = StartHWFilter(dvbdmxfeed->filter);
+ return ret;
+ }
+ if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
+ ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+ if (ret)
+ return ret;
}
- if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
- ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
if (dvbdmxfeed->pes_type < 2 && npids[0])
if (av7110->fe_synced)
- av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+ {
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+ if (ret)
+ return ret;
+ }
if ((dvbdmxfeed->ts_type & TS_PACKET)) {
if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
- av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
+ ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
- av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
+ ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
}
+ return ret;
}
-static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
+static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5];
int i;
+ int ret = 0;
+
dprintk(4, "%p\n", av7110);
if (dvbdmxfeed->pes_type <= 1) {
- av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
+ ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
+ if (ret)
+ return ret;
if (!av7110->rec_mode)
dvbdmx->recording = 0;
if (!av7110->playing)
@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
switch (i) {
case 2: //teletext
if (dvbdmxfeed->ts_type & TS_PACKET)
- StopHWFilter(dvbdmxfeed->filter);
+ ret = StopHWFilter(dvbdmxfeed->filter);
npids[2] = 0;
break;
case 0:
case 1:
case 4:
if (!pids_off)
- return;
+ return 0;
npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
break;
}
- ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+ if (!ret)
+ ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+ return ret;
}
static int av7110_start_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv;
+ int ret = 0;
dprintk(4, "%p\n", av7110);
@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
!(demux->pids[1] & 0x8000)) {
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
- av7110_av_start_play(av7110,RP_AV);
- demux->playing = 1;
+ ret = av7110_av_start_play(av7110,RP_AV);
+ if (!ret)
+ demux->playing = 1;
}
break;
default:
- dvb_feed_start_pid(feed);
+ ret = dvb_feed_start_pid(feed);
break;
}
} else if ((feed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE)) {
- StartHWFilter(feed->filter);
+ ret = StartHWFilter(feed->filter);
}
}
- if (feed->type == DMX_TYPE_SEC) {
+ else if (feed->type == DMX_TYPE_SEC) {
int i;
for (i = 0; i < demux->filternum; i++) {
@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
if (demux->filter[i].filter.parent != &feed->feed.sec)
continue;
demux->filter[i].state = DMX_STATE_GO;
- if (demux->dmx.frontend->source != DMX_MEMORY_FE)
- StartHWFilter(&demux->filter[i]);
+ if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+ ret = StartHWFilter(&demux->filter[i]);
+ if (ret)
+ break;
+ }
}
}
- return 0;
+ return ret;
}
@@ -1009,7 +1050,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv;
-
+ int i, rc, ret = 0;
dprintk(4, "%p\n", av7110);
if (feed->type == DMX_TYPE_TS) {
@@ -1022,26 +1063,29 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
}
if (feed->ts_type & TS_DECODER &&
feed->pes_type < DMX_TS_PES_OTHER) {
- dvb_feed_stop_pid(feed);
+ ret = dvb_feed_stop_pid(feed);
} else
if ((feed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE))
- StopHWFilter(feed->filter);
+ ret = StopHWFilter(feed->filter);
}
- if (feed->type == DMX_TYPE_SEC) {
- int i;
-
- for (i = 0; i<demux->filternum; i++)
+ if (!ret && feed->type == DMX_TYPE_SEC) {
+ for (i = 0; i<demux->filternum; i++) {
if (demux->filter[i].state == DMX_STATE_GO &&
demux->filter[i].filter.parent == &feed->feed.sec) {
demux->filter[i].state = DMX_STATE_READY;
- if (demux->dmx.frontend->source != DMX_MEMORY_FE)
- StopHWFilter(&demux->filter[i]);
+ if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+ rc = StopHWFilter(&demux->filter[i]);
+ if (!ret)
+ ret = rc;
+ /* keep going, stop as many filters as possible */
+ }
+ }
}
}
- return 0;
+ return ret;
}
@@ -1093,7 +1137,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
if (ret) {
printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
- return -EIO;
+ return ret;
}
dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
@@ -1119,18 +1163,14 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch (tone) {
case SEC_TONE_ON:
- Set22K(av7110, 1);
- break;
+ return Set22K(av7110, 1);
case SEC_TONE_OFF:
- Set22K(av7110, 0);
- break;
+ return Set22K(av7110, 0);
default:
return -EINVAL;
}
-
- return 0;
}
static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -1138,9 +1178,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
-
- return 0;
+ return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
}
static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
@@ -1148,9 +1186,7 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_diseqc_send(av7110, 0, NULL, minicmd);
-
- return 0;
+ return av7110_diseqc_send(av7110, 0, NULL, minicmd);
}
/* simplified code from budget-core.c */
@@ -1992,76 +2028,85 @@ static struct l64781_config grundig_29504_401_config = {
-static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
+static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
{
+ int ret = 0;
int synced = (status & FE_HAS_LOCK) ? 1 : 0;
av7110->fe_status = status;
if (av7110->fe_synced == synced)
- return;
-
- av7110->fe_synced = synced;
+ return 0;
if (av7110->playing)
- return;
+ return 0;
if (down_interruptible(&av7110->pid_mutex))
- return;
+ return -ERESTARTSYS;
- if (av7110->fe_synced) {
- SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+ if (synced) {
+ ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT], 0,
av7110->pids[DMX_PES_PCR]);
- av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+ if (!ret)
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
} else {
- SetPIDs(av7110, 0, 0, 0, 0, 0);
- av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
- av7110_wait_msgstate(av7110, GPMQBusy);
+ ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
+ if (!ret) {
+ ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
+ if (!ret)
+ ret = av7110_wait_msgstate(av7110, GPMQBusy);
+ }
}
+ if (!ret)
+ av7110->fe_synced = synced;
+
up(&av7110->pid_mutex);
+ return ret;
}
static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_set_frontend(fe, params);
+
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_set_frontend(fe, params);
+ return ret;
}
static int av7110_fe_init(struct dvb_frontend* fe)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_init(fe);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_init(fe);
+ return ret;
}
static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
struct av7110* av7110 = fe->dvb->priv;
- int ret;
/* call the real implementation */
- ret = av7110->fe_read_status(fe, status);
- if (ret)
- return ret;
-
- if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) {
- av7110_fe_lock_fix(av7110, *status);
- }
-
- return 0;
+ int ret = av7110->fe_read_status(fe, status);
+ if (!ret)
+ if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
+ ret = av7110_fe_lock_fix(av7110, *status);
+ return ret;
}
static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_diseqc_reset_overload(fe);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_diseqc_reset_overload(fe);
+ return ret;
}
static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_diseqc_send_master_cmd(fe, cmd);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
+ return ret;
}
static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_diseqc_send_burst(fe, minicmd);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_diseqc_send_burst(fe, minicmd);
+ return ret;
}
static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_set_tone(fe, tone);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_set_tone(fe, tone);
+ return ret;
}
static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_set_voltage(fe, voltage);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_set_voltage(fe, voltage);
+ return ret;
}
static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
{
struct av7110* av7110 = fe->dvb->priv;
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
+ int ret = av7110_fe_lock_fix(av7110, 0);
+ if (!ret)
+ ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
+ return ret;
}
static u8 read_pwm(struct av7110* av7110)
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 4f69b4d0147..508b7739c60 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -119,8 +119,7 @@ struct av7110 {
volatile int bmp_state;
#define BMP_NONE 0
#define BMP_LOADING 1
-#define BMP_LOADINGS 2
-#define BMP_LOADED 3
+#define BMP_LOADED 2
wait_queue_head_t bmpq;
@@ -255,12 +254,12 @@ struct av7110 {
};
-extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid);
extern void av7110_register_irc_handler(void (*func)(u32));
extern void av7110_unregister_irc_handler(void (*func)(u32));
-extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
+extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
extern int av7110_ir_init (void);
extern void av7110_ir_exit (void);
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index ccf946125d0..0696a5a4f85 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -121,6 +121,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
int av7110_av_start_record(struct av7110 *av7110, int av,
struct dvb_demux_feed *dvbdmxfeed)
{
+ int ret = 0;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
@@ -137,7 +138,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[0]->pid,
dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[0]);
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break;
case RP_VIDEO:
@@ -145,7 +146,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[1]);
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break;
case RP_AV:
@@ -157,14 +158,15 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[1]);
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
break;
}
- return 0;
+ return ret;
}
int av7110_av_start_play(struct av7110 *av7110, int av)
{
+ int ret = 0;
dprintk(2, "av7110:%p, \n", av7110);
if (av7110->rec_mode)
@@ -182,54 +184,57 @@ int av7110_av_start_play(struct av7110 *av7110, int av)
av7110->playing |= av;
switch (av7110->playing) {
case RP_AUDIO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
break;
case RP_VIDEO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
av7110->sinfo = 0;
break;
case RP_AV:
av7110->sinfo = 0;
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
break;
}
- return av7110->playing;
+ if (!ret)
+ ret = av7110->playing;
+ return ret;
}
-void av7110_av_stop(struct av7110 *av7110, int av)
+int av7110_av_stop(struct av7110 *av7110, int av)
{
+ int ret = 0;
dprintk(2, "av7110:%p, \n", av7110);
if (!(av7110->playing & av) && !(av7110->rec_mode & av))
- return;
-
+ return 0;
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
if (av7110->playing) {
av7110->playing &= ~av;
switch (av7110->playing) {
case RP_AUDIO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
break;
case RP_VIDEO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
break;
case RP_NONE:
- av7110_set_vidmode(av7110, av7110->vidmode);
+ ret = av7110_set_vidmode(av7110, av7110->vidmode);
break;
}
} else {
av7110->rec_mode &= ~av;
switch (av7110->rec_mode) {
case RP_AUDIO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break;
case RP_VIDEO:
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break;
case RP_NONE:
break;
}
}
+ return ret;
}
@@ -317,19 +322,22 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
return 0;
}
-void av7110_set_vidmode(struct av7110 *av7110, int mode)
+int av7110_set_vidmode(struct av7110 *av7110, int mode)
{
+ int ret;
dprintk(2, "av7110:%p, \n", av7110);
- av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
+ ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
- if (!av7110->playing) {
- ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+ if (!ret && !av7110->playing) {
+ ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT],
0, av7110->pids[DMX_PES_PCR]);
- av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+ if (!ret)
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
}
+ return ret;
}
@@ -340,17 +348,18 @@ static int sw2mode[16] = {
VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
};
-static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
+static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
{
int i;
int hsize, vsize;
int sw;
u8 *p;
+ int ret = 0;
dprintk(2, "av7110:%p, \n", av7110);
if (av7110->sinfo)
- return;
+ return 0;
for (i = 7; i < count - 10; i++) {
p = buf + i;
if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
@@ -359,11 +368,14 @@ static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
vsize = ((p[1] &0x0F) << 8) | (p[2]);
sw = (p[3] & 0x0F);
- av7110_set_vidmode(av7110, sw2mode[sw]);
- dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
- av7110->sinfo = 1;
+ ret = av7110_set_vidmode(av7110, sw2mode[sw]);
+ if (!ret) {
+ dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
+ av7110->sinfo = 1;
+ }
break;
}
+ return ret;
}
@@ -974,7 +986,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
unsigned long arg = (unsigned long) parg;
int ret = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
@@ -987,49 +999,57 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
case VIDEO_STOP:
av7110->videostate.play_state = VIDEO_STOPPED;
if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
- av7110_av_stop(av7110, RP_VIDEO);
+ ret = av7110_av_stop(av7110, RP_VIDEO);
else
- vidcom(av7110, VIDEO_CMD_STOP,
+ ret = vidcom(av7110, VIDEO_CMD_STOP,
av7110->videostate.video_blank ? 0 : 1);
- av7110->trickmode = TRICK_NONE;
+ if (!ret)
+ av7110->trickmode = TRICK_NONE;
break;
case VIDEO_PLAY:
av7110->trickmode = TRICK_NONE;
if (av7110->videostate.play_state == VIDEO_FREEZED) {
av7110->videostate.play_state = VIDEO_PLAYING;
- vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ if (ret)
+ break;
}
if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
if (av7110->playing == RP_AV) {
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+ if (ret)
+ break;
av7110->playing &= ~RP_VIDEO;
}
- av7110_av_start_play(av7110, RP_VIDEO);
- vidcom(av7110, VIDEO_CMD_PLAY, 0);
- } else {
- //av7110_av_stop(av7110, RP_VIDEO);
- vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ ret = av7110_av_start_play(av7110, RP_VIDEO);
}
- av7110->videostate.play_state = VIDEO_PLAYING;
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ if (!ret)
+ av7110->videostate.play_state = VIDEO_PLAYING;
break;
case VIDEO_FREEZE:
av7110->videostate.play_state = VIDEO_FREEZED;
if (av7110->playing & RP_VIDEO)
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
else
- vidcom(av7110, VIDEO_CMD_FREEZE, 1);
- av7110->trickmode = TRICK_FREEZE;
+ ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1);
+ if (!ret)
+ av7110->trickmode = TRICK_FREEZE;
break;
case VIDEO_CONTINUE:
if (av7110->playing & RP_VIDEO)
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
- vidcom(av7110, VIDEO_CMD_PLAY, 0);
- av7110->videostate.play_state = VIDEO_PLAYING;
- av7110->trickmode = TRICK_NONE;
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ if (!ret) {
+ av7110->videostate.play_state = VIDEO_PLAYING;
+ av7110->trickmode = TRICK_NONE;
+ }
break;
case VIDEO_SELECT_SOURCE:
@@ -1045,7 +1065,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
break;
case VIDEO_GET_EVENT:
- ret=dvb_video_get_event(av7110, parg, file->f_flags);
+ ret = dvb_video_get_event(av7110, parg, file->f_flags);
break;
case VIDEO_GET_SIZE:
@@ -1105,25 +1125,32 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
case VIDEO_FAST_FORWARD:
//note: arg is ignored by firmware
if (av7110->playing & RP_VIDEO)
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
- __Scan_I, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+ __Scan_I, 2, AV_PES, 0);
else
- vidcom(av7110, VIDEO_CMD_FFWD, arg);
- av7110->trickmode = TRICK_FAST;
- av7110->videostate.play_state = VIDEO_PLAYING;
+ ret = vidcom(av7110, VIDEO_CMD_FFWD, arg);
+ if (!ret) {
+ av7110->trickmode = TRICK_FAST;
+ av7110->videostate.play_state = VIDEO_PLAYING;
+ }
break;
case VIDEO_SLOWMOTION:
if (av7110->playing&RP_VIDEO) {
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
- vidcom(av7110, VIDEO_CMD_SLOW, arg);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
} else {
- vidcom(av7110, VIDEO_CMD_PLAY, 0);
- vidcom(av7110, VIDEO_CMD_STOP, 0);
- vidcom(av7110, VIDEO_CMD_SLOW, arg);
+ ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_STOP, 0);
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
+ }
+ if (!ret) {
+ av7110->trickmode = TRICK_SLOW;
+ av7110->videostate.play_state = VIDEO_PLAYING;
}
- av7110->trickmode = TRICK_SLOW;
- av7110->videostate.play_state = VIDEO_PLAYING;
break;
case VIDEO_GET_CAPABILITIES:
@@ -1136,18 +1163,21 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
av7110_ipack_reset(&av7110->ipack[1]);
if (av7110->playing == RP_AV) {
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
- __Play, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+ __Play, 2, AV_PES, 0);
+ if (ret)
+ break;
if (av7110->trickmode == TRICK_FAST)
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
- __Scan_I, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+ __Scan_I, 2, AV_PES, 0);
if (av7110->trickmode == TRICK_SLOW) {
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
- __Slow, 2, 0, 0);
- vidcom(av7110, VIDEO_CMD_SLOW, arg);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+ __Slow, 2, 0, 0);
+ if (!ret)
+ ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
}
if (av7110->trickmode == TRICK_FREEZE)
- vidcom(av7110, VIDEO_CMD_STOP, 1);
+ ret = vidcom(av7110, VIDEO_CMD_STOP, 1);
}
break;
@@ -1170,7 +1200,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
unsigned long arg = (unsigned long) parg;
int ret = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
(cmd != AUDIO_GET_STATUS))
@@ -1179,28 +1209,32 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case AUDIO_STOP:
if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
- av7110_av_stop(av7110, RP_AUDIO);
+ ret = av7110_av_stop(av7110, RP_AUDIO);
else
- audcom(av7110, AUDIO_CMD_MUTE);
- av7110->audiostate.play_state = AUDIO_STOPPED;
+ ret = audcom(av7110, AUDIO_CMD_MUTE);
+ if (!ret)
+ av7110->audiostate.play_state = AUDIO_STOPPED;
break;
case AUDIO_PLAY:
if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
- av7110_av_start_play(av7110, RP_AUDIO);
- audcom(av7110, AUDIO_CMD_UNMUTE);
- av7110->audiostate.play_state = AUDIO_PLAYING;
+ ret = av7110_av_start_play(av7110, RP_AUDIO);
+ if (!ret)
+ ret = audcom(av7110, AUDIO_CMD_UNMUTE);
+ if (!ret)
+ av7110->audiostate.play_state = AUDIO_PLAYING;
break;
case AUDIO_PAUSE:
- audcom(av7110, AUDIO_CMD_MUTE);
- av7110->audiostate.play_state = AUDIO_PAUSED;
+ ret = audcom(av7110, AUDIO_CMD_MUTE);
+ if (!ret)
+ av7110->audiostate.play_state = AUDIO_PAUSED;
break;
case AUDIO_CONTINUE:
if (av7110->audiostate.play_state == AUDIO_PAUSED) {
av7110->audiostate.play_state = AUDIO_PLAYING;
- audcom(av7110, AUDIO_CMD_MUTE | AUDIO_CMD_PCM16);
+ ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
}
break;
@@ -1210,14 +1244,15 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
case AUDIO_SET_MUTE:
{
- audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
- av7110->audiostate.mute_state = (int) arg;
+ ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
+ if (!ret)
+ av7110->audiostate.mute_state = (int) arg;
break;
}
case AUDIO_SET_AV_SYNC:
av7110->audiostate.AV_sync_state = (int) arg;
- audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
+ ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
break;
case AUDIO_SET_BYPASS_MODE:
@@ -1229,21 +1264,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
switch(av7110->audiostate.channel_select) {
case AUDIO_STEREO:
- audcom(av7110, AUDIO_CMD_STEREO);
- if (av7110->adac_type == DVB_ADAC_CRYSTAL)
- i2c_writereg(av7110, 0x20, 0x02, 0x49);
+ ret = audcom(av7110, AUDIO_CMD_STEREO);
+ if (!ret)
+ if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+ i2c_writereg(av7110, 0x20, 0x02, 0x49);
break;
case AUDIO_MONO_LEFT:
- audcom(av7110, AUDIO_CMD_MONO_L);
- if (av7110->adac_type == DVB_ADAC_CRYSTAL)
- i2c_writereg(av7110, 0x20, 0x02, 0x4a);
+ ret = audcom(av7110, AUDIO_CMD_MONO_L);
+ if (!ret)
+ if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+ i2c_writereg(av7110, 0x20, 0x02, 0x4a);
break;
case AUDIO_MONO_RIGHT:
- audcom(av7110, AUDIO_CMD_MONO_R);
- if (av7110->adac_type == DVB_ADAC_CRYSTAL)
- i2c_writereg(av7110, 0x20, 0x02, 0x45);
+ ret = audcom(av7110, AUDIO_CMD_MONO_R);
+ if (!ret)
+ if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+ i2c_writereg(av7110, 0x20, 0x02, 0x45);
break;
default:
@@ -1264,8 +1302,8 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
av7110_ipack_reset(&av7110->ipack[0]);
if (av7110->playing == RP_AV)
- av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
- __Play, 2, AV_PES, 0);
+ ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+ __Play, 2, AV_PES, 0);
break;
case AUDIO_SET_ID:
@@ -1274,7 +1312,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
{
struct audio_mixer *amix = (struct audio_mixer *)parg;
- av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
+ ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
break;
}
case AUDIO_SET_STREAMTYPE:
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
index cc5e7a7e87c..45dc144b8b4 100644
--- a/drivers/media/dvb/ttpci/av7110_av.h
+++ b/drivers/media/dvb/ttpci/av7110_av.h
@@ -3,14 +3,14 @@
struct av7110;
-extern void av7110_set_vidmode(struct av7110 *av7110, int mode);
+extern int av7110_set_vidmode(struct av7110 *av7110, int mode);
extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
-extern void av7110_av_stop(struct av7110 *av7110, int av);
+extern int av7110_av_stop(struct av7110 *av7110, int av);
extern int av7110_av_start_record(struct av7110 *av7110, int av,
struct dvb_demux_feed *dvbdmxfeed);
extern int av7110_av_start_play(struct av7110 *av7110, int av);
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 7fa4a0ebe13..1220826696c 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -137,7 +137,7 @@ static int waitdebi(struct av7110 *av7110, int adr, int state)
return 0;
udelay(5);
}
- return -1;
+ return -ETIMEDOUT;
}
static int load_dram(struct av7110 *av7110, u32 *data, int len)
@@ -155,7 +155,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
for (i = 0; i < blocks; i++) {
if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
- return -1;
+ return -ETIMEDOUT;
}
dprintk(4, "writing DRAM block %d\n", i);
mwdebi(av7110, DEBISWAB, bootblock,
@@ -170,7 +170,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
if (rest > 0) {
if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
- return -1;
+ return -ETIMEDOUT;
}
if (rest > 4)
mwdebi(av7110, DEBISWAB, bootblock,
@@ -185,13 +185,13 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
}
if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
- return -1;
+ return -ETIMEDOUT;
}
iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
- return -1;
+ return -ETIMEDOUT;
}
return 0;
}
@@ -263,7 +263,7 @@ int av7110_bootarm(struct av7110 *av7110)
if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
"saa7146_wait_for_debi_done() timed out\n");
- return -1;
+ return -ETIMEDOUT;
}
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(1);
@@ -284,7 +284,7 @@ int av7110_bootarm(struct av7110 *av7110)
if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
"saa7146_wait_for_debi_done() timed out after loading DRAM\n");
- return -1;
+ return -ETIMEDOUT;
}
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
msleep(30); /* the firmware needs some time to initialize */
@@ -308,6 +308,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
{
unsigned long start;
u32 stat;
+ int err;
if (FW_VERSION(av7110->arm_app) <= 0x261c) {
/* not supported by old firmware */
@@ -318,17 +319,17 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
/* new firmware */
start = jiffies;
for (;;) {
+ err = time_after(jiffies, start + ARM_WAIT_FREE);
if (down_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
up(&av7110->dcomlock);
- if ((stat & flags) == 0) {
+ if ((stat & flags) == 0)
break;
- }
- if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+ if (err) {
printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
__FUNCTION__, stat & flags);
- return -1;
+ return -ETIMEDOUT;
}
msleep(1);
}
@@ -342,6 +343,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
char *type = NULL;
u16 flags[2] = {0, 0};
u32 stat;
+ int err;
// dprintk(4, "%p\n", av7110);
@@ -351,24 +353,30 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
}
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_FREE);
+ if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+ break;
+ if (err) {
printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
return -ETIMEDOUT;
}
+ msleep(1);
}
wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
#ifndef _NOHANDSHAKE
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+ if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+ break;
+ if (err) {
printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
return -ETIMEDOUT;
}
+ msleep(1);
}
#endif
@@ -401,6 +409,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
/* non-immediate COMMAND type */
start = jiffies;
for (;;) {
+ err = time_after(jiffies, start + ARM_WAIT_FREE);
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & flags[0]) {
printk(KERN_ERR "%s: %s QUEUE overflow\n",
@@ -409,10 +418,10 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
}
if ((stat & flags[1]) == 0)
break;
- if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+ if (err) {
printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
__FUNCTION__, type);
- return -1;
+ return -ETIMEDOUT;
}
msleep(1);
}
@@ -432,13 +441,16 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
#ifdef COM_DEBUG
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_FREE)) {
- printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
- __FUNCTION__);
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_FREE);
+ if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+ break;
+ if (err) {
+ printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
+ __FUNCTION__, (buf[0] >> 8) & 0xff);
return -ETIMEDOUT;
}
+ msleep(1);
}
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
@@ -470,7 +482,7 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
ret = __av7110_send_fw_cmd(av7110, buf, length);
up(&av7110->dcomlock);
- if (ret)
+ if (ret && ret!=-ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
__FUNCTION__, ret);
return ret;
@@ -495,7 +507,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
}
ret = av7110_send_fw_cmd(av7110, buf, num + 2);
- if (ret)
+ if (ret && ret != -ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
return ret;
}
@@ -518,7 +530,7 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
}
ret = av7110_send_fw_cmd(av7110, cmd, 18);
- if (ret)
+ if (ret && ret != -ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
return ret;
}
@@ -551,26 +563,32 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
}
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
-#ifdef _NOHANDSHAKE
- msleep(1);
-#endif
- if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_FREE);
+ if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+ break;
+ if (err) {
printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
up(&av7110->dcomlock);
- return -1;
+ return -ETIMEDOUT;
}
+#ifdef _NOHANDSHAKE
+ msleep(1);
+#endif
}
#ifndef _NOHANDSHAKE
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+ if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+ break;
+ if (err) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
up(&av7110->dcomlock);
- return -1;
+ return -ETIMEDOUT;
}
+ msleep(1);
}
#endif
@@ -667,10 +685,10 @@ int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long bu
for (i = 0; i < len; i++)
buf[i + 4] = msg[i];
- if ((ret = av7110_send_fw_cmd(av7110, buf, 18)))
+ ret = av7110_send_fw_cmd(av7110, buf, 18);
+ if (ret && ret!=-ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
-
- return 0;
+ return ret;
}
@@ -705,18 +723,22 @@ static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
static int FlushText(struct av7110 *av7110)
{
unsigned long start;
+ int err;
if (down_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+ while (1) {
+ err = time_after(jiffies, start + ARM_WAIT_OSD);
+ if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+ break;
+ if (err) {
printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
up(&av7110->dcomlock);
- return -1;
+ return -ETIMEDOUT;
}
+ msleep(1);
}
up(&av7110->dcomlock);
return 0;
@@ -733,25 +755,31 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
return -ERESTARTSYS;
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+ while (1) {
+ ret = time_after(jiffies, start + ARM_WAIT_OSD);
+ if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+ break;
+ if (ret) {
printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
up(&av7110->dcomlock);
- return -1;
+ return -ETIMEDOUT;
}
+ msleep(1);
}
#ifndef _NOHANDSHAKE
start = jiffies;
- while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
- msleep(1);
- if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+ while (1) {
+ ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
+ if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+ break;
+ if (ret) {
printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
__FUNCTION__);
up(&av7110->dcomlock);
- return -1;
+ return -ETIMEDOUT;
}
+ msleep(1);
}
#endif
for (i = 0; i < length / 2; i++)
@@ -761,7 +789,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
up(&av7110->dcomlock);
- if (ret)
+ if (ret && ret!=-ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
return ret;
}
@@ -816,9 +844,25 @@ static osd_raw_window_t bpp2bit[8] = {
OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
};
-static inline int LoadBitmap(struct av7110 *av7110, u16 format,
+static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
+{
+ int ret = wait_event_interruptible_timeout(av7110->bmpq,
+ av7110->bmp_state != BMP_LOADING, 10*HZ);
+ if (ret == -ERESTARTSYS)
+ return ret;
+ if (ret == 0) {
+ printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
+ ret, av7110->bmp_state);
+ av7110->bmp_state = BMP_NONE;
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+static inline int LoadBitmap(struct av7110 *av7110,
u16 dx, u16 dy, int inc, u8 __user * data)
{
+ u16 format;
int bpp;
int i;
int d, delta;
@@ -827,14 +871,7 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
dprintk(4, "%p\n", av7110);
- ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
- if (ret == -ERESTARTSYS || ret == 0) {
- printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
- ret, av7110->bmp_state);
- av7110->bmp_state = BMP_NONE;
- return -1;
- }
- BUG_ON (av7110->bmp_state == BMP_LOADING);
+ format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
av7110->bmp_state = BMP_LOADING;
if (format == OSD_BITMAP8) {
@@ -847,18 +884,18 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
bpp=1; delta = 8;
} else {
av7110->bmp_state = BMP_NONE;
- return -1;
+ return -EINVAL;
}
av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
av7110->bmpp = 0;
if (av7110->bmplen > 32768) {
av7110->bmp_state = BMP_NONE;
- return -1;
+ return -EINVAL;
}
for (i = 0; i < dy; i++) {
if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
av7110->bmp_state = BMP_NONE;
- return -1;
+ return -EINVAL;
}
}
if (format != OSD_BITMAP8) {
@@ -873,37 +910,27 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
}
av7110->bmplen += 1024;
dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
- return av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
+ ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
+ if (!ret)
+ ret = WaitUntilBmpLoaded(av7110);
+ return ret;
}
-static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
+static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
{
- int ret;
-
dprintk(4, "%p\n", av7110);
- BUG_ON (av7110->bmp_state == BMP_NONE);
-
- ret = wait_event_interruptible_timeout(av7110->bmpq,
- av7110->bmp_state != BMP_LOADING, 10*HZ);
- if (ret == -ERESTARTSYS || ret == 0) {
- printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
- ret, av7110->bmp_state);
- av7110->bmp_state = BMP_NONE;
- return (ret == 0) ? -ETIMEDOUT : ret;
- }
-
- BUG_ON (av7110->bmp_state != BMP_LOADED);
-
- return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
+ return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
}
static inline int ReleaseBitmap(struct av7110 *av7110)
{
dprintk(4, "%p\n", av7110);
- if (av7110->bmp_state != BMP_LOADED)
+ if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
return -1;
+ if (av7110->bmp_state == BMP_LOADING)
+ dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
av7110->bmp_state = BMP_NONE;
return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
}
@@ -924,18 +951,22 @@ static u32 RGB2YUV(u16 R, u16 G, u16 B)
return Cr | (Cb << 16) | (Y << 8);
}
-static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
+static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
{
+ int ret;
+
u16 ch, cl;
u32 yuv;
yuv = blend ? RGB2YUV(r,g,b) : 0;
cl = (yuv & 0xffff);
ch = ((yuv >> 16) & 0xffff);
- SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
- color, ch, cl);
- SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
- color, ((blend >> 4) & 0x0f));
+ ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+ color, ch, cl);
+ if (!ret)
+ ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+ color, ((blend >> 4) & 0x0f));
+ return ret;
}
static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
@@ -968,14 +999,14 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
{
uint w, h, bpp, bpl, size, lpb, bnum, brest;
int i;
- int rc;
+ int rc,release_rc;
w = x1 - x0 + 1;
h = y1 - y0 + 1;
if (inc <= 0)
inc = w;
if (w <= 0 || w > 720 || h <= 0 || h > 576)
- return -1;
+ return -EINVAL;
bpp = av7110->osdbpp[av7110->osdwin] + 1;
bpl = ((w * bpp + 7) & ~7) / 8;
size = h * bpl;
@@ -983,176 +1014,186 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
bnum = size / (lpb * bpl);
brest = size - bnum * lpb * bpl;
- for (i = 0; i < bnum; i++) {
- rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
- w, lpb, inc, data);
- if (rc)
- return rc;
- rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+ if (av7110->bmp_state == BMP_LOADING) {
+ /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
+ BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
+ rc = WaitUntilBmpLoaded(av7110);
if (rc)
return rc;
- data += lpb * inc;
+ /* just continue. This should work for all fw versions
+ * if bnum==1 && !brest && LoadBitmap was successful
+ */
}
- if (brest) {
- rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
- w, brest / bpl, inc, data);
+
+ rc = 0;
+ for (i = 0; i < bnum; i++) {
+ rc = LoadBitmap(av7110, w, lpb, inc, data);
if (rc)
- return rc;
- rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+ break;
+ rc = BlitBitmap(av7110, x0, y0 + i * lpb);
if (rc)
- return rc;
+ break;
+ data += lpb * inc;
}
- ReleaseBitmap(av7110);
- return 0;
+ if (!rc && brest) {
+ rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
+ if (!rc)
+ rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
+ }
+ release_rc = ReleaseBitmap(av7110);
+ if (!rc)
+ rc = release_rc;
+ if (rc)
+ dprintk(1,"returns %d\n",rc);
+ return rc;
}
int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
{
int ret;
- ret = down_interruptible(&av7110->osd_sema);
- if (ret)
+ if (down_interruptible(&av7110->osd_sema))
return -ERESTARTSYS;
- /* stupid, but OSD functions don't provide a return code anyway */
- ret = 0;
-
switch (dc->cmd) {
case OSD_Close:
- DestroyOSDWindow(av7110, av7110->osdwin);
- goto out;
+ ret = DestroyOSDWindow(av7110, av7110->osdwin);
+ break;
case OSD_Open:
av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
- CreateOSDWindow(av7110, av7110->osdwin,
+ ret = CreateOSDWindow(av7110, av7110->osdwin,
bpp2bit[av7110->osdbpp[av7110->osdwin]],
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+ if (ret)
+ break;
if (!dc->data) {
- MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
- SetColorBlend(av7110, av7110->osdwin);
+ ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+ if (ret)
+ break;
+ ret = SetColorBlend(av7110, av7110->osdwin);
}
- goto out;
+ break;
case OSD_Show:
- MoveWindowRel(av7110, av7110->osdwin, 0, 0);
- goto out;
+ ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
+ break;
case OSD_Hide:
- HideWindow(av7110, av7110->osdwin);
- goto out;
+ ret = HideWindow(av7110, av7110->osdwin);
+ break;
case OSD_Clear:
- DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
- goto out;
+ ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
+ break;
case OSD_Fill:
- DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
- goto out;
+ ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
+ break;
case OSD_SetColor:
- OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
- goto out;
+ ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
+ break;
case OSD_SetPalette:
- {
- if (FW_VERSION(av7110->arm_app) >= 0x2618) {
+ if (FW_VERSION(av7110->arm_app) >= 0x2618)
ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
- goto out;
- } else {
+ else {
int i, len = dc->x0-dc->color+1;
u8 __user *colors = (u8 __user *)dc->data;
u8 r, g, b, blend;
-
+ ret = 0;
for (i = 0; i<len; i++) {
if (get_user(r, colors + i * 4) ||
get_user(g, colors + i * 4 + 1) ||
get_user(b, colors + i * 4 + 2) ||
get_user(blend, colors + i * 4 + 3)) {
ret = -EFAULT;
- goto out;
+ break;
}
- OSDSetColor(av7110, dc->color + i, r, g, b, blend);
+ ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
+ if (ret)
+ break;
}
}
- ret = 0;
- goto out;
- }
- case OSD_SetTrans:
- goto out;
+ break;
case OSD_SetPixel:
- DrawLine(av7110, av7110->osdwin,
+ ret = DrawLine(av7110, av7110->osdwin,
dc->x0, dc->y0, 0, 0, dc->color);
- goto out;
- case OSD_GetPixel:
- goto out;
+ break;
case OSD_SetRow:
dc->y1 = dc->y0;
/* fall through */
case OSD_SetBlock:
ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
- goto out;
+ break;
case OSD_FillRow:
- DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+ ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
dc->x1-dc->x0+1, dc->y1, dc->color);
- goto out;
+ break;
case OSD_FillBlock:
- DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+ ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
- goto out;
+ break;
case OSD_Line:
- DrawLine(av7110, av7110->osdwin,
+ ret = DrawLine(av7110, av7110->osdwin,
dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
- goto out;
- case OSD_Query:
- goto out;
- case OSD_Test:
- goto out;
+ break;
case OSD_Text:
{
char textbuf[240];
if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
ret = -EFAULT;
- goto out;
+ break;
}
textbuf[239] = 0;
if (dc->x1 > 3)
dc->x1 = 3;
- SetFont(av7110, av7110->osdwin, dc->x1,
+ ret = SetFont(av7110, av7110->osdwin, dc->x1,
(u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
- FlushText(av7110);
- WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
- goto out;
+ if (!ret)
+ ret = FlushText(av7110);
+ if (!ret)
+ ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
+ break;
}
case OSD_SetWindow:
- if (dc->x0 < 1 || dc->x0 > 7) {
+ if (dc->x0 < 1 || dc->x0 > 7)
ret = -EINVAL;
- goto out;
+ else {
+ av7110->osdwin = dc->x0;
+ ret = 0;
}
- av7110->osdwin = dc->x0;
- goto out;
+ break;
case OSD_MoveWindow:
- MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
- SetColorBlend(av7110, av7110->osdwin);
- goto out;
+ ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+ if (!ret)
+ ret = SetColorBlend(av7110, av7110->osdwin);
+ break;
case OSD_OpenRaw:
if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
ret = -EINVAL;
- goto out;
+ break;
}
- if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) {
+ if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
- }
- else {
+ else
av7110->osdbpp[av7110->osdwin] = 0;
- }
- CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
+ ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+ if (ret)
+ break;
if (!dc->data) {
- MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
- SetColorBlend(av7110, av7110->osdwin);
+ ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+ if (!ret)
+ ret = SetColorBlend(av7110, av7110->osdwin);
}
- goto out;
+ break;
default:
ret = -EINVAL;
- goto out;
+ break;
}
-out:
up(&av7110->osd_sema);
+ if (ret==-ERESTARTSYS)
+ dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
+ else if (ret)
+ dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
+
return ret;
}
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 52061e17c6d..fedd20f9815 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -458,27 +458,27 @@ static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
}
-static inline void av7710_set_video_mode(struct av7110 *av7110, int mode)
+static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
{
- av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
+ return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
}
-static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
+static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
{
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
(com>>16), (com&0xffff),
(arg>>16), (arg&0xffff));
}
-static int inline audcom(struct av7110 *av7110, u32 com)
+static inline int audcom(struct av7110 *av7110, u32 com)
{
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
(com>>16), (com&0xffff));
}
-static inline void Set22K(struct av7110 *av7110, int state)
+static inline int Set22K(struct av7110 *av7110, int state)
{
- av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
+ return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
}
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
index 24664074188..699ef8b5b99 100644
--- a/drivers/media/dvb/ttpci/av7110_ipack.c
+++ b/drivers/media/dvb/ttpci/av7110_ipack.c
@@ -24,7 +24,7 @@ int av7110_ipack_init(struct ipack *p, int size,
void (*func)(u8 *buf, int size, void *priv))
{
if (!(p->buf = vmalloc(size*sizeof(u8)))) {
- printk ("Couldn't allocate memory for ipack\n");
+ printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
return -ENOMEM;
}
p->size = size;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 6e0f5d307c5..9746d2bb916 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -570,9 +570,9 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
- buf[2] = 0x8e;
- buf[3] = (params->frequency < 174500000 ? 0xa1 :
- params->frequency < 454000000 ? 0x92 : 0x34);
+ buf[2] = 0x86;
+ buf[3] = (params->frequency < 150000000 ? 0x01 :
+ params->frequency < 445000000 ? 0x02 : 0x04);
if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
return -EIO;
@@ -695,8 +695,12 @@ static struct tda1004x_config philips_tu1216_config = {
.demod_address = 0x8,
.invert = 1,
.invert_oclk = 1,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
.pll_init = philips_tu1216_pll_init,
.pll_set = philips_tu1216_pll_set,
+ .pll_sleep = NULL,
.request_firmware = philips_tu1216_request_firmware,
};
@@ -1018,7 +1022,7 @@ static struct pci_device_id pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct saa7146_extension budget_extension = {
- .name = "budget dvb /w video in\0",
+ .name = "budget_av",
.pci_tbl = pci_tbl,
.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index dce11611137..a1267054bc0 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -69,6 +69,7 @@ struct budget_ci {
int slot_status;
struct dvb_ca_en50221 ca;
char ir_dev_name[50];
+ u8 tuner_pll_address; /* used for philips_tdm1316l configs */
};
/* from reading the following remotes:
@@ -723,7 +724,7 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
- struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len =
+ struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
sizeof(td1316_init) };
// setup PLL configuration
@@ -746,7 +747,7 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend
{
struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
u8 tuner_buf[4];
- struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
+ struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
int tuner_frequency = 0;
u8 band, cp, filter;
@@ -838,8 +839,12 @@ static struct tda1004x_config philips_tdm1316l_config = {
.demod_address = 0x8,
.invert = 0,
.invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
.pll_init = philips_tdm1316l_pll_init,
.pll_set = philips_tdm1316l_pll_set,
+ .pll_sleep = NULL,
.request_firmware = philips_tdm1316l_request_firmware,
};
@@ -865,12 +870,22 @@ static void frontend_init(struct budget_ci *budget_ci)
break;
case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+ budget_ci->tuner_pll_address = 0x63;
budget_ci->budget.dvb_frontend =
tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
break;
}
break;
+
+ case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+ budget_ci->tuner_pll_address = 0x60;
+ budget_ci->budget.dvb_frontend =
+ tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ if (budget_ci->budget.dvb_frontend) {
+ break;
+ }
+ break;
}
if (budget_ci->budget.dvb_frontend == NULL) {
@@ -950,11 +965,13 @@ static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
+ MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
{
.vendor = 0,
}
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 083fd44e5f9..9961917e8a7 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -40,6 +40,7 @@
#include "ves1820.h"
#include "l64781.h"
#include "tda8083.h"
+#include "s5h1420.h"
static void Set22K (struct budget *budget, int state)
{
@@ -177,6 +178,62 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m
return 0;
}
+static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+ struct budget* budget = (struct budget*) fe->dvb->priv;
+ u8 buf;
+ struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
+
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ switch(voltage) {
+ case SEC_VOLTAGE_13:
+ buf = (buf & 0xf7) | 0x04;
+ break;
+
+ case SEC_VOLTAGE_18:
+ buf = (buf & 0xf7) | 0x0c;
+ break;
+
+ case SEC_VOLTAGE_OFF:
+ buf = buf & 0xf0;
+ break;
+ }
+
+ msg.flags = 0;
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ return 0;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
+{
+ struct budget* budget = (struct budget*) fe->dvb->priv;
+ u8 buf;
+ struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
+
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ if (arg) {
+ buf = buf | 0x10;
+ } else {
+ buf = buf & 0xef;
+ }
+
+ msg.flags = 0;
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ return 0;
+}
+
+static void lnbp21_init(struct budget* budget)
+{
+ u8 buf = 0x00;
+ struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
+
+ i2c_transfer (&budget->i2c_adap, &msg, 1);
+}
+
static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -395,6 +452,38 @@ static struct tda8083_config grundig_29504_451_config = {
.pll_set = grundig_29504_451_pll_set,
};
+static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout)
+{
+ struct budget* budget = (struct budget*) fe->dvb->priv;
+ u32 div;
+ u8 data[4];
+ struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+ div = params->frequency / 1000;
+ data[0] = (div >> 8) & 0x7f;
+ data[1] = div & 0xff;
+ data[2] = 0xc2;
+
+ if (div < 1450)
+ data[3] = 0x00;
+ else if (div < 1850)
+ data[3] = 0x40;
+ else if (div < 2000)
+ data[3] = 0x80;
+ else
+ data[3] = 0xc0;
+
+ if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ *freqout = div * 1000;
+ return 0;
+}
+
+static struct s5h1420_config s5h1420_config = {
+ .demod_address = 0x53,
+ .pll_set = s5h1420_pll_set,
+};
+
static u8 read_pwm(struct budget* budget)
{
u8 b = 0xff;
@@ -459,6 +548,15 @@ static void frontend_init(struct budget *budget)
break;
}
break;
+
+ case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
+ budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
+ if (budget->dvb_frontend) {
+ budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
+ budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+ lnbp21_init(budget);
+ break;
+ }
}
if (budget->dvb_frontend == NULL) {
@@ -532,6 +630,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
+ MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
{
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 4aa714ab4c2..c6c1d41a2ef 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -3,6 +3,7 @@ config DVB_TTUSB_BUDGET
depends on DVB_CORE && USB
select DVB_CX22700
select DVB_TDA1004X
+ select DVB_VES1820
select DVB_TDA8083
select DVB_STV0299
help
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index afa0e7a0e50..aa43b5fcb8e 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -24,6 +24,7 @@
#include "dmxdev.h"
#include "dvb_demux.h"
#include "dvb_net.h"
+#include "ves1820.h"
#include "cx22700.h"
#include "tda1004x.h"
#include "stv0299.h"
@@ -1367,6 +1368,47 @@ static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
.pll_set = ttusb_novas_grundig_29504_491_pll_set,
};
+static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+ struct ttusb* ttusb = fe->dvb->priv;
+ u32 div;
+ u8 data[4];
+ struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
+
+ div = (params->frequency + 35937500 + 31250) / 62500;
+
+ data[0] = (div >> 8) & 0x7f;
+ data[1] = div & 0xff;
+ data[2] = 0x85 | ((div >> 10) & 0x60);
+ data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
+
+ if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+
+ return 0;
+}
+
+
+static struct ves1820_config alps_tdbe2_config = {
+ .demod_address = 0x09,
+ .xin = 57840000UL,
+ .invert = 1,
+ .selagc = VES1820_SELAGC_SIGNAMPERR,
+ .pll_set = alps_tdbe2_pll_set,
+};
+
+static u8 read_pwm(struct ttusb* ttusb)
+{
+ u8 b = 0xff;
+ u8 pwm;
+ struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
+ { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
+
+ if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+ pwm = 0x48;
+
+ return pwm;
+}
static void frontend_init(struct ttusb* ttusb)
@@ -1394,6 +1436,12 @@ static void frontend_init(struct ttusb* ttusb)
break;
+ case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
+ ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
+ if (ttusb->fe != NULL)
+ break;
+ break;
+
case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
// try the ALPS TDMB7 first
ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
@@ -1570,7 +1618,7 @@ static void ttusb_disconnect(struct usb_interface *intf)
static struct usb_device_id ttusb_table[] = {
{USB_DEVICE(0xb48, 0x1003)},
-/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */
+ {USB_DEVICE(0xb48, 0x1004)},
{USB_DEVICE(0xb48, 0x1005)},
{}
};
@@ -1578,7 +1626,7 @@ static struct usb_device_id ttusb_table[] = {
MODULE_DEVICE_TABLE(usb, ttusb_table);
static struct usb_driver ttusb_driver = {
- .name = "Technotrend/Hauppauge USB-Nova",
+ .name = "ttusb",
.probe = ttusb_probe,
.disconnect = ttusb_disconnect,
.id_table = ttusb_table,
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 505bdaff5a7..45c9a9a08e4 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1281,6 +1281,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
if (firmware_size < 60) {
printk("%s: firmware size too small for DSP code (%zu < 60).\n",
__FUNCTION__, firmware_size);
+ release_firmware(fw_entry);
return -1;
}
@@ -1294,6 +1295,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
printk("%s: crc32 check of DSP code failed (calculated "
"0x%08x != 0x%08x in file), file invalid.\n",
__FUNCTION__, crc32_csum, crc32_check);
+ release_firmware(fw_entry);
return -1;
}
memcpy(idstring, &firmware[36], 20);
@@ -1308,15 +1310,19 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
- if (result)
+ if (result) {
+ release_firmware(fw_entry);
return result;
+ }
trans_count = 0;
j = 0;
b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
- if (b == NULL)
+ if (b == NULL) {
+ release_firmware(fw_entry);
return -ENOMEM;
+ }
for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
size = firmware_size - i;
@@ -1345,6 +1351,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
+ release_firmware(fw_entry);
kfree(b);
return result;
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 1699cc9f6bb..725af3af5b2 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -157,7 +157,8 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
/* allocate memory for the internal state */
state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (state == NULL)
+ return NULL;
/* setup the state */
state->config = config;
@@ -167,10 +168,6 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
@@ -181,7 +178,8 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
/* allocate memory for the internal state */
state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (state == NULL)
+ return NULL;
/* setup the state */
state->config = config;
@@ -193,10 +191,6 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 1b70f8b0feb..f461750c764 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,19 +7,6 @@ menu "Video For Linux"
comment "Video Adapters"
-config TUNER_MULTI_I2C
- bool "Enable support for multiple I2C devices on Video Adapters (EXPERIMENTAL)"
- depends on VIDEO_DEV && EXPERIMENTAL
- ---help---
- Some video adapters have more than one tuner inside. This patch
- enables support for using more than one tuner. This is required
- for some cards to allow tunning both video and radio.
- It also improves I2C autodetection for these cards.
-
- Only few tuners currently is supporting this. More to come.
-
- It is safe to say 'Y' here even if your card has only one I2C tuner.
-
config VIDEO_BT848
tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C
@@ -344,6 +331,7 @@ config VIDEO_CX88_DVB
select DVB_MT352
select DVB_OR51132
select DVB_CX22702
+ select DVB_LGDT3302
---help---
This adds support for DVB/ATSC cards based on the
Connexant 2388x chip.
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 9a642c7de54..a070417e65e 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -138,25 +138,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
bt832_hexdump(i2c_client_s,buf);
-#if 0
- // Full 30/25 Frame rate
- printk("Full 30/25 Frame rate\n");
- buf[0]=BT832_VP_CONTROL0; // Reg.39
- buf[1]= 0x00;
- if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
- printk("bt832: i2c i/o error FFR: rc == %d (should be 2)\n",rc);
-
- bt832_hexdump(i2c_client_s,buf);
-#endif
-#if 1
// for testing (even works when no camera attached)
printk("bt832: *** Generate NTSC M Bars *****\n");
buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
-#endif
printk("Bt832: Camera Present: %s\n",
(buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 251092e7f19..2dbf5ec43ab 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-cards.c,v 1.49 2005/06/10 17:20:24 mchehab Exp $
+ $Id: bttv-cards.c,v 1.53 2005/07/05 17:37:35 nsh Exp $
bttv-cards.c
@@ -39,9 +39,6 @@
#include <asm/io.h>
#include "bttvp.h"
-#if 0 /* not working yet */
-#include "bt832.h"
-#endif
/* fwd decl */
static void boot_msp34xx(struct bttv *btv, int pin);
@@ -513,13 +510,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x01fe00,
.muxsel = { 2, 3, 1, 1},
-#if 0
- // old
- .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
-#else
// 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru>
.audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
-#endif
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
@@ -766,14 +758,9 @@ struct tvcard bttv_tvcards[] = {
.tuner = 0,
.svhs = 2,
.muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
-#if 0
- .gpiomask = 0xc33000,
- .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
-#else
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
.audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
-#endif
/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
gpio23 -- hef4052:nEnable (0x800000)
gpio12 -- hef4052:A1
@@ -1603,20 +1590,11 @@ struct tvcard bttv_tvcards[] = {
.video_inputs = 4,
.audio_inputs = 1,
.tuner = -1,
-#if 0 /* TODO ... */
- .svhs = OSPREY540_SVID_ANALOG,
- .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
- [OSPREY540_SVID_ANALOG] = 3, },
-#endif
.pll = PLL_28,
.tuner_type = -1,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
-#if 0 /* TODO ... */
- .muxsel_hook = osprey_540_muxsel,
- .picture_hook = osprey_540_set_picture,
-#endif
},{
/* ---- card 0x5C ---------------------------------- */
@@ -2546,21 +2524,12 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
btaor((2)<<5, ~(3<<5), BT848_IFORM);
gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
-#if 0
- /* svhs */
- /* wake chroma ADC */
- btand(~BT848_ADC_C_SLEEP, BT848_ADC);
- /* set to YC video */
- btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
- btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
-#else
/* composite */
/* set chroma ADC to sleep */
btor(BT848_ADC_C_SLEEP, BT848_ADC);
/* set to composite video */
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
-#endif
/* switch sync drive off */
gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
@@ -2813,10 +2782,18 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->tuner_type = tuner[btv->c.nr];
printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
if (btv->pinnacle_id != UNSET)
- bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+ bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
&btv->pinnacle_id);
- if (btv->tuner_type != UNSET)
- bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+ if (btv->tuner_type != UNSET) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.type = btv->tuner_type;
+ tun_setup.addr = ADDR_UNSET;
+
+ bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+
btv->svhs = bttv_tvcards[btv->c.type].svhs;
if (svhs[btv->c.nr] != UNSET)
btv->svhs = svhs[btv->c.nr];
@@ -3125,14 +3102,6 @@ static int tuner_0_table[] = {
TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
TUNER_PHILIPS_FM1216ME_MK3 };
-#if 0
-int tuner_0_fm_table[] = {
- PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL,
- PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
- PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
- PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
- PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
-#endif
static int tuner_1_table[] = {
TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
@@ -3218,36 +3187,6 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
static void __devinit boot_bt832(struct bttv *btv)
{
-#if 0 /* not working yet */
- int resetbit=0;
-
- switch (btv->c.type) {
- case BTTV_PXELVWPLTVPAK:
- resetbit = 0x400000;
- break;
- case BTTV_MODTEC_205:
- resetbit = 1<<9;
- break;
- default:
- BUG();
- }
-
- request_module("bt832");
- bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL);
-
- printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->c.nr,resetbit);
- gpio_write(0);
- gpio_inout(resetbit, resetbit);
- udelay(5);
- gpio_bits(resetbit, resetbit);
- udelay(5);
- gpio_bits(resetbit, 0);
- udelay(5);
-
- // bt832 on pixelview changes from i2c 0x8a to 0x88 after
- // being reset as above. So we must follow by this:
- bttv_call_i2c_clients(btv, BT832_REATTACH, NULL);
-#endif
}
/* ----------------------------------------------------------------------- */
@@ -3572,11 +3511,6 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq)
{
dprintk("tea5757_set_freq %d\n",freq);
tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
-#if 0
- /* breaks Miro PCTV */
- value = tea5757_read(btv);
- dprintk("bttv%d: tea5757 readback=0x%x\n",btv->c.nr,value);
-#endif
}
@@ -3656,13 +3590,8 @@ gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
{
unsigned int val, con;
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
if (btv->radio_user)
return;
-#else
- if (btv->radio)
- return;
-#endif
val = gpio_read();
if (set) {
@@ -3851,13 +3780,8 @@ pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
{
unsigned int val = 0;
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
if (btv->radio_user)
return;
-#else
- if (btv->radio)
- return;
-#endif
if (set) {
if (v->mode & VIDEO_SOUND_MONO) {
@@ -3888,13 +3812,8 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
{
unsigned int val = 0xffff;
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
if (btv->radio_user)
return;
-#else
- if (btv->radio)
- return;
-#endif
if (set) {
if (v->mode & VIDEO_SOUND_MONO) {
val = 0x0000;
@@ -4371,11 +4290,6 @@ void __devinit bttv_check_chipset(void)
latency = 0x0A;
#endif
-#if 0
- /* print which chipset we have */
- while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
- printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
-#endif
/* print warnings about any quirks found */
if (triton1)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 7d62b394c50..51a0f6d68e7 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
+ $Id: bttv-driver.c,v 1.42 2005/07/05 17:37:35 nsh Exp $
bttv - Bt848 frame grabber driver
@@ -35,6 +35,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -698,12 +699,10 @@ int locked_btres(struct bttv *btv, int bit)
static
void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
{
-#if 1 /* DEBUG */
if ((fh->resources & bits) != bits) {
/* trying to free ressources not allocated by us ... */
printk("bttv: BUG! (btres)\n");
}
-#endif
down(&btv->reslock);
fh->resources &= ~bits;
btv->resources &= ~bits;
@@ -943,11 +942,6 @@ audio_mux(struct bttv *btv, int mode)
i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
if (btv->opt_automute && !signal && !btv->radio_user)
mux = AUDIO_OFF;
-#if 0
- printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
- btv->c.nr, mode, btv->audio, signal ? "yes" : "no",
- mux, i2c_mux, in_interrupt() ? "yes" : "no");
-#endif
val = bttv_tvcards[btv->c.type].audiomux[mux];
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
@@ -994,11 +988,6 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
case BTTV_VOODOOTV_FM:
bttv_tda9880_setnorm(btv,norm);
break;
-#if 0
- case BTTV_OSPREY540:
- osprey_540_set_norm(btv,norm);
- break;
-#endif
}
return 0;
}
@@ -1849,7 +1838,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
if (unlikely(f->tuner != 0))
return -EINVAL;
- if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
+ if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
return -EINVAL;
down(&btv->lock);
btv->freq = f->frequency;
@@ -3865,7 +3854,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
btv->c.nr);
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
btv->c.nr);
return -EIO;
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index da448a5f9e9..234a8556376 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-i2c.c,v 1.21 2005/06/10 17:20:24 mchehab Exp $
+ $Id: bttv-i2c.c,v 1.25 2005/07/05 17:37:35 nsh Exp $
bttv-i2c.c -- all the i2c code is here
@@ -295,14 +295,26 @@ static int attach_inform(struct i2c_client *client)
{
struct bttv *btv = i2c_get_adapdata(client->adapter);
- if (btv->tuner_type != UNSET)
- bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+ if (bttv_debug)
+ printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
+ btv->c.nr,client->driver->name,client->addr,
+ i2c_clientname(client));
+ if (!client->driver->command)
+ return 0;
+
+ if (btv->tuner_type != UNSET) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.type = btv->tuner_type;
+ tun_setup.addr = ADDR_UNSET;
+
+ client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+
if (btv->pinnacle_id != UNSET)
- bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+ client->driver->command(client,AUDC_CONFIG_PINNACLE,
&btv->pinnacle_id);
- if (bttv_debug)
- printk("bttv%d: i2c attach [client=%s]\n",
- btv->c.nr, i2c_clientname(client));
return 0;
}
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index bdc5ce6c43b..9ed21fd190c 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -334,10 +334,6 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
}
vdelay = tvnorm->vdelay;
-#if 0 /* FIXME */
- if (vdelay < btv->vbi.lines*2)
- vdelay = btv->vbi.lines*2;
-#endif
xsf = (width*scaledtwidth)/swidth;
geo->hscale = ((totalwidth*4096UL)/xsf-4096);
@@ -776,13 +772,8 @@ bttv_overlay_risc(struct bttv *btv,
bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
break;
case V4L2_FIELD_INTERLACED:
-#if 0
- bttv_risc_overlay(btv, &buf->top, fmt, ov, 1, 0);
- bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
-#else
bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
-#endif
break;
default:
BUG();
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 91f8afeded8..4f39688f780 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -690,11 +690,9 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
int bitrate_mode = 1;
int bitrate = 7500000;
int bitrate_peak = 7500000;
-#if 1
bitrate_mode = BLACKBIRD_VIDEO_CBR;
bitrate = 4000*1024;
bitrate_peak = 4000*1024;
-#endif
/* assign stream type */
blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
@@ -810,9 +808,6 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
-#if 0 /* FIXME */
- set_scale(dev, 720, 480, V4L2_FIELD_INTERLACED);
-#endif
blackbird_codec_settings(dev);
msleep(1);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index b3fb04356b7..b0b47c3cde3 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-cards.c,v 1.76 2005/06/08 01:28:09 mchehab Exp $
+ * $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* card-specific stuff.
@@ -401,7 +401,7 @@ struct cx88_board cx88_boards[] = {
.dvb = 1,
},
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
- .name = "DVICO FusionHDTV DVB-T1",
+ .name = "DViCO FusionHDTV DVB-T1",
.tuner_type = TUNER_ABSENT, /* No analog tuner */
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -445,8 +445,8 @@ struct cx88_board cx88_boards[] = {
.gpio0 = 0x000007f8,
},
},
- [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
- .name = "DViCO - FusionHDTV 3 Gold",
+ [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
+ .name = "DViCO FusionHDTV 3 Gold-Q",
.tuner_type = TUNER_MICROTUNE_4042FI5,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -464,6 +464,9 @@ struct cx88_board cx88_boards[] = {
GPIO[3] selects RF input connector on tuner module
0 - RF connector labeled CABLE
1 - RF connector labeled ANT
+ GPIO[4] selects high RF for QAM256 mode
+ 0 - normal RF
+ 1 - high RF
*/
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -482,6 +485,7 @@ struct cx88_board cx88_boards[] = {
.vmux = 2,
.gpio0 = 0x0f00,
}},
+ .dvb = 1,
},
[CX88_BOARD_HAUPPAUGE_DVB_T1] = {
.name = "Hauppauge Nova-T DVB-T",
@@ -520,7 +524,7 @@ struct cx88_board cx88_boards[] = {
.blackbird = 1,
},
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
- .name = "DVICO FusionHDTV DVB-T Plus",
+ .name = "DViCO FusionHDTV DVB-T Plus",
.tuner_type = TUNER_ABSENT, /* No analog tuner */
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -700,21 +704,17 @@ struct cx88_board cx88_boards[] = {
},
},
[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
- .name = "DViCO - FusionHDTV 3 Gold-T",
+ .name = "DViCO FusionHDTV 3 Gold-T",
.tuner_type = TUNER_THOMSON_DTT7611,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */
- .input = {{
+ /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
+ .input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x0f0d,
},{
- .type = CX88_VMUX_CABLE,
- .vmux = 0,
- .gpio0 = 0x0f05,
- },{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0x0f00,
@@ -723,7 +723,36 @@ struct cx88_board cx88_boards[] = {
.vmux = 2,
.gpio0 = 0x0f00,
}},
+ .dvb = 1,
},
+ [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
+ .name = "ADS Tech Instant TV DVB-T PCI",
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x0700,
+ .gpio2 = 0x0101,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x0700,
+ .gpio2 = 0x0101,
+ }},
+ .dvb = 1,
+ },
+ [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
+ .name = "TerraTec Cinergy 1400 DVB-T",
+ .tuner_type = TUNER_ABSENT,
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ }},
+ .dvb = 1,
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -794,7 +823,7 @@ struct cx88_subid cx88_subids[] = {
},{
.subvendor = 0x18ac,
.subdevice = 0xd810,
- .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
+ .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
},{
.subvendor = 0x18ac,
.subdevice = 0xd820,
@@ -843,7 +872,15 @@ struct cx88_subid cx88_subids[] = {
.subvendor = 0x10fc,
.subdevice = 0xd035,
.card = CX88_BOARD_IODATA_GVBCTV7E,
- }
+ },{
+ .subvendor = 0x1421,
+ .subdevice = 0x0334,
+ .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
+ },{
+ .subvendor = 0x153b,
+ .subdevice = 0x1166,
+ .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
+ },
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index c046a23537d..5e868f5cd0c 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-core.c,v 1.28 2005/06/12 04:19:19 mchehab Exp $
+ * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* driver core
@@ -470,25 +470,6 @@ int cx88_risc_decode(u32 risc)
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
-#if 0 /* currently unused, but useful for debugging */
-void cx88_risc_disasm(struct cx88_core *core,
- struct btcx_riscmem *risc)
-{
- unsigned int i,j,n;
-
- printk("%s: risc disasm: %p [dma=0x%08lx]\n",
- core->name, risc->cpu, (unsigned long)risc->dma);
- for (i = 0; i < (risc->size >> 2); i += n) {
- printk("%s: %04d: ", core->name, i);
- n = cx88_risc_decode(risc->cpu[i]);
- for (j = 1; j < n; j++)
- printk("%s: %04d: 0x%08x [ arg #%d ]\n",
- core->name, i+j, risc->cpu[i+j], j);
- if (risc->cpu[i] == RISC_JUMP)
- break;
- }
-}
-#endif
void cx88_sram_channel_dump(struct cx88_core *core,
struct sram_channel *ch)
@@ -551,21 +532,6 @@ static char *cx88_pci_irqs[32] = {
"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
"i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
};
-char *cx88_vid_irqs[32] = {
- "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
- "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
- "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
- "y_sync", "u_sync", "v_sync", "vbi_sync",
- "opc_err", "par_err", "rip_err", "pci_abort",
-};
-char *cx88_mpeg_irqs[32] = {
- "ts_risci1", NULL, NULL, NULL,
- "ts_risci2", NULL, NULL, NULL,
- "ts_oflow", NULL, NULL, NULL,
- "ts_sync", NULL, NULL, NULL,
- "opc_err", "par_err", "rip_err", "pci_abort",
- "ts_err?",
-};
void cx88_print_irqbits(char *name, char *tag, char **strings,
u32 bits, u32 mask)
@@ -615,16 +581,11 @@ void cx88_wakeup(struct cx88_core *core,
break;
buf = list_entry(q->active.next,
struct cx88_buffer, vb.queue);
-#if 0
- if (buf->count > count)
- break;
-#else
/* count comes from the hw and is is 16bit wide --
* this trick handles wrap-arounds correctly for
* up to 32767 buffers in flight... */
if ((s16) (count - buf->count) < 0)
break;
-#endif
do_gettimeofday(&buf->vb.ts);
dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
count, buf->count);
@@ -952,12 +913,10 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
-#if 1
// FIXME: as-is from DScaler
dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
-#endif
// MO_SCONV_REG = adc clock / video dec clock * 2^17
tmp64 = adc_clock * (u64)(1 << 17);
@@ -1006,21 +965,7 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
set_tvaudio(core);
// tell i2c chips
-#ifdef V4L2_I2C_CLIENTS
cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
-#else
- {
- struct video_channel c;
- memset(&c,0,sizeof(c));
- c.channel = core->input;
- c.norm = VIDEO_MODE_PAL;
- if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
- c.norm = VIDEO_MODE_NTSC;
- if (norm->id & V4L2_STD_SECAM)
- c.norm = VIDEO_MODE_SECAM;
- cx88_call_i2c_clients(core,VIDIOCSCHAN,&c);
- }
-#endif
// done
return 0;
@@ -1230,8 +1175,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
/* ------------------------------------------------------------------ */
EXPORT_SYMBOL(cx88_print_ioctl);
-EXPORT_SYMBOL(cx88_vid_irqs);
-EXPORT_SYMBOL(cx88_mpeg_irqs);
EXPORT_SYMBOL(cx88_print_irqbits);
EXPORT_SYMBOL(cx88_core_irq);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 1a259c3966c..8db68f2d135 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-dvb.c,v 1.33 2005/06/12 04:19:19 mchehab Exp $
+ * $Id: cx88-dvb.c,v 1.41 2005/07/04 19:35:05 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines
@@ -30,20 +30,27 @@
#include <linux/file.h>
#include <linux/suspend.h>
-/* those two frontends need merging via linuxtv cvs ... */
-#define HAVE_CX22702 1
-#define HAVE_OR51132 1
+#define CONFIG_DVB_MT352 1
+#define CONFIG_DVB_CX22702 1
+#define CONFIG_DVB_OR51132 1
+#define CONFIG_DVB_LGDT3302 1
#include "cx88.h"
#include "dvb-pll.h"
-#include "mt352.h"
-#include "mt352_priv.h"
-#if HAVE_CX22702
+
+#if CONFIG_DVB_MT352
+# include "mt352.h"
+# include "mt352_priv.h"
+#endif
+#if CONFIG_DVB_CX22702
# include "cx22702.h"
#endif
-#if HAVE_OR51132
+#if CONFIG_DVB_OR51132
# include "or51132.h"
#endif
+#if CONFIG_DVB_LGDT3302
+# include "lgdt3302.h"
+#endif
MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -100,6 +107,7 @@ static struct videobuf_queue_ops dvb_qops = {
/* ------------------------------------------------------------------ */
+#if CONFIG_DVB_MT352
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
{
static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
@@ -167,8 +175,9 @@ static struct mt352_config dntv_live_dvbt_config = {
.demod_init = dntv_live_dvbt_demod_init,
.pll_set = mt352_pll_set,
};
+#endif
-#if HAVE_CX22702
+#if CONFIG_DVB_CX22702
static struct cx22702_config connexant_refboard_config = {
.demod_address = 0x43,
.pll_address = 0x60,
@@ -182,7 +191,7 @@ static struct cx22702_config hauppauge_novat_config = {
};
#endif
-#if HAVE_OR51132
+#if CONFIG_DVB_OR51132
static int or51132_set_ts_param(struct dvb_frontend* fe,
int is_punctured)
{
@@ -199,6 +208,32 @@ static struct or51132_config pchdtv_hd3000 = {
};
#endif
+#if CONFIG_DVB_LGDT3302
+static int lgdt3302_set_ts_param(struct dvb_frontend* fe, int is_punctured)
+{
+ struct cx8802_dev *dev= fe->dvb->priv;
+ if (is_punctured)
+ dev->ts_gen_cntrl |= 0x04;
+ else
+ dev->ts_gen_cntrl &= ~0x04;
+ return 0;
+}
+
+static struct lgdt3302_config fusionhdtv_3_gold_q = {
+ .demod_address = 0x0e,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_microtune_4042,
+ .set_ts_params = lgdt3302_set_ts_param,
+};
+
+static struct lgdt3302_config fusionhdtv_3_gold_t = {
+ .demod_address = 0x0e,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_thomson_dtt7611,
+ .set_ts_params = lgdt3302_set_ts_param,
+};
+#endif
+
static int dvb_register(struct cx8802_dev *dev)
{
/* init struct videobuf_dvb */
@@ -207,16 +242,18 @@ static int dvb_register(struct cx8802_dev *dev)
/* init frontend */
switch (dev->core->board) {
-#if HAVE_CX22702
+#if CONFIG_DVB_CX22702
case CX88_BOARD_HAUPPAUGE_DVB_T1:
dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
&dev->core->i2c_adap);
break;
+ case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
case CX88_BOARD_CONEXANT_DVB_T1:
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
&dev->core->i2c_adap);
break;
#endif
+#if CONFIG_DVB_MT352
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_lg_z201;
@@ -231,17 +268,49 @@ static int dvb_register(struct cx8802_dev *dev)
break;
case CX88_BOARD_KWORLD_DVB_T:
case CX88_BOARD_DNTV_LIVE_DVB_T:
+ case CX88_BOARD_ADSTECH_DVB_T_PCI:
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_unknown_1;
dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
&dev->core->i2c_adap);
break;
-#if HAVE_OR51132
+#endif
+#if CONFIG_DVB_OR51132
case CX88_BOARD_PCHDTV_HD3000:
dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
&dev->core->i2c_adap);
break;
#endif
+#if CONFIG_DVB_LGDT3302
+ case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
+ dev->ts_gen_cntrl = 0x08;
+ {
+ /* Do a hardware reset of chip before using it. */
+ struct cx88_core *core = dev->core;
+
+ cx_clear(MO_GP0_IO, 1);
+ mdelay(100);
+ cx_set(MO_GP0_IO, 9); // ANT connector too FIXME
+ mdelay(200);
+ dev->dvb.frontend = lgdt3302_attach(&fusionhdtv_3_gold_q,
+ &dev->core->i2c_adap);
+ }
+ break;
+ case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
+ dev->ts_gen_cntrl = 0x08;
+ {
+ /* Do a hardware reset of chip before using it. */
+ struct cx88_core *core = dev->core;
+
+ cx_clear(MO_GP0_IO, 1);
+ mdelay(100);
+ cx_set(MO_GP0_IO, 9); /* ANT connector too FIXME */
+ mdelay(200);
+ dev->dvb.frontend = lgdt3302_attach(&fusionhdtv_3_gold_t,
+ &dev->core->i2c_adap);
+ }
+ break;
+#endif
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index e20adefcfc6..8403c4e9505 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,5 @@
/*
- $Id: cx88-i2c.c,v 1.23 2005/06/12 04:19:19 mchehab Exp $
+ $Id: cx88-i2c.c,v 1.28 2005/07/05 17:37:35 nsh Exp $
cx88-i2c.c -- all the i2c code is here
@@ -91,25 +91,32 @@ static int cx8800_bit_getsda(void *data)
static int attach_inform(struct i2c_client *client)
{
- struct tuner_addr tun_addr;
+ struct tuner_setup tun_setup;
struct cx88_core *core = i2c_get_adapdata(client->adapter);
- dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
- client->addr, i2c_clientname(client));
+ dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
+ client->driver->name,client->addr,i2c_clientname(client));
if (!client->driver->command)
return 0;
if (core->radio_type != UNSET) {
- tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
- tun_addr.type = core->radio_type;
- tun_addr.addr = core->radio_addr;
- client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
+ if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
+ tun_setup.mode_mask = T_RADIO;
+ tun_setup.type = core->radio_type;
+ tun_setup.addr = core->radio_addr;
+
+ client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
}
if (core->tuner_type != UNSET) {
- tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
- tun_addr.type = core->tuner_type;
- tun_addr.addr = core->tuner_addr;
- client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
+ if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = core->tuner_type;
+ tun_setup.addr = core->tuner_addr;
+
+ client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
}
if (core->tda9887_conf)
@@ -157,6 +164,7 @@ static struct i2c_client cx8800_i2c_client_template = {
};
static char *i2c_devs[128] = {
+ [ 0x1c >> 1 ] = "lgdt3302",
[ 0x86 >> 1 ] = "tda9887/cx22702",
[ 0xa0 >> 1 ] = "eeprom",
[ 0xc0 >> 1 ] = "tuner (analog)",
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index dc0dcf249aa..21488779819 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-input.c,v 1.11 2005/05/22 20:57:56 nsh Exp $
+ * $Id: cx88-input.c,v 1.15 2005/07/07 13:58:38 mchehab Exp $
*
* Device driver for GPIO attached remote control interfaces
* on Conexant 2388x based TV/DVB cards.
@@ -38,119 +38,206 @@
/* DigitalNow DNTV Live DVB-T Remote */
static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
- [ 0x00 ] = KEY_ESC, // 'go up a level?'
- [ 0x01 ] = KEY_KP1, // '1'
- [ 0x02 ] = KEY_KP2, // '2'
- [ 0x03 ] = KEY_KP3, // '3'
- [ 0x04 ] = KEY_KP4, // '4'
- [ 0x05 ] = KEY_KP5, // '5'
- [ 0x06 ] = KEY_KP6, // '6'
- [ 0x07 ] = KEY_KP7, // '7'
- [ 0x08 ] = KEY_KP8, // '8'
- [ 0x09 ] = KEY_KP9, // '9'
- [ 0x0a ] = KEY_KP0, // '0'
- [ 0x0b ] = KEY_TUNER, // 'tv/fm'
- [ 0x0c ] = KEY_SEARCH, // 'scan'
- [ 0x0d ] = KEY_STOP, // 'stop'
- [ 0x0e ] = KEY_PAUSE, // 'pause'
- [ 0x0f ] = KEY_LIST, // 'source'
-
- [ 0x10 ] = KEY_MUTE, // 'mute'
- [ 0x11 ] = KEY_REWIND, // 'backward <<'
- [ 0x12 ] = KEY_POWER, // 'power'
- [ 0x13 ] = KEY_S, // 'snap'
- [ 0x14 ] = KEY_AUDIO, // 'stereo'
- [ 0x15 ] = KEY_CLEAR, // 'reset'
- [ 0x16 ] = KEY_PLAY, // 'play'
- [ 0x17 ] = KEY_ENTER, // 'enter'
- [ 0x18 ] = KEY_ZOOM, // 'full screen'
- [ 0x19 ] = KEY_FASTFORWARD, // 'forward >>'
- [ 0x1a ] = KEY_CHANNELUP, // 'channel +'
- [ 0x1b ] = KEY_VOLUMEUP, // 'volume +'
- [ 0x1c ] = KEY_INFO, // 'preview'
- [ 0x1d ] = KEY_RECORD, // 'record'
- [ 0x1e ] = KEY_CHANNELDOWN, // 'channel -'
- [ 0x1f ] = KEY_VOLUMEDOWN, // 'volume -'
+ [0x00] = KEY_ESC, /* 'go up a level?' */
+ /* Keys 0 to 9 */
+ [0x0a] = KEY_KP0,
+ [0x01] = KEY_KP1,
+ [0x02] = KEY_KP2,
+ [0x03] = KEY_KP3,
+ [0x04] = KEY_KP4,
+ [0x05] = KEY_KP5,
+ [0x06] = KEY_KP6,
+ [0x07] = KEY_KP7,
+ [0x08] = KEY_KP8,
+ [0x09] = KEY_KP9,
+
+ [0x0b] = KEY_TUNER, /* tv/fm */
+ [0x0c] = KEY_SEARCH, /* scan */
+ [0x0d] = KEY_STOP,
+ [0x0e] = KEY_PAUSE,
+ [0x0f] = KEY_LIST, /* source */
+
+ [0x10] = KEY_MUTE,
+ [0x11] = KEY_REWIND, /* backward << */
+ [0x12] = KEY_POWER,
+ [0x13] = KEY_S, /* snap */
+ [0x14] = KEY_AUDIO, /* stereo */
+ [0x15] = KEY_CLEAR, /* reset */
+ [0x16] = KEY_PLAY,
+ [0x17] = KEY_ENTER,
+ [0x18] = KEY_ZOOM, /* full screen */
+ [0x19] = KEY_FASTFORWARD, /* forward >> */
+ [0x1a] = KEY_CHANNELUP,
+ [0x1b] = KEY_VOLUMEUP,
+ [0x1c] = KEY_INFO, /* preview */
+ [0x1d] = KEY_RECORD, /* record */
+ [0x1e] = KEY_CHANNELDOWN,
+ [0x1f] = KEY_VOLUMEDOWN,
};
/* ---------------------------------------------------------------------- */
/* IO-DATA BCTV7E Remote */
static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
- [ 0x40 ] = KEY_TV, // TV
- [ 0x20 ] = KEY_RADIO, // FM
- [ 0x60 ] = KEY_EPG, // EPG
- [ 0x00 ] = KEY_POWER, // power
-
- [ 0x50 ] = KEY_KP1, // 1
- [ 0x30 ] = KEY_KP2, // 2
- [ 0x70 ] = KEY_KP3, // 3
- [ 0x10 ] = KEY_L, // Live
-
- [ 0x48 ] = KEY_KP4, // 4
- [ 0x28 ] = KEY_KP5, // 5
- [ 0x68 ] = KEY_KP6, // 6
- [ 0x08 ] = KEY_T, // Time Shift
-
- [ 0x58 ] = KEY_KP7, // 7
- [ 0x38 ] = KEY_KP8, // 8
- [ 0x78 ] = KEY_KP9, // 9
- [ 0x18 ] = KEY_PLAYPAUSE, // Play
-
- [ 0x44 ] = KEY_KP0, // 10
- [ 0x24 ] = KEY_ENTER, // 11
- [ 0x64 ] = KEY_ESC, // 12
- [ 0x04 ] = KEY_M, // Multi
-
- [ 0x54 ] = KEY_VIDEO, // VIDEO
- [ 0x34 ] = KEY_CHANNELUP, // channel +
- [ 0x74 ] = KEY_VOLUMEUP, // volume +
- [ 0x14 ] = KEY_MUTE, // Mute
-
- [ 0x4c ] = KEY_S, // SVIDEO
- [ 0x2c ] = KEY_CHANNELDOWN, // channel -
- [ 0x6c ] = KEY_VOLUMEDOWN, // volume -
- [ 0x0c ] = KEY_ZOOM, // Zoom
-
- [ 0x5c ] = KEY_PAUSE, // pause
- [ 0x3c ] = KEY_C, // || (red)
- [ 0x7c ] = KEY_RECORD, // recording
- [ 0x1c ] = KEY_STOP, // stop
-
- [ 0x41 ] = KEY_REWIND, // backward <<
- [ 0x21 ] = KEY_PLAY, // play
- [ 0x61 ] = KEY_FASTFORWARD, // forward >>
- [ 0x01 ] = KEY_NEXT, // skip >|
+ [0x40] = KEY_TV,
+ [0x20] = KEY_RADIO, /* FM */
+ [0x60] = KEY_EPG,
+ [0x00] = KEY_POWER,
+
+ /* Keys 0 to 9 */
+ [0x44] = KEY_KP0, /* 10 */
+ [0x50] = KEY_KP1,
+ [0x30] = KEY_KP2,
+ [0x70] = KEY_KP3,
+ [0x48] = KEY_KP4,
+ [0x28] = KEY_KP5,
+ [0x68] = KEY_KP6,
+ [0x58] = KEY_KP7,
+ [0x38] = KEY_KP8,
+ [0x78] = KEY_KP9,
+
+ [0x10] = KEY_L, /* Live */
+ [0x08] = KEY_T, /* Time Shift */
+
+ [0x18] = KEY_PLAYPAUSE, /* Play */
+
+ [0x24] = KEY_ENTER, /* 11 */
+ [0x64] = KEY_ESC, /* 12 */
+ [0x04] = KEY_M, /* Multi */
+
+ [0x54] = KEY_VIDEO,
+ [0x34] = KEY_CHANNELUP,
+ [0x74] = KEY_VOLUMEUP,
+ [0x14] = KEY_MUTE,
+
+ [0x4c] = KEY_S, /* SVIDEO */
+ [0x2c] = KEY_CHANNELDOWN,
+ [0x6c] = KEY_VOLUMEDOWN,
+ [0x0c] = KEY_ZOOM,
+
+ [0x5c] = KEY_PAUSE,
+ [0x3c] = KEY_C, /* || (red) */
+ [0x7c] = KEY_RECORD, /* recording */
+ [0x1c] = KEY_STOP,
+
+ [0x41] = KEY_REWIND, /* backward << */
+ [0x21] = KEY_PLAY,
+ [0x61] = KEY_FASTFORWARD, /* forward >> */
+ [0x01] = KEY_NEXT, /* skip >| */
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* ADS Tech Instant TV DVB-T PCI Remote */
+static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [0x4d] = KEY_0,
+ [0x57] = KEY_1,
+ [0x4f] = KEY_2,
+ [0x53] = KEY_3,
+ [0x56] = KEY_4,
+ [0x4e] = KEY_5,
+ [0x5e] = KEY_6,
+ [0x54] = KEY_7,
+ [0x4c] = KEY_8,
+ [0x5c] = KEY_9,
+
+ [0x5b] = KEY_POWER,
+ [0x5f] = KEY_MUTE,
+ [0x55] = KEY_GOTO,
+ [0x5d] = KEY_SEARCH,
+ [0x17] = KEY_EPG, /* Guide */
+ [0x1f] = KEY_MENU,
+ [0x0f] = KEY_UP,
+ [0x46] = KEY_DOWN,
+ [0x16] = KEY_LEFT,
+ [0x1e] = KEY_RIGHT,
+ [0x0e] = KEY_SELECT, /* Enter */
+ [0x5a] = KEY_INFO,
+ [0x52] = KEY_EXIT,
+ [0x59] = KEY_PREVIOUS,
+ [0x51] = KEY_NEXT,
+ [0x58] = KEY_REWIND,
+ [0x50] = KEY_FORWARD,
+ [0x44] = KEY_PLAYPAUSE,
+ [0x07] = KEY_STOP,
+ [0x1b] = KEY_RECORD,
+ [0x13] = KEY_TUNER, /* Live */
+ [0x0a] = KEY_A,
+ [0x12] = KEY_B,
+ [0x03] = KEY_PROG1, /* 1 */
+ [0x01] = KEY_PROG2, /* 2 */
+ [0x00] = KEY_PROG3, /* 3 */
+ [0x06] = KEY_DVD,
+ [0x48] = KEY_AUX, /* Photo */
+ [0x40] = KEY_VIDEO,
+ [0x19] = KEY_AUDIO, /* Music */
+ [0x0b] = KEY_CHANNELUP,
+ [0x08] = KEY_CHANNELDOWN,
+ [0x15] = KEY_VOLUMEUP,
+ [0x1c] = KEY_VOLUMEDOWN,
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* MSI TV@nywhere remote */
+static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
+ /* Keys 0 to 9 */
+ [0x00] = KEY_0,
+ [0x01] = KEY_1,
+ [0x02] = KEY_2,
+ [0x03] = KEY_3,
+ [0x04] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+ [0x07] = KEY_7,
+ [0x08] = KEY_8,
+ [0x09] = KEY_9,
+
+ [0x0c] = KEY_MUTE,
+ [0x0f] = KEY_SCREEN, /* Full Screen */
+ [0x10] = KEY_F, /* Funtion */
+ [0x11] = KEY_T, /* Time shift */
+ [0x12] = KEY_POWER,
+ [0x13] = KEY_MEDIA, /* MTS */
+ [0x14] = KEY_SLOW,
+ [0x16] = KEY_REWIND, /* backward << */
+ [0x17] = KEY_ENTER, /* Return */
+ [0x18] = KEY_FASTFORWARD, /* forward >> */
+ [0x1a] = KEY_CHANNELUP,
+ [0x1b] = KEY_VOLUMEUP,
+ [0x1e] = KEY_CHANNELDOWN,
+ [0x1f] = KEY_VOLUMEDOWN,
};
/* ---------------------------------------------------------------------- */
struct cx88_IR {
- struct cx88_core *core;
- struct input_dev input;
- struct ir_input_state ir;
- char name[32];
- char phys[32];
+ struct cx88_core *core;
+ struct input_dev input;
+ struct ir_input_state ir;
+ char name[32];
+ char phys[32];
/* sample from gpio pin 16 */
- int sampling;
- u32 samples[16];
- int scount;
- unsigned long release;
+ int sampling;
+ u32 samples[16];
+ int scount;
+ unsigned long release;
/* poll external decoder */
- int polling;
- struct work_struct work;
- struct timer_list timer;
- u32 gpio_addr;
- u32 last_gpio;
- u32 mask_keycode;
- u32 mask_keydown;
- u32 mask_keyup;
+ int polling;
+ struct work_struct work;
+ struct timer_list timer;
+ u32 gpio_addr;
+ u32 last_gpio;
+ u32 mask_keycode;
+ u32 mask_keydown;
+ u32 mask_keyup;
};
static int ir_debug = 0;
-module_param(ir_debug, int, 0644); /* debug level [IR] */
+module_param(ir_debug, int, 0644); /* debug level [IR] */
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define ir_dprintk(fmt, arg...) if (ir_debug) \
@@ -174,37 +261,37 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
/* extract data */
data = ir_extract_bits(gpio, ir->mask_keycode);
ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
- gpio, data,
- ir->polling ? "poll" : "irq",
- (gpio & ir->mask_keydown) ? " down" : "",
- (gpio & ir->mask_keyup) ? " up" : "");
+ gpio, data,
+ ir->polling ? "poll" : "irq",
+ (gpio & ir->mask_keydown) ? " down" : "",
+ (gpio & ir->mask_keyup) ? " up" : "");
if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown) {
- ir_input_keydown(&ir->input,&ir->ir,data,data);
+ ir_input_keydown(&ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_nokey(&ir->input, &ir->ir);
}
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup)) {
- ir_input_keydown(&ir->input,&ir->ir,data,data);
+ ir_input_keydown(&ir->input, &ir->ir, data, data);
} else {
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_nokey(&ir->input, &ir->ir);
}
} else {
/* can't distinguish keydown/up :-/ */
- ir_input_keydown(&ir->input,&ir->ir,data,data);
- ir_input_nokey(&ir->input,&ir->ir);
+ ir_input_keydown(&ir->input, &ir->ir, data, data);
+ ir_input_nokey(&ir->input, &ir->ir);
}
}
static void ir_timer(unsigned long data)
{
- struct cx88_IR *ir = (struct cx88_IR*)data;
+ struct cx88_IR *ir = (struct cx88_IR *)data;
schedule_work(&ir->work);
}
@@ -227,47 +314,61 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
IR_KEYTAB_TYPE *ir_codes = NULL;
int ir_type = IR_TYPE_OTHER;
- ir = kmalloc(sizeof(*ir),GFP_KERNEL);
+ ir = kmalloc(sizeof(*ir), GFP_KERNEL);
if (NULL == ir)
return -ENOMEM;
- memset(ir,0,sizeof(*ir));
+ memset(ir, 0, sizeof(*ir));
/* detect & configure */
switch (core->board) {
case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_KWORLD_DVB_T:
- ir_codes = ir_codes_dntv_live_dvb_t;
- ir->gpio_addr = MO_GP1_IO;
+ ir_codes = ir_codes_dntv_live_dvb_t;
+ ir->gpio_addr = MO_GP1_IO;
ir->mask_keycode = 0x1f;
- ir->mask_keyup = 0x60;
- ir->polling = 50; // ms
+ ir->mask_keyup = 0x60;
+ ir->polling = 50; /* ms */
break;
case CX88_BOARD_HAUPPAUGE:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- ir_codes = ir_codes_hauppauge_new;
- ir_type = IR_TYPE_RC5;
- ir->sampling = 1;
+ ir_codes = ir_codes_hauppauge_new;
+ ir_type = IR_TYPE_RC5;
+ ir->sampling = 1;
break;
case CX88_BOARD_WINFAST2000XP_EXPERT:
- ir_codes = ir_codes_winfast;
- ir->gpio_addr = MO_GP0_IO;
+ ir_codes = ir_codes_winfast;
+ ir->gpio_addr = MO_GP0_IO;
ir->mask_keycode = 0x8f8;
- ir->mask_keyup = 0x100;
- ir->polling = 1; // ms
+ ir->mask_keyup = 0x100;
+ ir->polling = 1; /* ms */
break;
case CX88_BOARD_IODATA_GVBCTV7E:
- ir_codes = ir_codes_iodata_bctv7e;
- ir->gpio_addr = MO_GP0_IO;
+ ir_codes = ir_codes_iodata_bctv7e;
+ ir->gpio_addr = MO_GP0_IO;
ir->mask_keycode = 0xfd;
ir->mask_keydown = 0x02;
- ir->polling = 5; // ms
+ ir->polling = 5; /* ms */
break;
case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
- ir_codes = ir_codes_pixelview;
- ir->gpio_addr = MO_GP1_IO;
+ ir_codes = ir_codes_pixelview;
+ ir->gpio_addr = MO_GP1_IO;
+ ir->mask_keycode = 0x1f;
+ ir->mask_keyup = 0x80;
+ ir->polling = 1; /* ms */
+ break;
+ case CX88_BOARD_ADSTECH_DVB_T_PCI:
+ ir_codes = ir_codes_adstech_dvb_t_pci;
+ ir->gpio_addr = MO_GP1_IO;
+ ir->mask_keycode = 0xbf;
+ ir->mask_keyup = 0x40;
+ ir->polling = 50; /* ms */
+ break;
+ case CX88_BOARD_MSI_TVANYWHERE_MASTER:
+ ir_codes = ir_codes_msi_tvanywhere;
+ ir->gpio_addr = MO_GP1_IO;
ir->mask_keycode = 0x1f;
- ir->mask_keyup = 0x80;
- ir->polling = 1; // ms
+ ir->mask_keyup = 0x40;
+ ir->polling = 1; /* ms */
break;
}
@@ -279,8 +380,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
/* init input device */
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)",
cx88_boards[core->board].name);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
- pci_name(pci));
+ snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
ir->input.name = ir->name;
@@ -288,10 +388,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir->input.id.bustype = BUS_PCI;
ir->input.id.version = 1;
if (pci->subsystem_vendor) {
- ir->input.id.vendor = pci->subsystem_vendor;
+ ir->input.id.vendor = pci->subsystem_vendor;
ir->input.id.product = pci->subsystem_device;
} else {
- ir->input.id.vendor = pci->vendor;
+ ir->input.id.vendor = pci->vendor;
ir->input.id.product = pci->device;
}
@@ -303,13 +403,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
INIT_WORK(&ir->work, cx88_ir_work, ir);
init_timer(&ir->timer);
ir->timer.function = ir_timer;
- ir->timer.data = (unsigned long)ir;
+ ir->timer.data = (unsigned long)ir;
schedule_work(&ir->work);
}
if (ir->sampling) {
- core->pci_irqmask |= (1<<18); // IR_SMP_INT
- cx_write(MO_DDS_IO, 0xa80a80); // 4 kHz sample rate
- cx_write(MO_DDSCFG_IO, 0x5); // enable
+ core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */
+ cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */
+ cx_write(MO_DDSCFG_IO, 0x5); /* enable */
}
/* all done */
@@ -345,7 +445,7 @@ int cx88_ir_fini(struct cx88_core *core)
void cx88_ir_irq(struct cx88_core *core)
{
struct cx88_IR *ir = core->ir;
- u32 samples,rc5;
+ u32 samples, rc5;
int i;
if (NULL == ir)
@@ -354,7 +454,7 @@ void cx88_ir_irq(struct cx88_core *core)
return;
samples = cx_read(MO_SAMPLE_IO);
- if (0 != samples && 0xffffffff != samples) {
+ if (0 != samples && 0xffffffff != samples) {
/* record sample data */
if (ir->scount < ARRAY_SIZE(ir->samples))
ir->samples[ir->scount++] = samples;
@@ -362,8 +462,8 @@ void cx88_ir_irq(struct cx88_core *core)
}
if (!ir->scount) {
/* nothing to sample */
- if (ir->ir.keypressed && time_after(jiffies,ir->release))
- ir_input_nokey(&ir->input,&ir->ir);
+ if (ir->ir.keypressed && time_after(jiffies, ir->release))
+ ir_input_nokey(&ir->input, &ir->ir);
return;
}
@@ -373,14 +473,14 @@ void cx88_ir_irq(struct cx88_core *core)
for (i = 0; i < ir->scount; i++)
ir->samples[i] = ~ir->samples[i];
if (ir_debug)
- ir_dump_samples(ir->samples,ir->scount);
+ ir_dump_samples(ir->samples, ir->scount);
/* decode it */
switch (core->board) {
case CX88_BOARD_HAUPPAUGE:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- rc5 = ir_decode_biphase(ir->samples,ir->scount,5,7);
- ir_dprintk("biphase decoded: %x\n",rc5);
+ rc5 = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
+ ir_dprintk("biphase decoded: %x\n", rc5);
if ((rc5 & 0xfffff000) != 0x3000)
break;
ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 9ade2ae91e9..fe2767c0ff9 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $
+ * $Id: cx88-mpeg.c,v 1.31 2005/07/07 14:17:47 mchehab Exp $
*
* Support for the mpeg transport stream transfers
* PCI function #2 of the cx2388x.
@@ -64,17 +64,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
/* write TS length to chip */
cx_write(MO_TS_LNGTH, buf->vb.width);
-#if 1
/* FIXME: this needs a review.
* also: move to cx88-blackbird + cx88-dvb source files? */
if (cx88_boards[core->board].dvb) {
/* negedge driven & software reset */
- cx_write(TS_GEN_CNTRL, 0x40);
+ cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
udelay(100);
cx_write(MO_PINMUX_IO, 0x00);
- cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00);
- cx_write(TS_SOP_STAT,0x00);
+ cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
+ if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) ||
+ (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) {
+ cx_write(TS_SOP_STAT, 1<<13);
+ } else {
+ cx_write(TS_SOP_STAT, 0x00);
+ }
cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
udelay(100);
}
@@ -93,7 +97,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
udelay(100);
}
-#endif
/* reset counter */
cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
@@ -265,6 +268,15 @@ static void cx8802_timeout(unsigned long data)
do_cancel_buffers(dev,"timeout",1);
}
+static char *cx88_mpeg_irqs[32] = {
+ "ts_risci1", NULL, NULL, NULL,
+ "ts_risci2", NULL, NULL, NULL,
+ "ts_oflow", NULL, NULL, NULL,
+ "ts_sync", NULL, NULL, NULL,
+ "opc_err", "par_err", "rip_err", "pci_abort",
+ "ts_err?",
+};
+
static void cx8802_mpeg_irq(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
@@ -277,10 +289,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
return;
cx_write(MO_TS_INTSTAT, status);
-#if 0
- cx88_print_irqbits(core->name, "irq mpeg ",
- cx88_mpeg_irqs, status, mask);
-#endif
+
if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq mpeg ",
cx88_mpeg_irqs, status, mask);
@@ -436,10 +445,8 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
}
spin_unlock(&dev->slock);
-#if 1
/* FIXME -- shutdown device */
cx88_shutdown(dev->core);
-#endif
pci_save_state(pci_dev);
if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -461,10 +468,8 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
-#if 1
/* FIXME: re-initialize hardware */
cx88_reset(dev->core);
-#endif
/* restart video+vbi capture */
spin_lock(&dev->slock);
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 63ad33f5818..37f82662d26 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,5 @@
/*
- $Id: cx88-reg.h,v 1.7 2005/06/03 13:31:51 mchehab Exp $
+ $Id: cx88-reg.h,v 1.8 2005/07/07 13:58:38 mchehab Exp $
cx88x-hw.h - CX2388x register offsets
@@ -604,20 +604,11 @@
#define EN_I2SIN_STR2DAC 0x00004000
#define EN_I2SIN_ENABLE 0x00008000
-#if 0
-/* old */
-#define EN_DMTRX_SUMDIFF 0x00000800
-#define EN_DMTRX_SUMR 0x00000880
-#define EN_DMTRX_LR 0x00000900
-#define EN_DMTRX_MONO 0x00000980
-#else
-/* dscaler cvs */
#define EN_DMTRX_SUMDIFF (0 << 7)
#define EN_DMTRX_SUMR (1 << 7)
#define EN_DMTRX_LR (2 << 7)
#define EN_DMTRX_MONO (3 << 7)
#define EN_DMTRX_BYPASS (1 << 11)
-#endif
// Video
#define VID_CAPTURE_CONTROL 0x310180
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 46d78b1dc9b..91207f10bae 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,5 @@
/*
- $Id: cx88-tvaudio.c,v 1.36 2005/06/05 05:53:45 mchehab Exp $
+ $Id: cx88-tvaudio.c,v 1.37 2005/07/07 13:58:38 mchehab Exp $
cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
@@ -278,80 +278,6 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
set_audio_finish(core);
}
-#if 0
-static void set_audio_standard_NICAM(struct cx88_core *core)
-{
- static const struct rlist nicam_common[] = {
- /* from dscaler */
- { AUD_RATE_ADJ1, 0x00000010 },
- { AUD_RATE_ADJ2, 0x00000040 },
- { AUD_RATE_ADJ3, 0x00000100 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00001000 },
- // { AUD_DMD_RA_DDS, 0x00c0d5ce },
-
- // Deemphasis 1:
- { AUD_DEEMPHGAIN_R, 0x000023c2 },
- { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
- { AUD_DEEMPHNUMER2_R, 0x0003023e },
- { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
-
-#if 0
- // Deemphasis 2: (other tv norm?)
- { AUD_DEEMPHGAIN_R, 0x0000c600 },
- { AUD_DEEMPHNUMER1_R, 0x00066738 },
- { AUD_DEEMPHNUMER2_R, 0x00066739 },
- { AUD_DEEMPHDENOM1_R, 0x0001e88c },
- { AUD_DEEMPHDENOM2_R, 0x0001e88c },
-#endif
-
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_ERRLOGPERIOD_R, 0x00000fff },
- { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
- { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
-
- // setup QAM registers
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
- { AUD_QAM_MODE, 0x05 },
-
- { /* end of list */ },
- };
- static const struct rlist nicam_pal_i[] = {
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_PHACC_FREQ_8MSB, 0x3a },
- { AUD_PHACC_FREQ_8LSB, 0x93 },
-
- { /* end of list */ },
- };
- static const struct rlist nicam_default[] = {
- { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
- { AUD_PHACC_FREQ_8MSB, 0x34 },
- { AUD_PHACC_FREQ_8LSB, 0x4c },
-
- { /* end of list */ },
- };
-
- set_audio_start(core, 0x0010,
- EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
- set_audio_registers(core, nicam_common);
- switch (core->tvaudio) {
- case WW_NICAM_I:
- dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
- set_audio_registers(core, nicam_pal_i);
- break;
- case WW_NICAM_BGDKL:
- dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__);
- set_audio_registers(core, nicam_default);
- break;
- };
- set_audio_finish(core);
-}
-#endif
static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
{
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index e4ca7350df1..c44a079d08c 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-video.c,v 1.63 2005/06/12 04:19:19 mchehab Exp $
+ * $Id: cx88-video.c,v 1.79 2005/07/07 14:17:47 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* video4linux video interface
@@ -86,13 +86,6 @@ static struct cx88_tvnorm tvnorms[] = {
.id = V4L2_STD_NTSC_M_JP,
.cxiformat = VideoFormatNTSCJapan,
.cxoformat = 0x181f0008,
-#if 0
- },{
- .name = "NTSC-4.43",
- .id = FIXME,
- .cxiformat = VideoFormatNTSC443,
- .cxoformat = 0x181f0008,
-#endif
},{
.name = "PAL-BG",
.id = V4L2_STD_PAL_BG,
@@ -248,6 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},
+ .off = 0,
.reg = MO_CONTR_BRIGHT,
.mask = 0xff00,
.shift = 8,
@@ -261,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},
- .off = 0,
+ .off = 128,
.reg = MO_HUE,
.mask = 0x00ff,
.shift = 0,
@@ -674,231 +668,6 @@ static struct videobuf_queue_ops cx8800_video_qops = {
/* ------------------------------------------------------------------ */
-#if 0 /* overlay support not finished yet */
-static u32* ov_risc_field(struct cx8800_dev *dev, struct cx8800_fh *fh,
- u32 *rp, struct btcx_skiplist *skips,
- u32 sync_line, int skip_even, int skip_odd)
-{
- int line,maxy,start,end,skip,nskips;
- u32 ri,ra;
- u32 addr;
-
- /* sync instruction */
- *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
- addr = (unsigned long)dev->fbuf.base;
- addr += dev->fbuf.fmt.bytesperline * fh->win.w.top;
- addr += (fh->fmt->depth >> 3) * fh->win.w.left;
-
- /* scan lines */
- for (maxy = -1, line = 0; line < fh->win.w.height;
- line++, addr += dev->fbuf.fmt.bytesperline) {
- if ((line%2) == 0 && skip_even)
- continue;
- if ((line%2) == 1 && skip_odd)
- continue;
-
- /* calculate clipping */
- if (line > maxy)
- btcx_calc_skips(line, fh->win.w.width, &maxy,
- skips, &nskips, fh->clips, fh->nclips);
-
- /* write out risc code */
- for (start = 0, skip = 0; start < fh->win.w.width; start = end) {
- if (skip >= nskips) {
- ri = RISC_WRITE;
- end = fh->win.w.width;
- } else if (start < skips[skip].start) {
- ri = RISC_WRITE;
- end = skips[skip].start;
- } else {
- ri = RISC_SKIP;
- end = skips[skip].end;
- skip++;
- }
- if (RISC_WRITE == ri)
- ra = addr + (fh->fmt->depth>>3)*start;
- else
- ra = 0;
-
- if (0 == start)
- ri |= RISC_SOL;
- if (fh->win.w.width == end)
- ri |= RISC_EOL;
- ri |= (fh->fmt->depth>>3) * (end-start);
-
- *(rp++)=cpu_to_le32(ri);
- if (0 != ra)
- *(rp++)=cpu_to_le32(ra);
- }
- }
- kfree(skips);
- return rp;
-}
-
-static int ov_risc_frame(struct cx8800_dev *dev, struct cx8800_fh *fh,
- struct cx88_buffer *buf)
-{
- struct btcx_skiplist *skips;
- u32 instructions,fields;
- u32 *rp;
- int rc;
-
- /* skip list for window clipping */
- if (NULL == (skips = kmalloc(sizeof(*skips) * fh->nclips,GFP_KERNEL)))
- return -ENOMEM;
-
- fields = 0;
- if (V4L2_FIELD_HAS_TOP(fh->win.field))
- fields++;
- if (V4L2_FIELD_HAS_BOTTOM(fh->win.field))
- fields++;
-
- /* estimate risc mem: worst case is (clip+1) * lines instructions
- + syncs + jump (all 2 dwords) */
- instructions = (fh->nclips+1) * fh->win.w.height;
- instructions += 3 + 4;
- if ((rc = btcx_riscmem_alloc(dev->pci,&buf->risc,instructions*8)) < 0) {
- kfree(skips);
- return rc;
- }
-
- /* write risc instructions */
- rp = buf->risc.cpu;
- switch (fh->win.field) {
- case V4L2_FIELD_TOP:
- rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 0);
- break;
- case V4L2_FIELD_BOTTOM:
- rp = ov_risc_field(dev, fh, rp, skips, 0x200, 0, 0);
- break;
- case V4L2_FIELD_INTERLACED:
- rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 1);
- rp = ov_risc_field(dev, fh, rp, skips, 0x200, 1, 0);
- break;
- default:
- BUG();
- }
-
- /* save pointer to jmp instruction address */
- buf->risc.jmp = rp;
- kfree(skips);
- return 0;
-}
-
-static int verify_window(struct cx8800_dev *dev, struct v4l2_window *win)
-{
- enum v4l2_field field;
- int maxw, maxh;
-
- if (NULL == dev->fbuf.base)
- return -EINVAL;
- if (win->w.width < 48 || win->w.height < 32)
- return -EINVAL;
- if (win->clipcount > 2048)
- return -EINVAL;
-
- field = win->field;
- maxw = norm_maxw(core->tvnorm);
- maxh = norm_maxh(core->tvnorm);
-
- if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default:
- return -EINVAL;
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
- return 0;
-}
-
-static int setup_window(struct cx8800_dev *dev, struct cx8800_fh *fh,
- struct v4l2_window *win)
-{
- struct v4l2_clip *clips = NULL;
- int n,size,retval = 0;
-
- if (NULL == fh->fmt)
- return -EINVAL;
- retval = verify_window(dev,win);
- if (0 != retval)
- return retval;
-
- /* copy clips -- luckily v4l1 + v4l2 are binary
- compatible here ...*/
- n = win->clipcount;
- size = sizeof(*clips)*(n+4);
- clips = kmalloc(size,GFP_KERNEL);
- if (NULL == clips)
- return -ENOMEM;
- if (n > 0) {
- if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
- kfree(clips);
- return -EFAULT;
- }
- }
-
- /* clip against screen */
- if (NULL != dev->fbuf.base)
- n = btcx_screen_clips(dev->fbuf.fmt.width, dev->fbuf.fmt.height,
- &win->w, clips, n);
- btcx_sort_clips(clips,n);
-
- /* 4-byte alignments */
- switch (fh->fmt->depth) {
- case 8:
- case 24:
- btcx_align(&win->w, clips, n, 3);
- break;
- case 16:
- btcx_align(&win->w, clips, n, 1);
- break;
- case 32:
- /* no alignment fixups needed */
- break;
- default:
- BUG();
- }
-
- down(&fh->vidq.lock);
- if (fh->clips)
- kfree(fh->clips);
- fh->clips = clips;
- fh->nclips = n;
- fh->win = *win;
-#if 0
- fh->ov.setup_ok = 1;
-#endif
-
- /* update overlay if needed */
- retval = 0;
-#if 0
- if (check_btres(fh, RESOURCE_OVERLAY)) {
- struct bttv_buffer *new;
-
- new = videobuf_alloc(sizeof(*new));
- bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
- retval = bttv_switch_overlay(btv,fh,new);
- }
-#endif
- up(&fh->vidq.lock);
- return retval;
-}
-#endif
/* ------------------------------------------------------------------ */
@@ -1327,9 +1096,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
struct cx8800_fh *fh = file->private_data;
struct cx8800_dev *dev = fh->dev;
struct cx88_core *core = dev->core;
-#if 0
- unsigned long flags;
-#endif
int err;
if (video_debug > 1)
@@ -1350,12 +1116,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE |
-#if 0
- V4L2_TUNER_CAP_LOW |
-#endif
-#if 0
- V4L2_CAP_VIDEO_OVERLAY |
-#endif
0;
if (UNSET != core->tuner_type)
cap->capabilities |= V4L2_CAP_TUNER;
@@ -1456,36 +1216,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
}
-#if 0
- /* needs review */
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
- unsigned int n = a->index;
-
- memset(a,0,sizeof(*a));
- a->index = n;
- switch (n) {
- case 0:
- if ((CX88_VMUX_TELEVISION == INPUT(n)->type)
- || (CX88_VMUX_CABLE == INPUT(n)->type)) {
- strcpy(a->name,"Television");
- // FIXME figure out if stereo received and set V4L2_AUDCAP_STEREO.
- return 0;
- }
- break;
- case 1:
- if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD == core->board) {
- strcpy(a->name,"Line In");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
- }
- break;
- }
- // Audio input not available.
- return -EINVAL;
- }
-#endif
/* --- capture ioctls ---------------------------------------- */
case VIDIOC_ENUM_FMT:
@@ -1588,13 +1318,16 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
{
struct v4l2_frequency *f = arg;
+ memset(f,0,sizeof(*f));
+
if (UNSET == core->tuner_type)
return -EINVAL;
- if (f->tuner != 0)
- return -EINVAL;
- memset(f,0,sizeof(*f));
+
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
+
+ cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f);
+
return 0;
}
case VIDIOC_S_FREQUENCY:
@@ -1612,11 +1345,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
down(&dev->lock);
dev->freq = f->frequency;
cx88_newstation(core);
-#ifdef V4L2_I2C_CLIENTS
cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
-#else
- cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq);
-#endif
up(&dev->lock);
return 0;
}
@@ -1714,11 +1443,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
cap->version = CX88_VERSION_CODE;
- cap->capabilities = V4L2_CAP_TUNER
-#if 0
- | V4L2_TUNER_CAP_LOW
-#endif
- ;
+ cap->capabilities = V4L2_CAP_TUNER;
return 0;
}
case VIDIOC_G_TUNER:
@@ -1730,19 +1455,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
memset(t,0,sizeof(*t));
strcpy(t->name, "Radio");
- t->rangelow = (int)(65*16);
- t->rangehigh = (int)(108*16);
-#ifdef V4L2_I2C_CLIENTS
cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
-#else
- {
- struct video_tuner vt;
- memset(&vt,0,sizeof(vt));
- cx88_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
- t->signal = vt.signal;
- }
-#endif
return 0;
}
case VIDIOC_ENUMINPUT:
@@ -1775,8 +1489,29 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
*id = 0;
return 0;
}
- case VIDIOC_S_AUDIO:
+ case VIDIOCSTUNER:
+ {
+ struct video_tuner *v = arg;
+
+ if (v->tuner) /* Only tuner 0 */
+ return -EINVAL;
+
+ cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v);
+ return 0;
+ }
case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+
+ if (0 != t->index)
+ return -EINVAL;
+
+ cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t);
+
+ return 0;
+ }
+
+ case VIDIOC_S_AUDIO:
case VIDIOC_S_INPUT:
case VIDIOC_S_STD:
return 0;
@@ -1847,6 +1582,14 @@ static void cx8800_vid_timeout(unsigned long data)
spin_unlock_irqrestore(&dev->slock,flags);
}
+static char *cx88_vid_irqs[32] = {
+ "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
+ "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
+ "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
+ "y_sync", "u_sync", "v_sync", "vbi_sync",
+ "opc_err", "par_err", "rip_err", "pci_abort",
+};
+
static void cx8800_vid_irq(struct cx8800_dev *dev)
{
struct cx88_core *core = dev->core;
@@ -2014,7 +1757,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
{
struct cx8800_dev *dev;
struct cx88_core *core;
- struct tuner_addr tun_addr;
int err;
dev = kmalloc(sizeof(*dev),GFP_KERNEL);
@@ -2088,22 +1830,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
request_module("tuner");
if (core->tda9887_conf)
request_module("tda9887");
- if (core->radio_type != UNSET) {
- tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
- tun_addr.type = core->radio_type;
- tun_addr.addr = core->radio_addr;
- cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
- }
- if (core->tuner_type != UNSET) {
- tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
- tun_addr.type = core->tuner_type;
- tun_addr.addr = core->tuner_addr;
- cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
- }
-
- if (core->tda9887_conf)
- cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
-
/* register v4l devices */
dev->video_dev = cx88_vdev_init(core,dev->pci,
&cx8800_video_template,"video");
@@ -2213,10 +1939,8 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
}
spin_unlock(&dev->slock);
-#if 1
/* FIXME -- shutdown device */
cx88_shutdown(dev->core);
-#endif
pci_save_state(pci_dev);
if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -2238,10 +1962,8 @@ static int cx8800_resume(struct pci_dev *pci_dev)
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
-#if 1
/* FIXME: re-initialize hardware */
cx88_reset(dev->core);
-#endif
/* restart video+vbi capture */
spin_lock(&dev->slock);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 867e988a5a9..307beae04f2 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
/*
- * $Id: cx88.h,v 1.62 2005/06/12 04:19:19 mchehab Exp $
+ * $Id: cx88.h,v 1.68 2005/07/07 14:17:47 mchehab Exp $
*
* v4l2 device driver for cx2388x based TV cards
*
@@ -51,8 +51,6 @@
/* ----------------------------------------------------------- */
/* defines and enums */
-#define V4L2_I2C_CLIENTS 1
-
#define FORMAT_FLAGS_PACKED 0x01
#define FORMAT_FLAGS_PLANAR 0x02
@@ -84,9 +82,9 @@ struct cx88_tvnorm {
static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
{
return (norm->id & V4L2_STD_625_50) ? 768 : 640;
-// return (norm->id & V4L2_STD_625_50) ? 720 : 640;
}
+
static unsigned int inline norm_maxh(struct cx88_tvnorm *norm)
{
return (norm->id & V4L2_STD_625_50) ? 576 : 480;
@@ -159,7 +157,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_KWORLD_DVB_T 14
#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
#define CX88_BOARD_KWORLD_LTV883 16
-#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD 17
+#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 17
#define CX88_BOARD_HAUPPAUGE_DVB_T1 18
#define CX88_BOARD_CONEXANT_DVB_T1 19
#define CX88_BOARD_PROVIDEO_PV259 20
@@ -167,10 +165,12 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_PCHDTV_HD3000 22
#define CX88_BOARD_DNTV_LIVE_DVB_T 23
#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
-#define CX88_BOARD_DIGITALLOGIC_MEC 25
+#define CX88_BOARD_DIGITALLOGIC_MEC 25
#define CX88_BOARD_IODATA_GVBCTV7E 26
#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28
+#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
+#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -220,7 +220,6 @@ struct cx88_subid {
#define RESOURCE_VBI 4
#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
-//#define BUFFER_TIMEOUT (HZ*2)
/* buffer for one video frame */
struct cx88_buffer {
@@ -336,11 +335,6 @@ struct cx8800_dev {
struct pci_dev *pci;
unsigned char pci_rev,pci_lat;
-#if 0
- /* video overlay */
- struct v4l2_framebuffer fbuf;
- struct cx88_buffer *screen;
-#endif
/* capture queues */
struct cx88_dmaqueue vidq;
@@ -435,8 +429,6 @@ struct cx8802_dev {
/* ----------------------------------------------------------- */
/* cx88-core.c */
-extern char *cx88_vid_irqs[32];
-extern char *cx88_mpeg_irqs[32];
extern void cx88_print_irqbits(char *name, char *tag, char **strings,
u32 bits, u32 mask);
extern void cx88_print_ioctl(char *name, unsigned int cmd);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 92664f75d32..9fc5055e001 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -1,5 +1,5 @@
/*
- * $Id: ir-kbd-i2c.c,v 1.10 2004/12/09 12:51:35 kraxel Exp $
+ * $Id: ir-kbd-i2c.c,v 1.11 2005/07/07 16:42:11 mchehab Exp $
*
* keyboard input driver for i2c IR remote controls
*
@@ -66,26 +66,26 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
[ 29 ] = KEY_PAGEDOWN,
[ 19 ] = KEY_SOUND,
- [ 24 ] = KEY_KPPLUSMINUS, // CH +/-
- [ 22 ] = KEY_SUBTITLE, // CC
- [ 13 ] = KEY_TEXT, // TTX
- [ 11 ] = KEY_TV, // AIR/CBL
- [ 17 ] = KEY_PC, // PC/TV
- [ 23 ] = KEY_OK, // CH RTN
- [ 25 ] = KEY_MODE, // FUNC
- [ 12 ] = KEY_SEARCH, // AUTOSCAN
+ [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */
+ [ 22 ] = KEY_SUBTITLE, /* CC */
+ [ 13 ] = KEY_TEXT, /* TTX */
+ [ 11 ] = KEY_TV, /* AIR/CBL */
+ [ 17 ] = KEY_PC, /* PC/TV */
+ [ 23 ] = KEY_OK, /* CH RTN */
+ [ 25 ] = KEY_MODE, /* FUNC */
+ [ 12 ] = KEY_SEARCH, /* AUTOSCAN */
/* Not sure what to do with these ones! */
- [ 15 ] = KEY_SELECT, // SOURCE
- [ 10 ] = KEY_KPPLUS, // +100
- [ 20 ] = KEY_KPEQUAL, // SYNC
- [ 28 ] = KEY_MEDIA, // PC/TV
+ [ 15 ] = KEY_SELECT, /* SOURCE */
+ [ 10 ] = KEY_KPPLUS, /* +100 */
+ [ 20 ] = KEY_KPEQUAL, /* SYNC */
+ [ 28 ] = KEY_MEDIA, /* PC/TV */
};
static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
[ 0x3 ] = KEY_POWER,
[ 0x6f ] = KEY_MUTE,
- [ 0x10 ] = KEY_BACKSPACE, // Recall
+ [ 0x10 ] = KEY_BACKSPACE, /* Recall */
[ 0x11 ] = KEY_KP0,
[ 0x4 ] = KEY_KP1,
@@ -97,7 +97,7 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
[ 0xc ] = KEY_KP7,
[ 0xd ] = KEY_KP8,
[ 0xe ] = KEY_KP9,
- [ 0x12 ] = KEY_KPDOT, // 100+
+ [ 0x12 ] = KEY_KPDOT, /* 100+ */
[ 0x7 ] = KEY_VOLUMEUP,
[ 0xb ] = KEY_VOLUMEDOWN,
@@ -109,25 +109,16 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
[ 0x13 ] = KEY_CHANNELDOWN,
[ 0x48 ] = KEY_ZOOM,
- [ 0x1b ] = KEY_VIDEO, // Video source
-#if 0
- [ 0x1f ] = KEY_S, // Snapshot
-#endif
- [ 0x49 ] = KEY_LANGUAGE, // MTS Select
- [ 0x19 ] = KEY_SEARCH, // Auto Scan
+ [ 0x1b ] = KEY_VIDEO, /* Video source */
+ [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
+ [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
[ 0x4b ] = KEY_RECORD,
[ 0x46 ] = KEY_PLAY,
- [ 0x45 ] = KEY_PAUSE, // Pause
+ [ 0x45 ] = KEY_PAUSE, /* Pause */
[ 0x44 ] = KEY_STOP,
-#if 0
- [ 0x43 ] = KEY_T, // Time Shift
- [ 0x47 ] = KEY_Y, // Time Shift OFF
- [ 0x4a ] = KEY_O, // TOP
- [ 0x17 ] = KEY_F, // SURF CH
-#endif
- [ 0x40 ] = KEY_FORWARD, // Forward ?
- [ 0x42 ] = KEY_REWIND, // Backward ?
+ [ 0x40 ] = KEY_FORWARD, /* Forward ? */
+ [ 0x42 ] = KEY_REWIND, /* Backward ? */
};
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index b4ee9dfe6d4..6239254db27 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -567,10 +567,6 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
switch (audmode) {
case V4L2_TUNER_MODE_STEREO:
src = 0x0020 | nicam;
-#if 0
- /* spatial effect */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
-#endif
break;
case V4L2_TUNER_MODE_MONO:
if (msp->mode == MSP_MODE_AM_NICAM) {
@@ -741,16 +737,14 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
set_current_state(TASK_INTERRUPTIBLE);
schedule();
} else {
-#if 0
- /* hmm, that one doesn't return on wakeup ... */
- msleep_interruptible(timeout);
-#else
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(timeout));
-#endif
}
}
- try_to_freeze();
+ if (current->flags & PF_FREEZE) {
+ refrigerator ();
+ }
+
remove_wait_queue(&msp->wq, &wait);
return msp->restart;
}
@@ -1154,17 +1148,10 @@ static int msp3410d_thread(void *data)
MSP_CARRIER(10.7));
/* scart routing */
msp3400c_set_scart(client,SCART_IN2,0);
-#if 0
- /* radio from SCART_IN2 */
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
- msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
-#else
/* msp34xx does radio decoding */
msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
-#endif
break;
case 0x0003:
case 0x0004:
@@ -1507,10 +1494,6 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
return -1;
}
-#if 0
- /* this will turn on a 1kHz beep - might be useful for debugging... */
- msp3400c_write(c,I2C_MSP3400C_DFP, 0x0014, 0x1040);
-#endif
msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d",
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 9c005cb128d..2fb7c2d1787 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -511,22 +511,6 @@ int microtune_init(struct i2c_client *c)
tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
company_code,buf[0x13],buf[0x14]);
-#if 0
- /* seems to cause more problems than it solves ... */
- switch (company_code) {
- case 0x30bf:
- case 0x3cbf:
- case 0x3dbf:
- case 0x4d54:
- case 0x8e81:
- case 0x8e91:
- /* ok (?) */
- break;
- default:
- tuner_warn("tuner: microtune: unknown companycode\n");
- return 0;
- }
-#endif
if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
NULL != microtune_part[buf[0x13]])
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 70bf1f1fad5..486234d41b5 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -326,6 +326,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct mxb* mxb = (struct mxb*)dev->ext_priv;
struct video_decoder_init init;
struct i2c_msg msg;
+ struct tuner_setup tun_setup;
int i = 0, err = 0;
struct tea6415c_multiplex vm;
@@ -349,8 +350,10 @@ static int mxb_init_done(struct saa7146_dev* dev)
mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
/* select a tuner type */
- i = 5;
- mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.addr = ADDR_UNSET;
+ tun_setup.type = 5;
+ mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
/* mute audio on tea6420s */
mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index e6d0a18833d..79d05ea1b69 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -155,10 +155,6 @@ static struct v4l2_mpeg_compression param_defaults =
.target = 256,
},
-#if 0
- /* FIXME: size? via S_FMT? */
- .video_format = MPEG_VIDEO_FORMAT_D1,
-#endif
};
/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0c781e24c44..88b71a20b60 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,6 +1,5 @@
-
/*
- * $Id: saa7134-cards.c,v 1.58 2005/06/07 18:05:00 nsh Exp $
+ * $Id: saa7134-cards.c,v 1.80 2005/07/07 01:49:30 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* card-specific stuff.
@@ -47,6 +46,10 @@ struct saa7134_board saa7134_boards[] = {
.name = "UNKNOWN/GENERIC",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.inputs = {{
.name = "default",
.vmux = 0,
@@ -58,6 +61,10 @@ struct saa7134_board saa7134_boards[] = {
.name = "Proteus Pro [philips reference design]",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.inputs = {{
.name = name_comp1,
.vmux = 0,
@@ -83,6 +90,10 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyVIDEO3000",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.gpiomask = 0xe000,
.inputs = {{
.name = name_tv,
@@ -90,7 +101,7 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.gpio = 0x8000,
.tv = 1,
- },{
+ },{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
@@ -117,12 +128,21 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.gpio = 0x2000,
},
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x8000,
+ },
},
[SAA7134_BOARD_FLYVIDEO2000] = {
/* "TC Wan" <tcwan@cs.usm.my> */
.name = "LifeView FlyVIDEO2000",
.audio_clock = 0x00200000,
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.gpiomask = 0xe000,
.inputs = {{
.name = name_tv,
@@ -146,14 +166,14 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.gpio = 0x4000,
}},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
.gpio = 0x2000,
- },
+ },
.mute = {
.name = name_mute,
- .amux = LINE2,
+ .amux = LINE2,
.gpio = 0x8000,
},
},
@@ -162,6 +182,10 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyTV Platinum Mini",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -183,6 +207,10 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyTV Platinum FM",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.gpiomask = 0x1E000, /* Set GP16 and unused 15,14,13 to Output */
.inputs = {{
.name = name_tv,
@@ -190,7 +218,7 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.gpio = 0x10000, /* GP16=1 selects TV input */
.tv = 1,
- },{
+ },{
/* .name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
@@ -200,29 +228,38 @@ struct saa7134_board saa7134_boards[] = {
*/ .name = name_comp1, /* Composite signal on S-Video input */
.vmux = 0,
.amux = LINE2,
-// .gpio = 0x4000,
+/* .gpio = 0x4000, */
},{
.name = name_comp2, /* Composite input */
.vmux = 3,
.amux = LINE2,
-// .gpio = 0x4000,
+/* .gpio = 0x4000, */
},{
.name = name_svideo, /* S-Video signal on S-Video input */
.vmux = 8,
.amux = LINE2,
-// .gpio = 0x4000,
+/* .gpio = 0x4000, */
}},
.radio = {
.name = name_radio,
.amux = TV,
.gpio = 0x00000, /* GP16=0 selects FM radio antenna */
},
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x10000,
+ },
},
[SAA7134_BOARD_EMPRESS] = {
/* "Gert Vervoort" <gert.vervoort@philips.com> */
.name = "EMPRESS",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
.inputs = {{
.name = name_comp1,
.vmux = 0,
@@ -245,33 +282,40 @@ struct saa7134_board saa7134_boards[] = {
.video_out = CCIR656,
},
[SAA7134_BOARD_MONSTERTV] = {
- /* "K.Ohta" <alpha292@bremen.or.jp> */
- .name = "SKNet Monster TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
+ /* "K.Ohta" <alpha292@bremen.or.jp> */
+ .name = "SKNet Monster TV",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
},
[SAA7134_BOARD_MD9717] = {
.name = "Tevion MD 9717",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -302,10 +346,13 @@ struct saa7134_board saa7134_boards[] = {
},
},
[SAA7134_BOARD_TVSTATION_RDS] = {
- /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
+ /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
.name = "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -314,10 +361,10 @@ struct saa7134_board saa7134_boards[] = {
.tv = 1,
},{
.name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
.name = name_svideo,
.vmux = 8,
@@ -328,10 +375,10 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},{
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
+ .name = "CVid over SVid",
+ .vmux = 0,
+ .amux = LINE1,
+ }},
.radio = {
.name = name_radio,
.amux = LINE2,
@@ -341,6 +388,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "KNC One TV-Station DVR",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x820000,
.inputs = {{
@@ -369,32 +419,38 @@ struct saa7134_board saa7134_boards[] = {
.video_out = CCIR656,
},
[SAA7134_BOARD_CINERGY400] = {
- .name = "Terratec Cinergy 400 TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, // CVideo over SVideo Connector
- .vmux = 0,
- .amux = LINE1,
- }}
- },
+ .name = "Terratec Cinergy 400 TV",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp2, /* CVideo over SVideo Connector */
+ .vmux = 0,
+ .amux = LINE1,
+ }}
+ },
[SAA7134_BOARD_MD5044] = {
.name = "Medion 5044",
- .audio_clock = 0x00187de7, // was: 0x00200000,
+ .audio_clock = 0x00187de7, /* was: 0x00200000, */
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -426,57 +482,65 @@ struct saa7134_board saa7134_boards[] = {
},
},
[SAA7134_BOARD_KWORLD] = {
- .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
+ .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC_M,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ }},
+ },
[SAA7134_BOARD_CINERGY600] = {
- .name = "Terratec Cinergy 600 TV",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
+ .name = "Terratec Cinergy 600 TV",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, // CVideo over SVideo Connector
- .vmux = 0,
- .amux = LINE1,
- }},
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp2, /* CVideo over SVideo Connector */
+ .vmux = 0,
+ .amux = LINE1,
+ }},
.radio = {
.name = name_radio,
.amux = LINE2,
- },
- },
+ },
+ },
[SAA7134_BOARD_MD7134] = {
.name = "Medion 7134",
- //.audio_clock = 0x00200000,
.audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.mpeg = SAA7134_MPEG_DVB,
.inputs = {{
@@ -504,6 +568,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "Typhoon TV+Radio 90031",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -523,11 +590,14 @@ struct saa7134_board saa7134_boards[] = {
.name = name_radio,
.amux = LINE2,
},
- },
+ },
[SAA7134_BOARD_ELSA] = {
.name = "ELSA EX-VISION 300TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_HITACHI_NTSC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_svideo,
.vmux = 8,
@@ -542,11 +612,14 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.tv = 1,
}},
- },
+ },
[SAA7134_BOARD_ELSA_500TV] = {
.name = "ELSA EX-VISION 500TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_HITACHI_NTSC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_svideo,
.vmux = 7,
@@ -562,83 +635,100 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.tv = 1,
}},
- },
+ },
[SAA7134_BOARD_ASUSTeK_TVFM7134] = {
- .name = "ASUS TV-FM 7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
- [SAA7135_BOARD_ASUSTeK_TVFM7135] = {
- .name = "ASUS TV-FM 7135",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
+ .name = "ASUS TV-FM 7134",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
+ [SAA7134_BOARD_ASUSTeK_TVFM7135] = {
+ .name = "ASUS TV-FM 7135",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0x200000,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
.gpio = 0x0000,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE2,
.gpio = 0x0000,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE2,
.gpio = 0x0000,
- }},
- .radio = {
- .name = name_radio,
- .amux = TV,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
.gpio = 0x200000,
- },
+ },
+ .mute = {
+ .name = name_mute,
+ .gpio = 0x0000,
+ },
+
},
[SAA7134_BOARD_VA1000POWER] = {
- .name = "AOPEN VA1000 POWER",
+ .name = "AOPEN VA1000 POWER",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ }},
},
[SAA7134_BOARD_10MOONSTVMASTER] = {
/* "lilicheng" <llc@linuxfans.org> */
.name = "10MOONS PCI TV CAPTURE CARD",
.audio_clock = 0x00200000,
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0xe000,
.inputs = {{
.name = name_tv,
@@ -662,14 +752,14 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.gpio = 0x4000,
}},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
.gpio = 0x2000,
- },
+ },
.mute = {
.name = name_mute,
- .amux = LINE2,
+ .amux = LINE2,
.gpio = 0x8000,
},
},
@@ -678,6 +768,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "BMK MPEX No Tuner",
.audio_clock = 0x200000,
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_comp1,
.vmux = 4,
@@ -706,80 +799,94 @@ struct saa7134_board saa7134_boards[] = {
.name = "Compro VideoMate TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC_M,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
- },
- [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ }},
+ },
+ [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
.name = "Compro VideoMate TV Gold+",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.gpiomask = 0x800c0000,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- .gpio = 0x06c00012,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x0ac20012,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .gpio = 0x08c20012,
- .tv = 1,
- }},
- },
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x06c00012,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x0ac20012,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .gpio = 0x08c20012,
+ .tv = 1,
+ }}, /* radio and probably mute is missing */
+ },
[SAA7134_BOARD_CRONOS_PLUS] = {
- /* gpio pins:
- 0 .. 3 BASE_ID
- 4 .. 7 PROTECT_ID
- 8 .. 11 USER_OUT
- 12 .. 13 USER_IN
- 14 .. 15 VIDIN_SEL */
+ /*
+ gpio pins:
+ 0 .. 3 BASE_ID
+ 4 .. 7 PROTECT_ID
+ 8 .. 11 USER_OUT
+ 12 .. 13 USER_IN
+ 14 .. 15 VIDIN_SEL
+ */
.name = "Matrox CronosPlus",
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0xcf00,
- .inputs = {{
- .name = name_comp1,
- .vmux = 0,
+ .inputs = {{
+ .name = name_comp1,
+ .vmux = 0,
.gpio = 2 << 14,
},{
- .name = name_comp2,
- .vmux = 0,
+ .name = name_comp2,
+ .vmux = 0,
.gpio = 1 << 14,
},{
- .name = name_comp3,
- .vmux = 0,
+ .name = name_comp3,
+ .vmux = 0,
.gpio = 0 << 14,
},{
- .name = name_comp4,
- .vmux = 0,
+ .name = name_comp4,
+ .vmux = 0,
.gpio = 3 << 14,
},{
.name = name_svideo,
.vmux = 8,
.gpio = 2 << 14,
- }},
- },
+ }},
+ },
[SAA7134_BOARD_MD2819] = {
.name = "AverMedia M156 / Medion 2819",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -809,6 +916,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "BMK MPEX Tuner",
.audio_clock = 0x200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_comp1,
.vmux = 1,
@@ -825,62 +935,72 @@ struct saa7134_board saa7134_boards[] = {
}},
.mpeg = SAA7134_MPEG_EMPRESS,
.video_out = CCIR656,
- },
- [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
- .name = "ASUS TV-FM 7133",
- .audio_clock = 0x00187de7,
- // probably wrong, the 7133 one is the NTSC version ...
- // .tuner_type = TUNER_PHILIPS_FM1236_MK3
- .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 6,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
+ },
+ [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
+ .name = "ASUS TV-FM 7133",
+ .audio_clock = 0x00187de7,
+ /* probably wrong, the 7133 one is the NTSC version ...
+ * .tuner_type = TUNER_PHILIPS_FM1236_MK3 */
+ .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
[SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
- .name = "Pinnacle PCTV Stereo (saa7134)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_MT2032,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
+ .name = "Pinnacle PCTV Stereo (saa7134)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_MT2032,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_comp2,
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
[SAA7134_BOARD_MANLI_MTV002] = {
/* Ognjen Nastic <ognjen@logosoft.ba> */
.name = "Manli MuchTV M-TV002/Behold TV 403 FM",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_svideo,
.vmux = 8,
@@ -905,6 +1025,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "Manli MuchTV M-TV001/Behold TV 401",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_svideo,
.vmux = 8,
@@ -921,14 +1044,17 @@ struct saa7134_board saa7134_boards[] = {
}},
.mute = {
.name = name_mute,
- .amux = LINE1,
+ .amux = LINE1,
},
- },
+ },
[SAA7134_BOARD_TG3000TV] = {
/* TransGear 3000TV */
.name = "Nagase Sangyo TransGear 3000TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC_M,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -944,81 +1070,90 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
}},
},
- [SAA7134_BOARD_ECS_TVP3XP] = {
- .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
- .audio_clock = 0x187de7, // xtal 32.1 MHz
- .tuner_type = TUNER_PHILIPS_PAL,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
+ [SAA7134_BOARD_ECS_TVP3XP] = {
+ .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
+ .audio_clock = 0x187de7, /* xtal 32.1 MHz */
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
},{
.name = "CVid over SVid",
.vmux = 0,
.amux = LINE1,
}},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
- [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
- .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
- .audio_clock = 0x187de7,
- .tuner_type = TUNER_PHILIPS_NTSC,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_tv_mono,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = "CVid over SVid",
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
+ .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "CVid over SVid",
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_AVACSSMARTTV] = {
/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
.name = "AVACS SmartTV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
- },{
+ },{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
@@ -1047,6 +1182,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "AVerMedia DVD EZMaker",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_comp1,
.vmux = 3,
@@ -1055,28 +1193,34 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 8,
}},
},
- [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
- /* toshii@netbsd.org */
- .name = "Noval Prime TV 7133",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_ALPS_TSBH1_NTSC,
- .inputs = {{
- .name = name_comp1,
- .vmux = 3,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 8,
- }},
- },
+ [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
+ /* toshii@netbsd.org */
+ .name = "Noval Prime TV 7133",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_ALPS_TSBH1_NTSC,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_comp1,
+ .vmux = 3,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ }},
+ },
[SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
.name = "AverMedia AverTV Studio 305",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1256_IH3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -1097,35 +1241,41 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
}},
.radio = {
- .name = name_radio,
- .amux = LINE2,
- },
+ .name = name_radio,
+ .amux = LINE2,
+ },
.mute = {
- .name = name_mute,
- .amux = LINE1,
+ .name = name_mute,
+ .amux = LINE1,
},
},
- [SAA7133_BOARD_UPMOST_PURPLE_TV] = {
- .name = "UPMOST PURPLE TV",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1236_MK3,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 7,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 7,
- .amux = LINE1,
- }},
+ [SAA7134_BOARD_UPMOST_PURPLE_TV] = {
+ .name = "UPMOST PURPLE TV",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 7,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_svideo,
+ .vmux = 7,
+ .amux = LINE1,
+ }},
},
[SAA7134_BOARD_ITEMS_MTV005] = {
/* Norman Jonas <normanjonas@arcor.de> */
.name = "Items MuchTV Plus / IT-005",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_tv,
.vmux = 3,
@@ -1149,27 +1299,30 @@ struct saa7134_board saa7134_boards[] = {
.name = "Terratec Cinergy 200 TV",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
- .name = name_tv,
+ .name = name_tv,
.vmux = 1,
.amux = LINE2,
.tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, // CVideo over SVideo Connector
- .vmux = 0,
- .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp2, /* CVideo over SVideo Connector */
+ .vmux = 0,
+ .amux = LINE1,
}},
.mute = {
- .name = name_mute,
- .amux = LINE2,
+ .name = name_mute,
+ .amux = LINE2,
},
},
[SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
@@ -1177,84 +1330,96 @@ struct saa7134_board saa7134_boards[] = {
.name = "Compro VideoMate TV PVR/FM",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC_M,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0x808c0080,
- .inputs = {{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
.gpio = 0x00080,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
.gpio = 0x00080,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2_LEFT,
- .tv = 1,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2_LEFT,
+ .tv = 1,
.gpio = 0x00080,
- }},
+ }},
.radio = {
.name = name_radio,
.amux = LINE2,
.gpio = 0x80000,
- },
+ },
.mute = {
.name = name_mute,
- .amux = LINE2,
+ .amux = LINE2,
.gpio = 0x40000,
},
- },
- [SAA7134_BOARD_SABRENT_SBTTVFM] = {
+ },
+ [SAA7134_BOARD_SABRENT_SBTTVFM] = {
/* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
- .name = "Sabrent SBT-TVFM (saa7130)",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_NTSC_M,
- .inputs = {{
+ .name = "Sabrent SBT-TVFM (saa7130)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_NTSC_M,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
.name = name_comp1,
.vmux = 1,
.amux = LINE2,
},{
- .name = name_tv,
- .vmux = 3,
- .amux = LINE2,
- .tv = 1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- },
- },
+ .name = name_tv,
+ .vmux = 3,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
/* Helge Jensen <helge.jensen@slog.dk> */
- .name = ":Zolid Xpert TV7134",
+ .name = ":Zolid Xpert TV7134",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_NTSC,
- .inputs = {{
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
.name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = LINE2,
- .tv = 1,
- }},
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ }},
},
[SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
/* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
.name = "Empire PCI TV-Radio LE",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0x4000,
.inputs = {{
.name = name_tv_mono,
@@ -1273,18 +1438,18 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
.gpio = 0x8000,
}},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x8000,
- },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x8000,
+ },
.mute = {
- .name = name_mute,
- .amux = TV,
- .gpio =0x8000,
- }
+ .name = name_mute,
+ .amux = TV,
+ .gpio =0x8000,
+ }
},
- [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
+ [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
/*
Nickolay V. Shmyrev <nshmyrev@yandex.ru>
Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
@@ -1292,6 +1457,9 @@ struct saa7134_board saa7134_boards[] = {
.name = "Avermedia AVerTV Studio 307",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1256_IH3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x03,
.inputs = {{
@@ -1321,13 +1489,21 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
.gpio = 0x01,
},
- },
- [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ .gpio = 0x00,
+ },
+ },
+ [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
.name = "Avermedia AVerTV GO 007 FM",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.gpiomask = 0x00300003,
-// .gpiomask = 0x8c240003,
+ /* .gpiomask = 0x8c240003, */
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -1350,16 +1526,24 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
.gpio = 0x00300001,
},
- },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x01,
+ },
+ },
[SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
- /* Jon Westgate <oryn@oryn.fsck.tv> */
- .name = "AVerMedia Cardbus TV/Radio",
- .audio_clock = 0x00200000,
- .tuner_type = TUNER_PHILIPS_PAL,
+ /* Kees.Blom@cwi.nl */
+ .name = "AVerMedia Cardbus TV/Radio (E500)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.inputs = {{
.name = name_tv,
.vmux = 1,
- .amux = LINE2,
+ .amux = TV,
.tv = 1,
},{
.name = name_comp1,
@@ -1368,10 +1552,10 @@ struct saa7134_board saa7134_boards[] = {
},{
.name = name_svideo,
.vmux = 8,
- .amux = LINE2,
+ .amux = LINE1,
}},
.radio = {
- .name = name_radio,
+ .name = name_radio,
.amux = LINE1,
},
},
@@ -1379,119 +1563,134 @@ struct saa7134_board saa7134_boards[] = {
.name = "Terratec Cinergy 400 mobile",
.audio_clock = 0x187de7,
.tuner_type = TUNER_ALPS_TSBE5_PAL,
- .tda9887_conf = TDA9887_PRESENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
.inputs = {{
- .name = name_tv,
+ .name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
- },{
+ },{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
}},
},
[SAA7134_BOARD_CINERGY600_MK3] = {
- .name = "Terratec Cinergy 600 TV MK3",
- .audio_clock = 0x00200000,
+ .name = "Terratec Cinergy 600 TV MK3",
+ .audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 4,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- },{
- .name = name_comp2, // CVideo over SVideo Connector
- .vmux = 0,
- .amux = LINE1,
- }},
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 4,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = name_comp2, /* CVideo over SVideo Connector */
+ .vmux = 0,
+ .amux = LINE1,
+ }},
.radio = {
.name = name_radio,
.amux = LINE2,
- },
- },
- [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
- /* Dylan Walkden <dylan_walkden@hotmail.com> */
- .name = "Compro VideoMate Gold+ Pal",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL,
- .gpiomask = 0x1ce780,
- .inputs = {{
- .name = name_svideo,
- .vmux = 0, // CVideo over SVideo Connector - ok?
- .amux = LINE1,
- .gpio = 0x008080,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x008080,
- },{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x008080,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE2,
- .gpio = 0x80000,
- },
- .mute = {
- .name = name_mute,
- .amux = LINE2,
- .gpio = 0x0c8000,
- },
- },
+ },
+ },
+ [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
+ /* Dylan Walkden <dylan_walkden@hotmail.com> */
+ .name = "Compro VideoMate Gold+ Pal",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x1ce780,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 0, /* CVideo over SVideo Connector - ok? */
+ .amux = LINE1,
+ .gpio = 0x008080,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x008080,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x008080,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ .gpio = 0x80000,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE2,
+ .gpio = 0x0c8000,
+ },
+ },
[SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
- .name = "Pinnacle PCTV 300i DVB-T + PAL",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_MT2032,
- .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
+ .name = "Pinnacle PCTV 300i DVB-T + PAL",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_MT2032,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
.mpeg = SAA7134_MPEG_DVB,
- .inputs = {{
- .name = name_tv,
- .vmux = 3,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE2,
- },{
- .name = name_comp2,
- .vmux = 1,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_comp2,
+ .vmux = 1,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
[SAA7134_BOARD_PROVIDEO_PV952] = {
/* andreas.kretschmer@web.de */
.name = "ProVideo PV952",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_comp1,
@@ -1515,10 +1714,13 @@ struct saa7134_board saa7134_boards[] = {
},
[SAA7134_BOARD_AVERMEDIA_305] = {
/* much like the "studio" version but without radio
- * and another tuner (sirspiritus@yandex.ru) */
+ * and another tuner (sirspiritus@yandex.ru) */
.name = "AverMedia AverTV/305",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FQ1216ME,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -1539,115 +1741,268 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
}},
.mute = {
- .name = name_mute,
- .amux = LINE1,
+ .name = name_mute,
+ .amux = LINE1,
},
},
[SAA7134_BOARD_FLYDVBTDUO] = {
/* LifeView FlyDVB-T DUO */
- /* "Nico Sabbi <nsabbi@tiscali.it> */
+ /* "Nico Sabbi <nsabbi@tiscali.it> Hartmut Hackmann hartmut.hackmann@t-online.de*/
.name = "LifeView FlyDVB-T DUO",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_TDA8290,
-// .gpiomask = 0xe000,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
-// .gpio = 0x0000,
.tv = 1,
- },{
+ },{
.name = name_comp1, /* Composite signal on S-Video input */
.vmux = 0,
.amux = LINE2,
-// .gpio = 0x4000,
},{
.name = name_comp2, /* Composite input */
.vmux = 3,
.amux = LINE2,
-// .gpio = 0x4000,
},{
.name = name_svideo, /* S-Video signal on S-Video input */
.vmux = 8,
.amux = LINE2,
-// .gpio = 0x4000,
}},
},
- [SAA7134_BOARD_AVERMEDIA_307] = {
- /*
- Davydov Vladimir <vladimir@iqmedia.com>
- */
- .name = "Avermedia AVerTV 307",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FQ1216ME,
- .tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 0,
- .amux = LINE1,
- },{
- .name = name_comp2,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE1,
- }},
- },
+ [SAA7134_BOARD_PHILIPS_TOUGH] = {
+ .name = "Philips TOUGH DVB-T reference design",
+ .tuner_type = TUNER_ABSENT,
+ .audio_clock = 0x00187de7,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_AVERMEDIA_307] = {
+ /*
+ Davydov Vladimir <vladimir@iqmedia.com>
+ */
+ .name = "Avermedia AVerTV 307",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FQ1216ME,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_comp2,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
[SAA7134_BOARD_ADS_INSTANT_TV] = {
- .name = "ADS Tech Instant TV (saa7135)",
+ .name = "ADS Tech Instant TV (saa7135)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
+ .name = "Kworld/Tevion V-Stream Xpert TV PVR7134",
.audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
- },{
- .name = name_svideo,
- .vmux = 8,
- .amux = LINE2,
- }},
- },
- [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
- .name = "Kworld/Tevion V-Stream Xpert TV PVR7134",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_PAL_I,
- .gpiomask = 0x0700,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- .gpio = 0x000,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- .gpio = 0x200, //gpio by DScaler
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = LINE1,
- .gpio = 0x200,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- .gpio = 0x100,
- },
- },
- };
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x0700,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x000,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x200, /* gpio by DScaler */
+ },{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ .gpio = 0x200,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x100,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x000,
+ },
+ },
+ [SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = {
+ .name = "Typhoon DVB-T Duo Digital/Analog Cardbus",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ /* .gpiomask = 0xe000, */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ /* .gpio = 0x0000, */
+ .tv = 1,
+ },{
+ .name = name_comp1, /* Composite signal on S-Video input */
+ .vmux = 0,
+ .amux = LINE2,
+ /* .gpio = 0x4000, */
+ },{
+ .name = name_comp2, /* Composite input */
+ .vmux = 3,
+ .amux = LINE2,
+ /* .gpio = 0x4000, */
+ },{
+ .name = name_svideo, /* S-Video signal on S-Video input */
+ .vmux = 8,
+ .amux = LINE2,
+ /* .gpio = 0x4000, */
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ },
+ },
+ [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
+ .name = "Compro VideoMate TV Gold+II",
+ .audio_clock = 0x002187de7,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = 0x63,
+ .radio_addr = 0x60,
+ .gpiomask = 0x8c1880,
+ .inputs = {{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ .gpio = 0x800800,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x801000,
+ },{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x800000,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x880000,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = LINE2,
+ .gpio = 0x840000,
+ },
+ },
+ [SAA7134_BOARD_KWORLD_XPERT] = {
+ /*
+ FIXME:
+ - Remote control doesn't initialize properly.
+ - Audio volume starts muted,
+ then gradually increases after channel change.
+ - Overlay scaling problems (application error?)
+ - Composite S-Video untested.
+ From: Konrad Rzepecki <hannibal@megapolis.pl>
+ */
+ .name = "Kworld Xpert TV PVR7134",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_TENA_9533_DI,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = 0x61,
+ .radio_addr = 0x60,
+ .gpiomask = 0x0700,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x000,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x200, /* gpio by DScaler */
+ },{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ .gpio = 0x200,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x100,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x000,
+ },
+ },
+};
+
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -1661,13 +2016,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0x2001,
.driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0x2001,
.driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = PCI_VENDOR_ID_PHILIPS,
@@ -1676,70 +2031,70 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x4e85,
+ .subvendor = 0x1131,
+ .subdevice = 0x4e85,
.driver_data = SAA7134_BOARD_MONSTERTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
- .subdevice = 0x1142,
- .driver_data = SAA7134_BOARD_CINERGY400,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
- .subdevice = 0x1143,
- .driver_data = SAA7134_BOARD_CINERGY600,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153B,
- .subdevice = 0x1158,
- .driver_data = SAA7134_BOARD_CINERGY600_MK3,
- },{
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x153B,
+ .subdevice = 0x1142,
+ .driver_data = SAA7134_BOARD_CINERGY400,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x153B,
+ .subdevice = 0x1143,
+ .driver_data = SAA7134_BOARD_CINERGY600,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x153B,
+ .subdevice = 0x1158,
+ .driver_data = SAA7134_BOARD_CINERGY600_MK3,
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x153b,
.subdevice = 0x1162,
.driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x5168,
.subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x4e42, //"Typhoon PCI Capture TV Card" Art.No. 50673
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x4e42, /* "Typhoon PCI Capture TV Card" Art.No. 50673 */
+ .subdevice = 0x0138,
+ .driver_data = SAA7134_BOARD_FLYVIDEO3000,
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x5168,
.subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO2000,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168,
.subdevice = 0x0212, /* minipci, LR212 */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168, /* Animation Technologies (LifeView) */
.subdevice = 0x0214, /* Standard PCI, LR214WF */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1489, /* KYE */
.subdevice = 0x0214, /* Genius VideoWonder ProTV */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x16be,
@@ -1758,36 +2113,36 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x226b,
.driver_data = SAA7134_BOARD_ELSA_500TV,
},{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4842,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = PCI_VENDOR_ID_ASUSTEK,
+ .subdevice = 0x4842,
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
},{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4845,
- .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = PCI_VENDOR_ID_ASUSTEK,
+ .subdevice = 0x4845,
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7135,
},{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4830,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4843,
- .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = PCI_VENDOR_ID_ASUSTEK,
+ .subdevice = 0x4830,
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = PCI_VENDOR_ID_ASUSTEK,
+ .subdevice = 0x4843,
+ .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = PCI_VENDOR_ID_ASUSTEK,
+ .subdevice = 0x4840,
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
},{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4840,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = PCI_VENDOR_ID_PHILIPS,
@@ -1808,118 +2163,118 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x7133,
+ .subvendor = 0x1131,
+ .subdevice = 0x7133,
.driver_data = SAA7134_BOARD_VA1000POWER,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
+ .subdevice = 0x2001,
.driver_data = SAA7134_BOARD_10MOONSTVMASTER,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
+ .subvendor = 0x185b,
+ .subdevice = 0xc100,
.driver_data = SAA7134_BOARD_VIDEOMATE_TV,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
+ .subvendor = 0x185b,
+ .subdevice = 0xc100,
.driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_MATROX,
- .subdevice = 0x48d0,
+ .subvendor = PCI_VENDOR_ID_MATROX,
+ .subdevice = 0x48d0,
.driver_data = SAA7134_BOARD_CRONOS_PLUS,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa70b,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xa70b,
.driver_data = SAA7134_BOARD_MD2819,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2115,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0x2115,
.driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2108,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0x2108,
.driver_data = SAA7134_BOARD_AVERMEDIA_305,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x10ff,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0x10ff,
.driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
- },{
+ },{
/* AVerMedia CardBus */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xd6ee,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xd6ee,
.driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
},{
/* TransGear 3000TV */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x050c,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0x050c,
.driver_data = SAA7134_BOARD_TG3000TV,
},{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002b,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002d,
- .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1019,
- .subdevice = 0x4cb4,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1019,
- .subdevice = 0x4cb5,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
- },{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x12ab,
- .subdevice = 0x0800,
- .driver_data = SAA7133_BOARD_UPMOST_PURPLE_TV,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x11bd,
+ .subdevice = 0x002b,
+ .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x11bd,
+ .subdevice = 0x002d,
+ .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1019,
+ .subdevice = 0x4cb4,
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1019,
+ .subdevice = 0x4cb5,
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x12ab,
+ .subdevice = 0x0800,
+ .driver_data = SAA7134_BOARD_UPMOST_PURPLE_TV,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x153B,
.subdevice = 0x1152,
.driver_data = SAA7134_BOARD_CINERGY200,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
+ .subvendor = 0x185b,
+ .subdevice = 0xc100,
.driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0,
+ .subvendor = 0x1131,
+ .subdevice = 0,
.driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -1939,18 +2294,24 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = 0x185b,
.subdevice = 0xc200,
.driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1540,
.subdevice = 0x9524,
.driver_data = SAA7134_BOARD_PROVIDEO_PV952,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168,
- .subdevice = 0x0306,
+ .subdevice = 0x0502, /* Cardbus version */
+ .driver_data = SAA7134_BOARD_FLYDVBTDUO,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5168,
+ .subdevice = 0x0306, /* PCI version */
.driver_data = SAA7134_BOARD_FLYDVBTDUO,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -1959,31 +2320,44 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0xf31f,
.driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
+ .subdevice = 0x2004,
+ .driver_data = SAA7134_BOARD_PHILIPS_TOUGH,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1421,
.subdevice = 0x0350, /* PCI version */
.driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1421,
.subdevice = 0x0370, /* cardbus version */
.driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
+ },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x4e42,
+ .subdevice = 0x0502,
+ .driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
+
+ },{
/* --- boards without eeprom + subsystem ID --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0,
.driver_data = SAA7134_BOARD_NOAUTO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
+ .subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0,
.driver_data = SAA7134_BOARD_NOAUTO,
},{
@@ -1991,26 +2365,26 @@ struct pci_device_id saa7134_pci_tbl[] = {
/* --- default catch --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
- },{
+ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
},{
/* --- end of list --- */
@@ -2021,46 +2395,9 @@ MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
/* ----------------------------------------------------------- */
/* flyvideo tweaks */
-#if 0
-static struct {
- char *model;
- int tuner_type;
-} fly_list[0x20] = {
- /* default catch ... */
- [ 0 ... 0x1f ] = {
- .model = "UNKNOWN",
- .tuner_type = TUNER_ABSENT,
- },
- /* ... the ones known so far */
- [ 0x05 ] = {
- .model = "PAL-BG",
- .tuner_type = TUNER_LG_PAL_NEW_TAPC,
- },
- [ 0x10 ] = {
- .model = "PAL-BG / PAL-DK",
- .tuner_type = TUNER_PHILIPS_PAL,
- },
- [ 0x15 ] = {
- .model = "NTSC",
- .tuner_type = TUNER_ABSENT /* FIXME */,
- },
-};
-#endif
static void board_flyvideo(struct saa7134_dev *dev)
{
-#if 0
- /* non-working attempt to detect the correct tuner type ... */
- u32 value;
- int index;
-
- value = dev->gpio_value;
- index = (value & 0x1f00) >> 8;
- printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
- dev->name, value, fly_list[index].model,
- fly_list[index].tuner_type);
- dev->tuner_type = fly_list[index].tuner_type;
-#endif
printk("%s: there are different flyvideo cards with different tuners\n"
"%s: out there, you might have to use the tuner=<nr> insmod\n"
"%s: option to override the default value.\n",
@@ -2071,7 +2408,7 @@ static void board_flyvideo(struct saa7134_dev *dev)
int saa7134_board_init1(struct saa7134_dev *dev)
{
- // Always print gpio, often manufacturers encode tuner type and other info.
+ /* Always print gpio, often manufacturers encode tuner type and other info. */
saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
@@ -2082,7 +2419,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
dev->has_remote = 1;
board_flyvideo(dev);
break;
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600:
case SAA7134_BOARD_CINERGY600_MK3:
@@ -2090,23 +2427,25 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
+ case SAA7134_BOARD_KWORLD_XPERT:
case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
case SAA7134_BOARD_AVERMEDIA_305:
case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
case SAA7134_BOARD_AVERMEDIA_307:
case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
-// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
+/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
- case SAA7134_BOARD_MANLI_MTV001:
- case SAA7134_BOARD_MANLI_MTV002:
+ case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
+ case SAA7134_BOARD_MANLI_MTV001:
+ case SAA7134_BOARD_MANLI_MTV002:
case SAA7134_BOARD_AVACSSMARTTV:
dev->has_remote = 1;
break;
case SAA7134_BOARD_MD5044:
printk("%s: seems there are two different versions of the MD5044\n"
- "%s: (with the same ID) out there. If sound doesn't work for\n"
- "%s: you try the audio_clock_override=0x200000 insmod option.\n",
- dev->name,dev->name,dev->name);
+ "%s: (with the same ID) out there. If sound doesn't work for\n"
+ "%s: you try the audio_clock_override=0x200000 insmod option.\n",
+ dev->name,dev->name,dev->name);
break;
case SAA7134_BOARD_CINERGY400_CARDBUS:
/* power-up tuner chip */
@@ -2114,11 +2453,19 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
msleep(1);
break;
+ case SAA7134_BOARD_FLYDVBTDUO:
+ case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+ /* turn the fan on Hac: static for the time being */
+ saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
+ saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
+ break;
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS:
+ /* power-up tuner chip */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
+ msleep(1);
+ break;
}
- if (dev->has_remote)
- dev->irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
- SAA7134_IRQ2_INTE_GPIO18A |
- SAA7134_IRQ2_INTE_GPIO16 );
return 0;
}
@@ -2139,10 +2486,85 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break;
dev->board = board;
printk("%s: board type fixup: %s\n", dev->name,
- saa7134_boards[dev->board].name);
+ saa7134_boards[dev->board].name);
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
- if (TUNER_ABSENT != dev->tuner_type)
- saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
+
+ if (TUNER_ABSENT != dev->tuner_type) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = ADDR_UNSET;
+
+ saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+ break;
+case SAA7134_BOARD_MD7134:
+ {
+ struct tuner_setup tun_setup;
+ u8 subaddr;
+ u8 data[3];
+ int ret, tuner_t;
+
+ struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
+ {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+ subaddr= 0x14;
+ tuner_t = 0;
+ ret = i2c_transfer(&dev->i2c_adap, msg, 2);
+ if (ret != 2) {
+ printk(KERN_ERR "EEPROM read failure\n");
+ } else if ((data[0] != 0) && (data[0] != 0xff)) {
+ /* old config structure */
+ subaddr = data[0] + 2;
+ msg[1].len = 2;
+ i2c_transfer(&dev->i2c_adap, msg, 2);
+ tuner_t = (data[0] << 8) + data[1];
+ switch (tuner_t){
+ case 0x0103:
+ dev->tuner_type = TUNER_PHILIPS_PAL;
+ break;
+ case 0x010C:
+ dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+ break;
+ default:
+ printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
+ }
+ } else if ((data[1] != 0) && (data[1] != 0xff)) {
+ /* new config structure */
+ subaddr = data[1] + 1;
+ msg[1].len = 1;
+ i2c_transfer(&dev->i2c_adap, msg, 2);
+ subaddr = data[0] + 1;
+ msg[1].len = 2;
+ i2c_transfer(&dev->i2c_adap, msg, 2);
+ tuner_t = (data[1] << 8) + data[0];
+ switch (tuner_t) {
+ case 0x0005:
+ dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+ break;
+ case 0x001d:
+ dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3;
+ printk(KERN_INFO "%s Board has DVB-T\n", dev->name);
+ break;
+ default:
+ printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
+ }
+ } else {
+ printk(KERN_ERR "%s unexpected config structure\n", dev->name);
+ }
+
+ printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
+ if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
+ dev->tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE;
+ saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG, &dev->tda9887_conf);
+ }
+
+ tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = ADDR_UNSET;
+
+ saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
+ }
break;
}
return 0;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index f61ed1849a2..1dbe61755e9 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-core.c,v 1.30 2005/05/22 19:23:39 nsh Exp $
+ * $Id: saa7134-core.c,v 1.39 2005/07/05 17:37:35 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* driver core
@@ -183,46 +183,6 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
/* ------------------------------------------------------------------ */
-#if 0
-static char *dec1_bits[8] = {
- "DCSTD0", "DCSCT1", "WIPA", "GLIMB",
- "GLIMT", "SLTCA", "HLCK"
-};
-static char *dec2_bits[8] = {
- "RDCAP", "COPRO", "COLSTR", "TYPE3",
- NULL, "FIDT", "HLVLN", "INTL"
-};
-static char *scale1_bits[8] = {
- "VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
-};
-static char *scale2_bits[8] = {
- "TRERR", "CFERR", "LDERR", "WASRST",
- "FIDSCI", "FIDSCO", "D6^D5", "TASK"
-};
-
-static void dump_statusreg(struct saa7134_dev *dev, int reg,
- char *regname, char **bits)
-{
- int value,i;
-
- value = saa_readb(reg);
- printk(KERN_DEBUG "%s: %s:", dev->name, regname);
- for (i = 7; i >= 0; i--) {
- if (NULL == bits[i])
- continue;
- printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
- }
- printk("\n");
-}
-
-static void dump_statusregs(struct saa7134_dev *dev)
-{
- dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
- dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
- dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
- dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
-}
-#endif
/* ----------------------------------------------------------- */
/* delayed request_module */
@@ -616,10 +576,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
if (irq_debug)
print_irqstatus(dev,loop,report,status);
-#if 0
- if (report & SAA7134_IRQ_REPORT_CONF_ERR)
- dump_statusregs(dev);
-#endif
if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
saa7134_irq_video_intl(dev);
@@ -711,7 +667,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
SAA7134_MAIN_CTRL_EVFE1 |
SAA7134_MAIN_CTRL_EVFE2 |
SAA7134_MAIN_CTRL_ESFE |
- SAA7134_MAIN_CTRL_EBADC |
SAA7134_MAIN_CTRL_EBDAC);
/* enable peripheral devices */
@@ -726,14 +681,28 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
/* late init (with i2c + irq) */
static int saa7134_hwinit2(struct saa7134_dev *dev)
{
+ unsigned int irq2_mask;
dprintk("hwinit2\n");
saa7134_video_init2(dev);
saa7134_tvaudio_init2(dev);
/* enable IRQ's */
+ irq2_mask =
+ SAA7134_IRQ2_INTE_DEC3 |
+ SAA7134_IRQ2_INTE_DEC2 |
+ SAA7134_IRQ2_INTE_DEC1 |
+ SAA7134_IRQ2_INTE_DEC0 |
+ SAA7134_IRQ2_INTE_PE |
+ SAA7134_IRQ2_INTE_AR;
+
+ if (dev->has_remote)
+ irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
+ SAA7134_IRQ2_INTE_GPIO18A |
+ SAA7134_IRQ2_INTE_GPIO16 );
+
saa_writel(SAA7134_IRQ1, 0);
- saa_writel(SAA7134_IRQ2, dev->irq2_mask);
+ saa_writel(SAA7134_IRQ2, irq2_mask);
return 0;
}
@@ -954,13 +923,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
}
/* initialize hardware #1 */
- dev->irq2_mask =
- SAA7134_IRQ2_INTE_DEC3 |
- SAA7134_IRQ2_INTE_DEC2 |
- SAA7134_IRQ2_INTE_DEC1 |
- SAA7134_IRQ2_INTE_DEC0 |
- SAA7134_IRQ2_INTE_PE |
- SAA7134_IRQ2_INTE_AR;
saa7134_board_init1(dev);
saa7134_hwinit1(dev);
@@ -990,6 +952,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
request_module("saa6752hs");
request_module_depend("saa7134-empress",&need_empress);
}
+
if (card_is_dvb(dev))
request_module_depend("saa7134-dvb",&need_dvb);
@@ -1144,9 +1107,6 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
-#if 0 /* causes some trouble when reinserting the driver ... */
- pci_disable_device(pci_dev);
-#endif
pci_set_drvdata(pci_dev, NULL);
/* free memory */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index aa8e2cf62d5..334bc185009 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,8 +1,11 @@
/*
- * $Id: saa7134-dvb.c,v 1.13 2005/06/12 04:19:19 mchehab Exp $
+ * $Id: saa7134-dvb.c,v 1.18 2005/07/04 16:05:50 mkrufky Exp $
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
+ * Extended 3 / 2005 by Hartmut Hackmann to support various
+ * cards with the tda10046 DVB-T channel decoder
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -27,23 +30,31 @@
#include <linux/kthread.h>
#include <linux/suspend.h>
+#define CONFIG_DVB_MT352 1
+#define CONFIG_DVB_TDA1004X 1
+
#include "saa7134-reg.h"
#include "saa7134.h"
-#include "dvb-pll.h"
-#include "mt352.h"
-#include "mt352_priv.h" /* FIXME */
-#include "tda1004x.h"
+#if CONFIG_DVB_MT352
+# include "mt352.h"
+# include "mt352_priv.h" /* FIXME */
+#endif
+#if CONFIG_DVB_TDA1004X
+# include "tda1004x.h"
+#endif
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
static unsigned int antenna_pwr = 0;
+
module_param(antenna_pwr, int, 0444);
MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
/* ------------------------------------------------------------------ */
+#if CONFIG_DVB_MT352
static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
{
u32 ok;
@@ -138,51 +149,390 @@ static struct mt352_config pinnacle_300i = {
.demod_init = mt352_pinnacle_init,
.pll_set = mt352_pinnacle_pll_set,
};
+#endif
/* ------------------------------------------------------------------ */
-static int medion_cardbus_init(struct dvb_frontend* fe)
+#if CONFIG_DVB_TDA1004X
+static int philips_tu1216_pll_init(struct dvb_frontend *fe)
{
- /* anything to do here ??? */
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+ struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
+
+ /* setup PLL configuration */
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+ msleep(1);
+
return 0;
}
-static int medion_cardbus_pll_set(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params)
+static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct saa7134_dev *dev = fe->dvb->priv;
- struct v4l2_frequency f;
+ u8 tuner_buf[4];
+ struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
+ sizeof(tuner_buf) };
+ int tuner_frequency = 0;
+ u8 band, cp, filter;
+
+ /* determine charge pump */
+ tuner_frequency = params->frequency + 36166000;
+ if (tuner_frequency < 87000000)
+ return -EINVAL;
+ else if (tuner_frequency < 130000000)
+ cp = 3;
+ else if (tuner_frequency < 160000000)
+ cp = 5;
+ else if (tuner_frequency < 200000000)
+ cp = 6;
+ else if (tuner_frequency < 290000000)
+ cp = 3;
+ else if (tuner_frequency < 420000000)
+ cp = 5;
+ else if (tuner_frequency < 480000000)
+ cp = 6;
+ else if (tuner_frequency < 620000000)
+ cp = 3;
+ else if (tuner_frequency < 830000000)
+ cp = 5;
+ else if (tuner_frequency < 895000000)
+ cp = 7;
+ else
+ return -EINVAL;
+
+ /* determine band */
+ if (params->frequency < 49000000)
+ return -EINVAL;
+ else if (params->frequency < 161000000)
+ band = 1;
+ else if (params->frequency < 444000000)
+ band = 2;
+ else if (params->frequency < 861000000)
+ band = 4;
+ else
+ return -EINVAL;
+
+ /* setup PLL filter */
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ filter = 0;
+ break;
- /*
- * this instructs tuner.o to set the frequency, the call will
- * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
- * tda9887.o will see that as well.
+ case BANDWIDTH_7_MHZ:
+ filter = 0;
+ break;
+
+ case BANDWIDTH_8_MHZ:
+ filter = 1;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* calculate divisor
+ * ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
*/
- f.tuner = 0;
- f.type = V4L2_TUNER_DIGITAL_TV;
- f.frequency = params->frequency / 1000 * 16 / 1000;
- saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+ tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
+
+ /* setup tuner buffer */
+ tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
+ tuner_buf[1] = tuner_frequency & 0xff;
+ tuner_buf[2] = 0xca;
+ tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(1);
return 0;
}
-static int fe_request_firmware(struct dvb_frontend* fe,
- const struct firmware **fw, char* name)
+static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
+ const struct firmware **fw, char *name)
{
struct saa7134_dev *dev = fe->dvb->priv;
return request_firmware(fw, name, &dev->pci->dev);
}
+static struct tda1004x_config philips_tu1216_config = {
+
+ .demod_address = 0x8,
+ .invert = 1,
+ .invert_oclk = 1,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
+ .pll_init = philips_tu1216_pll_init,
+ .pll_set = philips_tu1216_pll_set,
+ .pll_sleep = NULL,
+ .request_firmware = philips_tu1216_request_firmware,
+};
+
+/* ------------------------------------------------------------------ */
+
+
+static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ /* this message is to set up ATC and ALC */
+ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+ struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
+
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+ msleep(1);
+
+ return 0;
+}
+
+static void philips_fmd1216_analog(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ /* this message actually turns the tuner back to analog mode */
+ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 };
+ struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
+
+ i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+ msleep(1);
+ fmd1216_init[2] = 0x86;
+ fmd1216_init[3] = 0x54;
+ i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+ msleep(1);
+}
+
+static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ u8 tuner_buf[4];
+ struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = tuner_buf,.len =
+ sizeof(tuner_buf) };
+ int tuner_frequency = 0;
+ int divider = 0;
+ u8 band, mode, cp;
+
+ /* determine charge pump */
+ tuner_frequency = params->frequency + 36130000;
+ if (tuner_frequency < 87000000)
+ return -EINVAL;
+ /* low band */
+ else if (tuner_frequency < 180000000) {
+ band = 1;
+ mode = 7;
+ cp = 0;
+ } else if (tuner_frequency < 195000000) {
+ band = 1;
+ mode = 6;
+ cp = 1;
+ /* mid band */
+ } else if (tuner_frequency < 366000000) {
+ if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+ band = 10;
+ } else {
+ band = 2;
+ }
+ mode = 7;
+ cp = 0;
+ } else if (tuner_frequency < 478000000) {
+ if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+ band = 10;
+ } else {
+ band = 2;
+ }
+ mode = 6;
+ cp = 1;
+ /* high band */
+ } else if (tuner_frequency < 662000000) {
+ if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+ band = 12;
+ } else {
+ band = 4;
+ }
+ mode = 7;
+ cp = 0;
+ } else if (tuner_frequency < 840000000) {
+ if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+ band = 12;
+ } else {
+ band = 4;
+ }
+ mode = 6;
+ cp = 1;
+ } else {
+ if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+ band = 12;
+ } else {
+ band = 4;
+ }
+ mode = 7;
+ cp = 1;
+
+ }
+ /* calculate divisor */
+ /* ((36166000 + Finput) / 166666) rounded! */
+ divider = (tuner_frequency + 83333) / 166667;
+
+ /* setup tuner buffer */
+ tuner_buf[0] = (divider >> 8) & 0x7f;
+ tuner_buf[1] = divider & 0xff;
+ tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4;
+ tuner_buf[3] = 0x40 | band;
+
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+ return 0;
+}
+
+
static struct tda1004x_config medion_cardbus = {
- .demod_address = 0x08, /* not sure this is correct */
- .invert = 0,
- .invert_oclk = 0,
- .pll_init = medion_cardbus_init,
- .pll_set = medion_cardbus_pll_set,
- .request_firmware = fe_request_firmware,
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_IFO_AUTO_NEG,
+ .if_freq = TDA10046_FREQ_3613,
+ .pll_init = philips_fmd1216_pll_init,
+ .pll_set = philips_fmd1216_pll_set,
+ .pll_sleep = philips_fmd1216_analog,
+ .request_firmware = NULL,
};
/* ------------------------------------------------------------------ */
+struct tda827x_data {
+ u32 lomax;
+ u8 spd;
+ u8 bs;
+ u8 bp;
+ u8 cp;
+ u8 gc3;
+ u8 div1p5;
+};
+
+static struct tda827x_data tda827x_dvbt[] = {
+ { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+ { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+ { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+ { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+ { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+ { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+ { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+ { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
+};
+
+static int philips_tda827x_pll_init(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ u8 tuner_buf[14];
+
+ struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
+ .len = sizeof(tuner_buf) };
+ int i, tuner_freq, if_freq;
+ u32 N;
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ if_freq = 4000000;
+ break;
+ case BANDWIDTH_7_MHZ:
+ if_freq = 4500000;
+ break;
+ default: /* 8 MHz or Auto */
+ if_freq = 5000000;
+ break;
+ }
+ tuner_freq = params->frequency + if_freq;
+
+ i = 0;
+ while (tda827x_dvbt[i].lomax < tuner_freq) {
+ if(tda827x_dvbt[i + 1].lomax == 0)
+ break;
+ i++;
+ }
+
+ N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2);
+ tuner_buf[0] = 0;
+ tuner_buf[1] = (N>>8) | 0x40;
+ tuner_buf[2] = N & 0xff;
+ tuner_buf[3] = 0;
+ tuner_buf[4] = 0x52;
+ tuner_buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
+ (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
+ tuner_buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
+ tuner_buf[7] = 0xbf;
+ tuner_buf[8] = 0x2a;
+ tuner_buf[9] = 0x05;
+ tuner_buf[10] = 0xff;
+ tuner_buf[11] = 0x00;
+ tuner_buf[12] = 0x00;
+ tuner_buf[13] = 0x40;
+
+ tuner_msg.len = 14;
+ if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(500);
+ /* correct CP value */
+ tuner_buf[0] = 0x30;
+ tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp;
+ tuner_msg.len = 2;
+ i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+
+ return 0;
+}
+
+static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ static u8 tda827x_sleep[] = { 0x30, 0xd0};
+ struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
+ .len = sizeof(tda827x_sleep) };
+ i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+}
+
+static struct tda1004x_config tda827x_lifeview_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .if_freq = TDA10046_FREQ_045,
+ .pll_init = philips_tda827x_pll_init,
+ .pll_set = philips_tda827x_pll_set,
+ .pll_sleep = philips_tda827x_pll_sleep,
+ .request_firmware = NULL,
+};
+#endif
+
+/* ------------------------------------------------------------------ */
+
static int dvb_init(struct saa7134_dev *dev)
{
/* init struct videobuf_dvb */
@@ -197,18 +547,31 @@ static int dvb_init(struct saa7134_dev *dev)
dev);
switch (dev->board) {
+#if CONFIG_DVB_MT352
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
printk("%s: pinnacle 300i dvb setup\n",dev->name);
dev->dvb.frontend = mt352_attach(&pinnacle_300i,
&dev->i2c_adap);
break;
+#endif
+#if CONFIG_DVB_TDA1004X
case SAA7134_BOARD_MD7134:
dev->dvb.frontend = tda10046_attach(&medion_cardbus,
&dev->i2c_adap);
- if (NULL == dev->dvb.frontend)
- printk("%s: Hmm, looks like this is the old MD7134 "
- "version without DVB-T support\n",dev->name);
break;
+ case SAA7134_BOARD_PHILIPS_TOUGH:
+ dev->dvb.frontend = tda10046_attach(&philips_tu1216_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_FLYDVBTDUO:
+ dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+ dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+ &dev->i2c_adap);
+ break;
+#endif
default:
printk("%s: Huh? unknown DVB card?\n",dev->name);
break;
@@ -227,8 +590,6 @@ static int dvb_fini(struct saa7134_dev *dev)
{
static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
- printk("%s: %s\n",dev->name,__FUNCTION__);
-
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
/* otherwise we don't detect the tuner on next insmod */
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index b6f002e8421..93dd6197854 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-i2c.c,v 1.11 2005/06/12 01:36:14 mchehab Exp $
+ * $Id: saa7134-i2c.c,v 1.19 2005/07/07 01:49:30 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* i2c interface support
@@ -197,10 +197,6 @@ static inline int i2c_send_byte(struct saa7134_dev *dev,
enum i2c_status status;
__u32 dword;
-#if 0
- i2c_set_attr(dev,attr);
- saa_writeb(SAA7134_I2C_DATA, data);
-#else
/* have to write both attr + data in one 32bit word */
dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
dword &= 0x0f;
@@ -210,7 +206,6 @@ static inline int i2c_send_byte(struct saa7134_dev *dev,
// dword |= 0x40 << 16; /* 400 kHz */
dword |= 0xf0 << 24;
saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
-#endif
d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
if (!i2c_is_busy_wait(dev))
@@ -331,12 +326,44 @@ static u32 functionality(struct i2c_adapter *adap)
static int attach_inform(struct i2c_client *client)
{
- struct saa7134_dev *dev = client->adapter->algo_data;
+ struct saa7134_dev *dev = client->adapter->algo_data;
int tuner = dev->tuner_type;
int conf = dev->tda9887_conf;
+ struct tuner_setup tun_setup;
+
+ d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
+ client->driver->name,client->addr,i2c_clientname(client));
+
+ if (!client->driver->command)
+ return 0;
+
+ if (saa7134_boards[dev->board].radio_type != UNSET) {
+
+ tun_setup.type = saa7134_boards[dev->board].radio_type;
+ tun_setup.addr = saa7134_boards[dev->board].radio_addr;
+
+ if ((tun_setup.addr == ADDR_UNSET) || (tun_setup.addr == client->addr)) {
+ tun_setup.mode_mask = T_RADIO;
+
+ client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+ }
+
+ if (tuner != UNSET) {
+
+ tun_setup.type = tuner;
+ tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
+
+ if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+
+ client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+ }
+
+ client->driver->command(client, TDA9887_SET_CONFIG, &conf);
- saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
- saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&conf);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index aba2b9de60d..213740122fe 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-input.c,v 1.19 2005/06/07 18:02:26 nsh Exp $
+ * $Id: saa7134-input.c,v 1.21 2005/06/22 23:37:34 nsh Exp $
*
* handle saa7134 IR remotes via linux kernel input layer.
*
@@ -68,10 +68,8 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
[ 6 ] = KEY_AGAIN, // Recal
[ 16 ] = KEY_KPENTER, // Enter
-#if 1 /* FIXME */
[ 26 ] = KEY_F22, // Stereo
[ 24 ] = KEY_EDIT, // AV Source
-#endif
};
static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
@@ -172,45 +170,45 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
};
static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
- [ 30 ] = KEY_POWER, // power
+ [ 30 ] = KEY_POWER, // power
[ 28 ] = KEY_SEARCH, // scan
- [ 7 ] = KEY_SELECT, // source
+ [ 7 ] = KEY_SELECT, // source
[ 22 ] = KEY_VOLUMEUP,
[ 20 ] = KEY_VOLUMEDOWN,
- [ 31 ] = KEY_CHANNELUP,
+ [ 31 ] = KEY_CHANNELUP,
[ 23 ] = KEY_CHANNELDOWN,
[ 24 ] = KEY_MUTE,
[ 2 ] = KEY_KP0,
- [ 1 ] = KEY_KP1,
- [ 11 ] = KEY_KP2,
- [ 27 ] = KEY_KP3,
- [ 5 ] = KEY_KP4,
- [ 9 ] = KEY_KP5,
- [ 21 ] = KEY_KP6,
+ [ 1 ] = KEY_KP1,
+ [ 11 ] = KEY_KP2,
+ [ 27 ] = KEY_KP3,
+ [ 5 ] = KEY_KP4,
+ [ 9 ] = KEY_KP5,
+ [ 21 ] = KEY_KP6,
[ 6 ] = KEY_KP7,
- [ 10 ] = KEY_KP8,
+ [ 10 ] = KEY_KP8,
[ 18 ] = KEY_KP9,
[ 16 ] = KEY_KPDOT,
[ 3 ] = KEY_TUNER, // tv/fm
- [ 4 ] = KEY_REWIND, // fm tuning left or function left
- [ 12 ] = KEY_FORWARD, // fm tuning right or function right
+ [ 4 ] = KEY_REWIND, // fm tuning left or function left
+ [ 12 ] = KEY_FORWARD, // fm tuning right or function right
[ 0 ] = KEY_RECORD,
- [ 8 ] = KEY_STOP,
- [ 17 ] = KEY_PLAY,
+ [ 8 ] = KEY_STOP,
+ [ 17 ] = KEY_PLAY,
[ 25 ] = KEY_ZOOM,
[ 14 ] = KEY_MENU, // function
[ 19 ] = KEY_AGAIN, // recall
[ 29 ] = KEY_RESTART, // reset
+ [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
// FIXME
[ 13 ] = KEY_F21, // mts
- [ 15 ] = KEY_F22, // min
- [ 26 ] = KEY_F23, // freeze
+ [ 15 ] = KEY_F22, // min
};
/* Alex Hermann <gaaf@gmx.net> */
@@ -489,13 +487,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
- ir_codes = eztv_codes;
- mask_keycode = 0x00017c;
- mask_keyup = 0x000002;
+ ir_codes = eztv_codes;
+ mask_keycode = 0x00017c;
+ mask_keyup = 0x000002;
polling = 50; // ms
- break;
+ break;
+ case SAA7134_BOARD_KWORLD_XPERT:
case SAA7134_BOARD_AVACSSMARTTV:
- ir_codes = avacssmart_codes;
+ ir_codes = avacssmart_codes;
mask_keycode = 0x00001F;
mask_keyup = 0x000020;
polling = 50; // ms
@@ -524,6 +523,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
polling = 50; // ms
break;
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
+ case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
ir_codes = videomate_tv_pvr_codes;
mask_keycode = 0x00003F;
mask_keyup = 0x400000;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index 81732904623..b5bede95dbf 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-oss.c,v 1.14 2005/05/18 22:45:16 hhackmann Exp $
+ * $Id: saa7134-oss.c,v 1.17 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* oss dsp interface
@@ -556,21 +556,28 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
static int
mixer_recsrc_7133(struct saa7134_dev *dev)
{
- u32 value = 0xbbbbbb;
+ u32 anabar, xbarin;
+ xbarin = 0x03; // adc
+ anabar = 0;
switch (dev->oss.input) {
case TV:
- value = 0xbbbb10; /* MAIN */
+ xbarin = 0; // Demodulator
+ anabar = 2; // DACs
break;
case LINE1:
- value = 0xbbbb32; /* AUX1 */
+ anabar = 0; // aux1, aux1
break;
case LINE2:
case LINE2_LEFT:
- value = 0xbbbb54; /* AUX2 */
+ anabar = 9; // aux2, aux2
break;
}
- saa_dsp_writel(dev, 0x46c >> 2, value);
+ /* output xbar always main channel */
+ saa_dsp_writel(dev, 0x46c >> 2, 0xbbbb10);
+ saa_dsp_writel(dev, 0x464 >> 2, xbarin);
+ saa_writel(0x594 >> 2, anabar);
+
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 345eb2a8c28..4dd9f1b2392 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
+ * $Id: saa7134-ts.c,v 1.15 2005/06/14 22:48:18 hhackmann Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
@@ -221,10 +221,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
if (dev->ts_q.curr) {
field = dev->ts_q.curr->vb.field;
if (field == V4L2_FIELD_TOP) {
- if ((status & 0x100000) != 0x000000)
+ if ((status & 0x100000) != 0x100000)
goto done;
} else {
- if ((status & 0x100000) != 0x100000)
+ if ((status & 0x100000) != 0x000000)
goto done;
}
saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 3617e7f7a41..eeafa5a71d2 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-tvaudio.c,v 1.25 2005/06/07 19:00:38 nsh Exp $
+ * $Id: saa7134-tvaudio.c,v 1.30 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* tv audio decoder (fm stereo, nicam, ...)
@@ -169,7 +169,7 @@ static void tvaudio_init(struct saa7134_dev *dev)
int clock = saa7134_boards[dev->board].audio_clock;
if (UNSET != audio_clock_override)
- clock = audio_clock_override;
+ clock = audio_clock_override;
/* init all audio registers */
saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
@@ -219,14 +219,17 @@ static void mute_input_7134(struct saa7134_dev *dev)
in = dev->input;
mute = (dev->ctl_mute ||
(dev->automute && (&card(dev).radio) != in));
- if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
- card(dev).mute.name) {
- /* 7130 - we'll mute using some unconnected audio input */
+ if (card(dev).mute.name) {
+ /*
+ * 7130 - we'll mute using some unconnected audio input
+ * 7134 - we'll probably should switch external mux with gpio
+ */
if (mute)
in = &card(dev).mute;
}
+
if (dev->hw_mute == mute &&
- dev->hw_input == in) {
+ dev->hw_input == in) {
dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
mute,in->name);
return;
@@ -260,6 +263,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
/* switch gpio-connected external audio mux */
if (0 == card(dev).gpiomask)
return;
+
mask = card(dev).gpiomask;
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
@@ -339,13 +343,8 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
set_current_state(TASK_INTERRUPTIBLE);
schedule();
} else {
-#if 0
- /* hmm, that one doesn't return on wakeup ... */
- msleep_interruptible(timeout);
-#else
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(timeout));
-#endif
}
}
remove_wait_queue(&dev->thread.wq, &wait);
@@ -400,27 +399,10 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
return value;
}
-#if 0
-static void sifdebug_dump_regs(struct saa7134_dev *dev)
-{
- print_regb(AUDIO_STATUS);
- print_regb(IDENT_SIF);
- print_regb(LEVEL_READOUT1);
- print_regb(LEVEL_READOUT2);
- print_regb(DCXO_IDENT_CTRL);
- print_regb(DEMODULATOR);
- print_regb(AGC_GAIN_SELECT);
- print_regb(MONITOR_SELECT);
- print_regb(FM_DEEMPHASIS);
- print_regb(FM_DEMATRIX);
- print_regb(SIF_SAMPLE_FREQ);
- print_regb(ANALOG_IO_SELECT);
-}
-#endif
static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
{
- __u32 idp,nicam;
+ __u32 idp, nicam, nicam_status;
int retval = -1;
switch (audio->mode) {
@@ -442,18 +424,24 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
break;
case TVAUDIO_NICAM_FM:
case TVAUDIO_NICAM_AM:
- nicam = saa_readb(SAA7134_NICAM_STATUS);
+ nicam = saa_readb(SAA7134_AUDIO_STATUS);
dprintk("getstereo: nicam=0x%x\n",nicam);
- switch (nicam & 0x0b) {
- case 0x08:
- retval = V4L2_TUNER_SUB_MONO;
- break;
- case 0x09:
- retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- break;
- case 0x0a:
- retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- break;
+ if (nicam & 0x1) {
+ nicam_status = saa_readb(SAA7134_NICAM_STATUS);
+ dprintk("getstereo: nicam_status=0x%x\n", nicam_status);
+
+ switch (nicam_status & 0x03) {
+ case 0x01:
+ retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ break;
+ case 0x02:
+ retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ break;
+ default:
+ retval = V4L2_TUNER_SUB_MONO;
+ }
+ } else {
+ /* No nicam detected */
}
break;
}
@@ -489,15 +477,15 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
break;
case TVAUDIO_FM_K_STEREO:
case TVAUDIO_FM_BG_STEREO:
+ case TVAUDIO_NICAM_AM:
+ case TVAUDIO_NICAM_FM:
dprintk("setstereo [fm] => %s\n",
name[ mode % ARRAY_SIZE(name) ]);
reg = fm[ mode % ARRAY_SIZE(fm) ];
saa_writeb(SAA7134_FM_DEMATRIX, reg);
break;
case TVAUDIO_FM_SAT_STEREO:
- case TVAUDIO_NICAM_AM:
- case TVAUDIO_NICAM_FM:
- /* FIXME */
+ /* Not implemented */
break;
}
return 0;
@@ -596,7 +584,7 @@ static int tvaudio_thread(void *data)
/* find the exact tv audio norm */
for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
if (dev->tvnorm->id != UNSET &&
- !(dev->tvnorm->id & tvaudio[i].std))
+ !(dev->tvnorm->id & tvaudio[i].std))
continue;
if (tvaudio[i].carr1 != carrier)
continue;
@@ -703,24 +691,6 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
return 0;
}
-#if 0
-static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
-{
- int err;
-
- d2printk("dsp read reg 0x%x\n", reg<<2);
- saa_readl(reg);
- err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
- if (err < 0)
- return err;
- *value = saa_readl(reg);
- d2printk("dsp read => 0x%06x\n", *value & 0xffffff);
- err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
- if (err < 0)
- return err;
- return 0;
-}
-#endif
int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
{
@@ -753,31 +723,50 @@ static int getstereo_7133(struct saa7134_dev *dev)
static int mute_input_7133(struct saa7134_dev *dev)
{
u32 reg = 0;
+ u32 xbarin, xbarout;
int mask;
+ struct saa7134_input *in;
+ /* Hac 0506 route OSS sound simultanously */
+ xbarin = 0x03;
switch (dev->input->amux) {
case TV:
reg = 0x02;
+ xbarin = 0;
break;
case LINE1:
reg = 0x00;
break;
case LINE2:
case LINE2_LEFT:
- reg = 0x01;
+ reg = 0x09;
break;
}
- if (dev->ctl_mute)
+ saa_dsp_writel(dev, 0x464 >> 2, xbarin);
+ if (dev->ctl_mute) {
reg = 0x07;
+ xbarout = 0xbbbbbb;
+ } else
+ xbarout = 0xbbbb10;
+ saa_dsp_writel(dev, 0x46c >> 2, xbarout);
+
saa_writel(0x594 >> 2, reg);
+
/* switch gpio-connected external audio mux */
if (0 != card(dev).gpiomask) {
mask = card(dev).gpiomask;
+
+ if (card(dev).mute.name && dev->ctl_mute)
+ in = &card(dev).mute;
+ else
+ in = dev->input;
+
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio);
- saa7134_track_gpio(dev,dev->input->name);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
+ saa7134_track_gpio(dev,in->name);
}
+
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index 3c33c591cc8..29e51cad2aa 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -130,13 +130,7 @@ static int buffer_prepare(struct videobuf_queue *q,
lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
if (lines > VBI_LINE_COUNT)
lines = VBI_LINE_COUNT;
-#if 1
llength = VBI_LINE_LENGTH;
-#else
- llength = (norm->h_stop - norm->h_start +1) * 2;
- if (llength > VBI_LINE_LENGTH)
- llength = VBI_LINE_LENGTH;
-#endif
size = lines * llength * 2;
if (0 != buf->vb.baddr && buf->vb.bsize < size)
return -EINVAL;
@@ -178,13 +172,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
int llength,lines;
lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
-#if 1
llength = VBI_LINE_LENGTH;
-#else
- llength = (norm->h_stop - norm->h_start +1) * 2;
- if (llength > VBI_LINE_LENGTH)
- llength = VBI_LINE_LENGTH;
-#endif
*size = lines * llength * 2;
if (0 == *count)
*count = vbibufs;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index c0a2ee52053..a4c2f751d09 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-video.c,v 1.30 2005/06/07 19:00:38 nsh Exp $
+ * $Id: saa7134-video.c,v 1.36 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
@@ -274,7 +274,7 @@ static struct saa7134_tvnorm tvnorms[] = {
.h_start = 0,
.h_stop = 719,
- .video_v_start = 23,
+ .video_v_start = 23,
.video_v_stop = 262,
.vbi_v_start_0 = 10,
.vbi_v_stop_0 = 21,
@@ -1204,7 +1204,6 @@ static int video_open(struct inode *inode, struct file *file)
struct list_head *list;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
-
list_for_each(list,&saa7134_devlist) {
h = list_entry(list, struct saa7134_dev, devlist);
if (h->video_dev && (h->video_dev->minor == minor))
@@ -1256,12 +1255,12 @@ static int video_open(struct inode *inode, struct file *file)
if (fh->radio) {
/* switch to radio mode */
saa7134_tvaudio_setinput(dev,&card(dev).radio);
- saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
+ saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
} else {
/* switch to video/vbi mode */
video_mux(dev,dev->ctl_input);
}
- return 0;
+ return 0;
}
static ssize_t
@@ -1304,10 +1303,10 @@ video_poll(struct file *file, struct poll_table_struct *wait)
} else {
down(&fh->cap.lock);
if (UNSET == fh->cap.read_off) {
- /* need to capture a new frame */
+ /* need to capture a new frame */
if (res_locked(fh->dev,RESOURCE_VIDEO)) {
- up(&fh->cap.lock);
- return POLLERR;
+ up(&fh->cap.lock);
+ return POLLERR;
}
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
up(&fh->cap.lock);
@@ -1363,6 +1362,36 @@ static int video_release(struct inode *inode, struct file *file)
res_free(dev,fh,RESOURCE_VBI);
}
+ /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
+ saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
+ saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0);
+ saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
+ saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
+
+ if (dev->tuner_type == TUNER_PHILIPS_TDA8290) {
+ u8 data[2];
+ int ret;
+ struct i2c_msg msg = {.addr=I2C_ADDR_TDA8290, .flags=0, .buf=data, .len = 2};
+ data[0] = 0x21;
+ data[1] = 0xc0;
+ ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
+ if (ret != 1)
+ printk(KERN_ERR "TDA8290 access failure\n");
+ msg.addr = I2C_ADDR_TDA8275;
+ data[0] = 0x30;
+ data[1] = 0xd0;
+ ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
+ if (ret != 1)
+ printk(KERN_ERR "TDA8275 access failure\n");
+ msg.addr = I2C_ADDR_TDA8290;
+ data[0] = 0x21;
+ data[1] = 0x80;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ data[0] = 0x00;
+ data[1] = 0x02;
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ }
+
/* free stuff */
videobuf_mmap_free(&fh->cap);
videobuf_mmap_free(&fh->vbi);
@@ -1399,13 +1428,6 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
-#if 0
- if (V4L2_STD_PAL == norm->id) {
- /* FIXME */
- f->fmt.vbi.start[0] += 3;
- f->fmt.vbi.start[1] += 3*2;
- }
-#endif
}
static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
@@ -2120,8 +2142,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
memset(t,0,sizeof(*t));
strcpy(t->name, "Radio");
- t->rangelow = (int)(65*16);
- t->rangehigh = (int)(108*16);
saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index d6b1c0d4d0f..6836c07794f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134.h,v 1.41 2005/06/07 18:02:26 nsh Exp $
+ * $Id: saa7134.h,v 1.48 2005/07/01 08:22:24 nsh Exp $
*
* v4l2 device driver for philips saa7134 based TV cards
*
@@ -46,8 +46,6 @@
#endif
#define UNSET (-1U)
-/* 2.4 / 2.5 driver compatibility stuff */
-
/* ----------------------------------------------------------- */
/* enums */
@@ -159,7 +157,7 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
#define SAA7134_BOARD_NOVAC_PRIMETV7133 34
#define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
-#define SAA7133_BOARD_UPMOST_PURPLE_TV 36
+#define SAA7134_BOARD_UPMOST_PURPLE_TV 36
#define SAA7134_BOARD_ITEMS_MTV005 37
#define SAA7134_BOARD_CINERGY200 38
#define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
@@ -176,13 +174,17 @@ struct saa7134_format {
#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
#define SAA7134_BOARD_PROVIDEO_PV952 51
#define SAA7134_BOARD_AVERMEDIA_305 52
-#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
+#define SAA7134_BOARD_ASUSTeK_TVFM7135 53
#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
#define SAA7134_BOARD_FLYDVBTDUO 55
#define SAA7134_BOARD_AVERMEDIA_307 56
#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
#define SAA7134_BOARD_ADS_INSTANT_TV 58
#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
+#define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60
+#define SAA7134_BOARD_PHILIPS_TOUGH 61
+#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
+#define SAA7134_BOARD_KWORLD_XPERT 63
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -213,6 +215,10 @@ struct saa7134_board {
/* i2c chip info */
unsigned int tuner_type;
+ unsigned int radio_type;
+ unsigned char tuner_addr;
+ unsigned char radio_addr;
+
unsigned int tda9887_conf;
/* peripheral I/O */
@@ -403,9 +409,12 @@ struct saa7134_dev {
/* config info */
unsigned int board;
unsigned int tuner_type;
+ unsigned int radio_type;
+ unsigned char tuner_addr;
+ unsigned char radio_addr;
+
unsigned int tda9887_conf;
unsigned int gpio_value;
- unsigned int irq2_mask;
/* i2c i/o */
struct i2c_adapter i2c_adap;
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 07ba6d3ed08..7cb1fb3e66f 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -243,19 +243,6 @@ static int tda7432_write(struct i2c_client *client, int subaddr, int val)
}
/* I don't think we ever actually _read_ the chip... */
-#if 0
-static int tda7432_read(struct i2c_client *client)
-{
- unsigned char buffer;
- d2printk("tda7432: In tda7432_read\n");
- if (1 != i2c_master_recv(client,&buffer,1)) {
- printk(KERN_WARNING "tda7432: I/O error, trying (read)\n");
- return -1;
- }
- dprintk("tda7432: Read 0x%02x\n", buffer);
- return buffer;
-}
-#endif
static int tda7432_set(struct i2c_client *client)
{
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index f59d4601cc6..a8b6a8df510 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,5 @@
/*
- * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $
+ * $Id: tda8290.c,v 1.15 2005/07/08 20:21:33 mchehab Exp $
*
* i2c tv tuner chip device driver
* controls the philips tda8290+75 tuner chip combo.
@@ -136,15 +136,12 @@ static int tda8290_tune(struct i2c_client *c)
return 0;
}
-static void set_frequency(struct tuner *t, u16 ifc)
+static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
{
- u32 freq;
u32 N;
if (t->mode == V4L2_TUNER_RADIO)
- freq = t->freq / 1000;
- else
- freq = t->freq;
+ freq = freq / 1000;
N = (((freq<<3)+ifc)&0x3fffc);
@@ -187,14 +184,14 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
struct tuner *t = i2c_get_clientdata(c);
set_audio(t);
- set_frequency(t, 864);
+ set_frequency(t, 864, freq);
tda8290_tune(c);
}
static void set_radio_freq(struct i2c_client *c, unsigned int freq)
{
struct tuner *t = i2c_get_clientdata(c);
- set_frequency(t, 704);
+ set_frequency(t, 704, freq);
tda8290_tune(c);
}
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 97b113e070f..566e1a5ca13 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -123,19 +123,6 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
return 0;
}
-#if 0
-static int tda9875_read(struct i2c_client *client)
-{
- unsigned char buffer;
- dprintk("In tda9875_read\n");
- if (1 != i2c_master_recv(client,&buffer,1)) {
- printk(KERN_WARNING "tda9875: I/O error, trying (read)\n");
- return -1;
- }
- dprintk("Read 0x%02x\n", buffer);
- return buffer;
-}
-#endif
static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
{
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index ee35562f4d1..108c3ad7d62 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -569,15 +569,6 @@ static int tda9887_configure(struct tda9887 *t)
tda9887_set_config(t,buf);
tda9887_set_insmod(t,buf);
-#if 0
- /* This as-is breaks some cards, must be fixed in a
- * card-specific way, probably using TDA9887_SET_CONFIG to
- * turn on/off port2 */
- if (t->std & V4L2_STD_SECAM_L) {
- /* secam fixup (FIXME: move this to tvnorms array?) */
- buf[1] &= ~cOutputPort2Inactive;
- }
-#endif
dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
buf[1],buf[2],buf[3]);
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index a29f08f81f6..b53c748caf2 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -2,7 +2,7 @@
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
* I2C address is allways 0xC0.
*
- * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $
+ * $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $
*
* Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
* This code is placed under the terms of the GNU General Public License
@@ -11,23 +11,11 @@
* from their contributions on DScaler.
*/
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/videodev.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
+#include <linux/videodev.h>
+#include <linux/delay.h>
+#include <media/tuner.h>
#include <media/tuner.h>
-
-/* Declared at tuner-core.c */
-extern unsigned int tuner_debug;
#define PREFIX "TEA5767 "
@@ -38,8 +26,8 @@ extern unsigned int tuner_debug;
******************************/
/* First register */
-#define TEA5767_MUTE 0x80 /* Mutes output */
-#define TEA5767_SEARCH 0x40 /* Activates station search */
+#define TEA5767_MUTE 0x80 /* Mutes output */
+#define TEA5767_SEARCH 0x40 /* Activates station search */
/* Bits 0-5 for divider MSB */
/* Second register */
@@ -130,6 +118,14 @@ extern unsigned int tuner_debug;
/* Reserved for future extensions */
#define TEA5767_RESERVED_MASK 0xff
+enum tea5767_xtal_freq {
+ TEA5767_LOW_LO_32768 = 0,
+ TEA5767_HIGH_LO_32768 = 1,
+ TEA5767_LOW_LO_13MHz = 2,
+ TEA5767_HIGH_LO_13MHz = 3,
+};
+
+
/*****************************************************************************/
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -153,103 +149,112 @@ static void tea5767_status_dump(unsigned char *buffer)
else
printk(PREFIX "Tuner not at band limit\n");
- div=((buffer[0]&0x3f)<<8) | buffer[1];
+ div = ((buffer[0] & 0x3f) << 8) | buffer[1];
switch (TEA5767_HIGH_LO_32768) {
case TEA5767_HIGH_LO_13MHz:
- frq = 1000*(div*50-700-225)/4; /* Freq in KHz */
+ frq = 1000 * (div * 50 - 700 - 225) / 4; /* Freq in KHz */
break;
case TEA5767_LOW_LO_13MHz:
- frq = 1000*(div*50+700+225)/4; /* Freq in KHz */
+ frq = 1000 * (div * 50 + 700 + 225) / 4; /* Freq in KHz */
break;
case TEA5767_LOW_LO_32768:
- frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */
+ frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4; /* Freq in KHz */
break;
case TEA5767_HIGH_LO_32768:
default:
- frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */
+ frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */
break;
}
- buffer[0] = (div>>8) & 0x3f;
- buffer[1] = div & 0xff;
+ buffer[0] = (div >> 8) & 0x3f;
+ buffer[1] = div & 0xff;
printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
- frq/1000,frq%1000,div);
+ frq / 1000, frq % 1000, div);
if (TEA5767_STEREO_MASK & buffer[2])
printk(PREFIX "Stereo\n");
else
printk(PREFIX "Mono\n");
- printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK);
+ printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
- printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4);
+ printk(PREFIX "ADC Level = %d\n",
+ (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
- printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK));
+ printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
- printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK));
+ printk(PREFIX "Reserved = 0x%02x\n",
+ (buffer[4] & TEA5767_RESERVED_MASK));
}
/* Freq should be specifyed at 62.5 Hz */
static void set_radio_freq(struct i2c_client *c, unsigned int frq)
{
struct tuner *t = i2c_get_clientdata(c);
- unsigned char buffer[5];
+ unsigned char buffer[5];
unsigned div;
int rc;
- if ( tuner_debug )
- printk(PREFIX "radio freq counter %d\n",frq);
+ tuner_dbg (PREFIX "radio freq counter %d\n", frq);
/* Rounds freq to next decimal value - for 62.5 KHz step */
/* frq = 20*(frq/16)+radio_frq[frq%16]; */
buffer[2] = TEA5767_PORT1_HIGH;
- buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
- buffer[4]=0;
+ buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
+ TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
+ buffer[4] = 0;
+
+ if (t->mode == T_STANDBY) {
+ tuner_dbg("TEA5767 set to standby mode\n");
+ buffer[3] |= TEA5767_STDBY;
+ }
if (t->audmode == V4L2_TUNER_MODE_MONO) {
tuner_dbg("TEA5767 set to mono\n");
buffer[2] |= TEA5767_MONO;
- } else
- tuner_dbg("TEA5767 set to stereo\n");
+ } else {
+ tuner_dbg("TEA5767 set to stereo\n");
+ }
- switch (t->type) {
+ /* Should be replaced */
+ switch (TEA5767_HIGH_LO_32768) {
case TEA5767_HIGH_LO_13MHz:
- tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
+ tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
buffer[2] |= TEA5767_HIGH_LO_INJECT;
buffer[4] |= TEA5767_PLLREF_ENABLE;
- div = (frq*4/16+700+225+25)/50;
+ div = (frq * 4 / 16 + 700 + 225 + 25) / 50;
break;
case TEA5767_LOW_LO_13MHz:
- tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
+ tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
buffer[4] |= TEA5767_PLLREF_ENABLE;
- div = (frq*4/16-700-225+25)/50;
+ div = (frq * 4 / 16 - 700 - 225 + 25) / 50;
break;
case TEA5767_LOW_LO_32768:
- tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
+ tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
buffer[3] |= TEA5767_XTAL_32768;
/* const 700=4000*175 Khz - to adjust freq to right value */
- div = (1000*(frq*4/16-700-225)+16384)>>15;
+ div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15;
break;
case TEA5767_HIGH_LO_32768:
default:
- tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
+ tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
buffer[2] |= TEA5767_HIGH_LO_INJECT;
buffer[3] |= TEA5767_XTAL_32768;
- div = (1000*(frq*4/16+700+225)+16384)>>15;
+ div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;
break;
}
- buffer[0] = (div>>8) & 0x3f;
- buffer[1] = div & 0xff;
+ buffer[0] = (div >> 8) & 0x3f;
+ buffer[1] = div & 0xff;
- if ( tuner_debug )
+ if (tuner_debug)
tea5767_status_dump(buffer);
- if (5 != (rc = i2c_master_send(c,buffer,5)))
- tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc);
+ if (5 != (rc = i2c_master_send(c, buffer, 5)))
+ tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
}
static int tea5767_signal(struct i2c_client *c)
@@ -258,11 +263,11 @@ static int tea5767_signal(struct i2c_client *c)
int rc;
struct tuner *t = i2c_get_clientdata(c);
- memset(buffer,0,sizeof(buffer));
- if (5 != (rc = i2c_master_recv(c,buffer,5)))
- tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+ memset(buffer, 0, sizeof(buffer));
+ if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+ tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
- return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4));
+ return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4));
}
static int tea5767_stereo(struct i2c_client *c)
@@ -271,47 +276,46 @@ static int tea5767_stereo(struct i2c_client *c)
int rc;
struct tuner *t = i2c_get_clientdata(c);
- memset(buffer,0,sizeof(buffer));
- if (5 != (rc = i2c_master_recv(c,buffer,5)))
- tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+ memset(buffer, 0, sizeof(buffer));
+ if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+ tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
rc = buffer[2] & TEA5767_STEREO_MASK;
- if ( tuner_debug )
- tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
+ tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
- return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0);
+ return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
}
-int tea_detection(struct i2c_client *c)
+int tea5767_autodetection(struct i2c_client *c)
{
- unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff };
+ unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
int rc;
struct tuner *t = i2c_get_clientdata(c);
- if (5 != (rc = i2c_master_recv(c,buffer,5))) {
- tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc );
+ if (5 != (rc = i2c_master_recv(c, buffer, 5))) {
+ tuner_warn("it is not a TEA5767. Received %i chars.\n", rc);
return EINVAL;
}
/* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
- if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
- buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
- tuner_warn ( "All bytes are equal. It is not a TEA5767\n" );
+ if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
+ buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
+ tuner_warn("All bytes are equal. It is not a TEA5767\n");
return EINVAL;
}
/* Status bytes:
* Byte 4: bit 3:1 : CI (Chip Identification) == 0
- * bit 0 : internally set to 0
+ * bit 0 : internally set to 0
* Byte 5: bit 7:0 : == 0
*/
if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
- tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" );
+ tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
return EINVAL;
}
- tuner_warn ( "TEA5767 detected.\n" );
+ tuner_warn("TEA5767 detected.\n");
return 0;
}
@@ -319,16 +323,16 @@ int tea5767_tuner_init(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
- if (tea_detection(c)==EINVAL) return EINVAL;
+ if (tea5767_autodetection(c) == EINVAL)
+ return EINVAL;
- tuner_info("type set to %d (%s)\n",
- t->type, TEA5767_TUNER_NAME);
- strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
+ tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
+ strlcpy(c->name, "tea5767", sizeof(c->name));
- t->tv_freq = set_tv_freq;
+ t->tv_freq = set_tv_freq;
t->radio_freq = set_radio_freq;
t->has_signal = tea5767_signal;
- t->is_stereo = tea5767_stereo;
+ t->is_stereo = tea5767_stereo;
return (0);
}
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
index 51748c6578d..7d825e510ff 100644
--- a/drivers/media/video/tuner-3036.c
+++ b/drivers/media/video/tuner-3036.c
@@ -152,7 +152,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
switch (cmd)
{
- case TUNER_SET_TVFREQ:
+ case VIDIOCSFREQ:
set_tv_freq(client, *iarg);
break;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6f6bf4a633f..de190630bab 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $
+ * $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $
*
* i2c tv tuner chip device driver
* core core, i.e. kernel interfaces, registering and so on
@@ -23,42 +23,36 @@
#include <media/tuner.h>
#include <media/audiochip.h>
-/*
- * comment line bellow to return to old behavor, where only one I2C device is supported
- */
-
#define UNSET (-1U)
/* standard i2c insmod options */
static unsigned short normal_i2c[] = {
- 0x4b, /* tda8290 */
+ 0x4b, /* tda8290 */
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
I2C_CLIENT_END
};
+
I2C_CLIENT_INSMOD;
/* insmod options used at init time => read/only */
-static unsigned int addr = 0;
+static unsigned int addr = 0;
module_param(addr, int, 0444);
/* insmod options used at runtime => read/write */
-unsigned int tuner_debug = 0;
-module_param(tuner_debug, int, 0644);
+unsigned int tuner_debug = 0;
+module_param(tuner_debug, int, 0644);
-static unsigned int tv_range[2] = { 44, 958 };
+static unsigned int tv_range[2] = { 44, 958 };
static unsigned int radio_range[2] = { 65, 108 };
-module_param_array(tv_range, int, NULL, 0644);
+module_param_array(tv_range, int, NULL, 0644);
module_param_array(radio_range, int, NULL, 0644);
MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
MODULE_LICENSE("GPL");
-static int this_adap;
-static unsigned short first_tuner, tv_tuner, radio_tuner;
-
static struct i2c_driver driver;
static struct i2c_client client_template;
@@ -70,18 +64,19 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
struct tuner *t = i2c_get_clientdata(c);
if (t->type == UNSET) {
- tuner_info("tuner type not set\n");
+ tuner_warn ("tuner type not set\n");
return;
}
if (NULL == t->tv_freq) {
- tuner_info("Huh? tv_set is NULL?\n");
+ tuner_warn ("Tuner has no way to set tv freq\n");
return;
}
- if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
- tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
- freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
+ if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
+ tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
+ freq / 16, freq % 16 * 100 / 16, tv_range[0],
+ tv_range[1]);
}
- t->tv_freq(c,freq);
+ t->tv_freq(c, freq);
}
static void set_radio_freq(struct i2c_client *c, unsigned int freq)
@@ -89,24 +84,20 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
struct tuner *t = i2c_get_clientdata(c);
if (t->type == UNSET) {
- tuner_info("tuner type not set\n");
+ tuner_warn ("tuner type not set\n");
return;
}
if (NULL == t->radio_freq) {
- tuner_info("no radio tuning for this one, sorry.\n");
+ tuner_warn ("tuner has no way to set radio frequency\n");
return;
}
- if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
- if (tuner_debug)
- tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
- freq/16000,freq%16000*1000/16);
- t->radio_freq(c,freq);
- } else {
- tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
- freq/16,freq%16*100/16,
- radio_range[0],radio_range[1]);
+ if (freq <= radio_range[0] * 16000 || freq >= radio_range[1] * 16000) {
+ tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
+ freq / 16000, freq % 16000 * 100 / 16000,
+ radio_range[0], radio_range[1]);
}
+ t->radio_freq(c, freq);
return;
}
@@ -117,42 +108,45 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
switch (t->mode) {
case V4L2_TUNER_RADIO:
tuner_dbg("radio freq set to %lu.%02lu\n",
- freq/16,freq%16*100/16);
- set_radio_freq(c,freq);
+ freq / 16000, freq % 16000 * 100 / 16000);
+ set_radio_freq(c, freq);
break;
case V4L2_TUNER_ANALOG_TV:
case V4L2_TUNER_DIGITAL_TV:
tuner_dbg("tv freq set to %lu.%02lu\n",
- freq/16,freq%16*100/16);
+ freq / 16, freq % 16 * 100 / 16);
set_tv_freq(c, freq);
break;
}
t->freq = freq;
}
-static void set_type(struct i2c_client *c, unsigned int type)
+static void set_type(struct i2c_client *c, unsigned int type,
+ unsigned int new_mode_mask)
{
struct tuner *t = i2c_get_clientdata(c);
unsigned char buffer[4];
- /* sanity check */
- if (type == UNSET || type == TUNER_ABSENT)
+ if (type == UNSET || type == TUNER_ABSENT) {
+ tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
return;
- if (type >= tuner_count)
+ }
+
+ if (type >= tuner_count) {
+ tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count);
return;
+ }
+ /* This code detects calls by card attach_inform */
if (NULL == t->i2c.dev.driver) {
- /* not registered yet */
- t->type = type;
+ tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
+
+ t->type=type;
return;
}
- if ((t->initialized) && (t->type == type))
- /* run only once except type change Hac 04/05*/
- return;
-
- t->initialized = 1;
t->type = type;
+
switch (t->type) {
case TUNER_MT2032:
microtune_init(c);
@@ -161,136 +155,194 @@ static void set_type(struct i2c_client *c, unsigned int type)
tda8290_init(c);
break;
case TUNER_TEA5767:
- if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT;
+ if (tea5767_tuner_init(c) == EINVAL) {
+ t->type = TUNER_ABSENT;
+ t->mode_mask = T_UNINITIALIZED;
+ return;
+ }
+ t->mode_mask = T_RADIO;
break;
case TUNER_PHILIPS_FMD1216ME_MK3:
buffer[0] = 0x0b;
buffer[1] = 0xdc;
buffer[2] = 0x9c;
buffer[3] = 0x60;
- i2c_master_send(c,buffer,4);
+ i2c_master_send(c, buffer, 4);
mdelay(1);
buffer[2] = 0x86;
buffer[3] = 0x54;
- i2c_master_send(c,buffer,4);
+ i2c_master_send(c, buffer, 4);
default_tuner_init(c);
break;
default:
- /* TEA5767 autodetection code */
- if (tea5767_tuner_init(c)!=EINVAL) {
- t->type = TUNER_TEA5767;
- if (first_tuner == 0x60)
- first_tuner++;
- break;
- }
-
default_tuner_init(c);
break;
}
- tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
+
+ if (t->mode_mask == T_UNINITIALIZED)
+ t->mode_mask = new_mode_mask;
+
+ set_freq(c, t->freq);
+ tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
+ c->adapter->name, c->driver->name, c->addr << 1, type,
+ t->mode_mask);
}
-#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
- return 0; } else if (tuner_debug) \
- tuner_info ("Cmd %s accepted to "tun"\n",cmd);
-#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
- CHECK_ADDR(radio_tuner,cmd,"radio") } else \
- { CHECK_ADDR(tv_tuner,cmd,"TV"); }
+/*
+ * This function apply tuner config to tuner specified
+ * by tun_setup structure. I addr is unset, then admin status
+ * and tun addr status is more precise then current status,
+ * it's applied. Otherwise status and type are applied only to
+ * tuner with exactly the same addr.
+*/
+
+static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
+{
+ struct tuner *t = i2c_get_clientdata(c);
+
+ if (tun_setup->addr == ADDR_UNSET) {
+ if (t->mode_mask & tun_setup->mode_mask)
+ set_type(c, tun_setup->type, tun_setup->mode_mask);
+ } else if (tun_setup->addr == c->addr) {
+ set_type(c, tun_setup->type, tun_setup->mode_mask);
+ }
+}
-static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
+static inline int check_mode(struct tuner *t, char *cmd)
{
- /* ADDR_UNSET defaults to first available tuner */
- if ( tun_addr->addr == ADDR_UNSET ) {
- if (first_tuner != c->addr)
- return;
- switch (tun_addr->v4l2_tuner) {
+ if (1 << t->mode & t->mode_mask) {
+ switch (t->mode) {
case V4L2_TUNER_RADIO:
- radio_tuner=c->addr;
+ tuner_dbg("Cmd %s accepted for radio\n", cmd);
break;
- default:
- tv_tuner=c->addr;
+ case V4L2_TUNER_ANALOG_TV:
+ tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
+ break;
+ case V4L2_TUNER_DIGITAL_TV:
+ tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
break;
}
- } else {
- /* Sets tuner to its configured value */
- switch (tun_addr->v4l2_tuner) {
- case V4L2_TUNER_RADIO:
- radio_tuner=tun_addr->addr;
- if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
- return;
- default:
- tv_tuner=tun_addr->addr;
- if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
- return;
- }
+ return 0;
}
- set_type(c,tun_addr->type);
+ return EINVAL;
}
static char pal[] = "-";
module_param_string(pal, pal, sizeof(pal), 0644);
+static char secam[] = "-";
+module_param_string(secam, secam, sizeof(secam), 0644);
+/* get more precise norm info from insmod option */
static int tuner_fixup_std(struct tuner *t)
{
if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
- /* get more precise norm info from insmod option */
switch (pal[0]) {
case 'b':
case 'B':
case 'g':
case 'G':
- tuner_dbg("insmod fixup: PAL => PAL-BG\n");
+ tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
t->std = V4L2_STD_PAL_BG;
break;
case 'i':
case 'I':
- tuner_dbg("insmod fixup: PAL => PAL-I\n");
+ tuner_dbg ("insmod fixup: PAL => PAL-I\n");
t->std = V4L2_STD_PAL_I;
break;
case 'd':
case 'D':
case 'k':
case 'K':
- tuner_dbg("insmod fixup: PAL => PAL-DK\n");
+ tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
t->std = V4L2_STD_PAL_DK;
break;
+ case 'M':
+ case 'm':
+ tuner_dbg ("insmod fixup: PAL => PAL-M\n");
+ t->std = V4L2_STD_PAL_M;
+ break;
+ case 'N':
+ case 'n':
+ tuner_dbg ("insmod fixup: PAL => PAL-N\n");
+ t->std = V4L2_STD_PAL_N;
+ break;
}
}
+ if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+ switch (secam[0]) {
+ case 'd':
+ case 'D':
+ case 'k':
+ case 'K':
+ tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
+ t->std = V4L2_STD_SECAM_DK;
+ break;
+ case 'l':
+ case 'L':
+ tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+ t->std = V4L2_STD_SECAM_L;
+ break;
+ }
+ }
+
return 0;
}
/* ---------------------------------------------------------------------- */
+/* static var Used only in tuner_attach and tuner_probe */
+static unsigned default_mode_mask;
+
+/* During client attach, set_type is called by adapter's attach_inform callback.
+ set_type must then be completed by tuner_attach.
+ */
static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct tuner *t;
- /* by default, first I2C card is both tv and radio tuner */
- if (this_adap == 0) {
- first_tuner = addr;
- tv_tuner = addr;
- radio_tuner = addr;
- }
- this_adap++;
-
- client_template.adapter = adap;
- client_template.addr = addr;
+ client_template.adapter = adap;
+ client_template.addr = addr;
- t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
- if (NULL == t)
- return -ENOMEM;
- memset(t,0,sizeof(struct tuner));
- memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
+ t = kmalloc(sizeof(struct tuner), GFP_KERNEL);
+ if (NULL == t)
+ return -ENOMEM;
+ memset(t, 0, sizeof(struct tuner));
+ memcpy(&t->i2c, &client_template, sizeof(struct i2c_client));
i2c_set_clientdata(&t->i2c, t);
- t->type = UNSET;
- t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
- t->audmode = V4L2_TUNER_MODE_STEREO;
+ t->type = UNSET;
+ t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ t->mode_mask = T_UNINITIALIZED;
+
+
+ tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
+
+ /* TEA5767 autodetection code - only for addr = 0xc0 */
+ if (addr == 0x60) {
+ if (tea5767_autodetection(&t->i2c) != EINVAL) {
+ t->type = TUNER_TEA5767;
+ t->mode_mask = T_RADIO;
+ t->mode = T_STANDBY;
+ t->freq = 87.5 * 16; /* Sets freq to FM range */
+ default_mode_mask &= ~T_RADIO;
+
+ i2c_attach_client (&t->i2c);
+ set_type(&t->i2c,t->type, t->mode_mask);
+ return 0;
+ }
+ }
- i2c_attach_client(&t->i2c);
- tuner_info("chip found @ 0x%x (%s)\n",
- addr << 1, adap->name);
+ /* Initializes only the first adapter found */
+ if (default_mode_mask != T_UNINITIALIZED) {
+ tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask);
+ t->mode_mask = default_mode_mask;
+ t->freq = 400 * 16; /* Sets freq to VHF High */
+ default_mode_mask = T_UNINITIALIZED;
+ }
- set_type(&t->i2c, t->type);
+ /* Should be just before return */
+ i2c_attach_client (&t->i2c);
+ set_type (&t->i2c,t->type, t->mode_mask);
return 0;
}
@@ -300,11 +352,8 @@ static int tuner_probe(struct i2c_adapter *adap)
normal_i2c[0] = addr;
normal_i2c[1] = I2C_CLIENT_END;
}
- this_adap = 0;
- first_tuner = 0;
- tv_tuner = 0;
- radio_tuner = 0;
+ default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
if (adap->class & I2C_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tuner_attach);
@@ -316,9 +365,10 @@ static int tuner_detach(struct i2c_client *client)
struct tuner *t = i2c_get_clientdata(client);
int err;
- err=i2c_detach_client(&t->i2c);
+ err = i2c_detach_client(&t->i2c);
if (err) {
- tuner_warn ("Client deregistration failed, client not detached.\n");
+ tuner_warn
+ ("Client deregistration failed, client not detached.\n");
return err;
}
@@ -326,37 +376,65 @@ static int tuner_detach(struct i2c_client *client)
return 0;
}
-#define SWITCH_V4L2 if (!t->using_v4l2 && tuner_debug) \
- tuner_info("switching to v4l2\n"); \
- t->using_v4l2 = 1;
-#define CHECK_V4L2 if (t->using_v4l2) { if (tuner_debug) \
- tuner_info("ignore v4l1 call\n"); \
- return 0; }
+/*
+ * Switch tuner to other mode. If tuner support both tv and radio,
+ * set another frequency to some value (This is needed for some pal
+ * tuners to avoid locking). Otherwise, just put second tuner in
+ * standby mode.
+ */
+
+static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
+{
+ if (mode != t->mode) {
+
+ t->mode = mode;
+ if (check_mode(t, cmd) == EINVAL) {
+ t->mode = T_STANDBY;
+ if (V4L2_TUNER_RADIO == mode) {
+ set_tv_freq(client, 400 * 16);
+ } else {
+ set_radio_freq(client, 87.5 * 16000);
+ }
+ return EINVAL;
+ }
+ }
+ return 0;
+}
+
+#define switch_v4l2() if (!t->using_v4l2) \
+ tuner_dbg("switching to v4l2\n"); \
+ t->using_v4l2 = 1;
+
+static inline int check_v4l2(struct tuner *t)
+{
+ if (t->using_v4l2) {
+ tuner_dbg ("ignore v4l1 call\n");
+ return EINVAL;
+ }
+ return 0;
+}
-static int
-tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct tuner *t = i2c_get_clientdata(client);
- unsigned int *iarg = (int*)arg;
+ unsigned int *iarg = (int *)arg;
- switch (cmd) {
+ switch (cmd) {
/* --- configuration --- */
- case TUNER_SET_TYPE:
- set_type(client,*iarg);
- break;
case TUNER_SET_TYPE_ADDR:
- set_addr(client,(struct tuner_addr *)arg);
+ tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x\n",
+ ((struct tuner_setup *)arg)->type,
+ ((struct tuner_setup *)arg)->addr,
+ ((struct tuner_setup *)arg)->mode_mask);
+
+ set_addr(client, (struct tuner_setup *)arg);
break;
case AUDC_SET_RADIO:
- t->mode = V4L2_TUNER_RADIO;
- CHECK_ADDR(tv_tuner,"AUDC_SET_RADIO","TV");
-
- if (V4L2_TUNER_RADIO != t->mode) {
- set_tv_freq(client,400 * 16);
- }
+ set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO");
break;
case AUDC_CONFIG_PINNACLE:
- CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE","TV");
+ if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
+ return 0;
switch (*iarg) {
case 2:
tuner_dbg("pinnacle pal\n");
@@ -368,219 +446,238 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
}
break;
+ case TDA9887_SET_CONFIG:
+ break;
/* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a
kernel pointer here... */
case VIDIOCSCHAN:
- {
- static const v4l2_std_id map[] = {
- [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
- [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
- [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
- [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
- [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
- [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
- };
- struct video_channel *vc = arg;
-
- CHECK_V4L2;
- t->mode = V4L2_TUNER_ANALOG_TV;
- CHECK_ADDR(tv_tuner,"VIDIOCSCHAN","TV");
-
- if (vc->norm < ARRAY_SIZE(map))
- t->std = map[vc->norm];
- tuner_fixup_std(t);
- if (t->freq)
- set_tv_freq(client,t->freq);
- return 0;
- }
+ {
+ static const v4l2_std_id map[] = {
+ [VIDEO_MODE_PAL] = V4L2_STD_PAL,
+ [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
+ [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
+ [4 /* bttv */ ] = V4L2_STD_PAL_M,
+ [5 /* bttv */ ] = V4L2_STD_PAL_N,
+ [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
+ };
+ struct video_channel *vc = arg;
+
+ if (check_v4l2(t) == EINVAL)
+ return 0;
+
+ if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
+ return 0;
+
+ if (vc->norm < ARRAY_SIZE(map))
+ t->std = map[vc->norm];
+ tuner_fixup_std(t);
+ if (t->freq)
+ set_tv_freq(client, t->freq);
+ return 0;
+ }
case VIDIOCSFREQ:
- {
- unsigned long *v = arg;
+ {
+ unsigned long *v = arg;
- CHECK_MODE("VIDIOCSFREQ");
- CHECK_V4L2;
- set_freq(client,*v);
- return 0;
- }
+ if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
+ return 0;
+ if (check_v4l2(t) == EINVAL)
+ return 0;
+
+ set_freq(client, *v);
+ return 0;
+ }
case VIDIOCGTUNER:
- {
- struct video_tuner *vt = arg;
-
- CHECK_ADDR(radio_tuner,"VIDIOCGTUNER","radio");
- CHECK_V4L2;
- if (V4L2_TUNER_RADIO == t->mode) {
- if (t->has_signal)
- vt->signal = t->has_signal(client);
- if (t->is_stereo) {
- if (t->is_stereo(client))
- vt->flags |= VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
- }
- vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
+ {
+ struct video_tuner *vt = arg;
+
+ if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
+ return 0;
+ if (check_v4l2(t) == EINVAL)
+ return 0;
+
+ if (V4L2_TUNER_RADIO == t->mode) {
+ if (t->has_signal)
+ vt->signal = t->has_signal(client);
+ if (t->is_stereo) {
+ if (t->is_stereo(client))
+ vt->flags |=
+ VIDEO_TUNER_STEREO_ON;
+ else
+ vt->flags &=
+ ~VIDEO_TUNER_STEREO_ON;
+ }
+ vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
+ vt->rangelow = radio_range[0] * 16000;
+ vt->rangehigh = radio_range[1] * 16000;
- } else {
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
- }
+ } else {
+ vt->rangelow = tv_range[0] * 16;
+ vt->rangehigh = tv_range[1] * 16;
+ }
- return 0;
- }
+ return 0;
+ }
case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO","radio");
- CHECK_V4L2;
- if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
- va->mode = t->is_stereo(client)
- ? VIDEO_SOUND_STEREO
- : VIDEO_SOUND_MONO;
- return 0;
- }
+ {
+ struct video_audio *va = arg;
+
+ if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
+ return 0;
+ if (check_v4l2(t) == EINVAL)
+ return 0;
+
+ if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
+ va->mode = t->is_stereo(client)
+ ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+ return 0;
+ }
case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
+ {
+ v4l2_std_id *id = arg;
- SWITCH_V4L2;
- t->mode = V4L2_TUNER_ANALOG_TV;
- CHECK_ADDR(tv_tuner,"VIDIOC_S_STD","TV");
+ if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
+ == EINVAL)
+ return 0;
- t->std = *id;
- tuner_fixup_std(t);
- if (t->freq)
- set_freq(client,t->freq);
- break;
- }
+ switch_v4l2();
+
+ t->std = *id;
+ tuner_fixup_std(t);
+ if (t->freq)
+ set_freq(client, t->freq);
+ break;
+ }
case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- CHECK_MODE("VIDIOC_S_FREQUENCY");
- SWITCH_V4L2;
- if (V4L2_TUNER_RADIO == f->type &&
- V4L2_TUNER_RADIO != t->mode)
- set_tv_freq(client,400*16);
- t->mode = f->type;
- set_freq(client,f->frequency);
- break;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ {
+ struct v4l2_frequency *f = arg;
+
+ t->freq = f->frequency;
+ switch_v4l2();
+ if (V4L2_TUNER_RADIO == f->type &&
+ V4L2_TUNER_RADIO != t->mode) {
+ if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
+ == EINVAL)
+ return 0;
+ }
+ set_freq(client,t->freq);
- CHECK_MODE("VIDIOC_G_FREQUENCY");
- SWITCH_V4L2;
- f->type = t->mode;
- f->frequency = t->freq;
- break;
- }
+ break;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
+ return 0;
+ switch_v4l2();
+ f->type = t->mode;
+ f->frequency = t->freq;
+ break;
+ }
case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *tuner = arg;
-
- CHECK_MODE("VIDIOC_G_TUNER");
- SWITCH_V4L2;
- if (V4L2_TUNER_RADIO == t->mode) {
- if (t->has_signal)
- tuner -> signal = t->has_signal(client);
- if (t->is_stereo) {
- if (t->is_stereo(client)) {
- tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
- } else {
- tuner -> rxsubchans = V4L2_TUNER_SUB_MONO;
+ {
+ struct v4l2_tuner *tuner = arg;
+
+ if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
+ return 0;
+ switch_v4l2();
+
+ if (V4L2_TUNER_RADIO == t->mode) {
+
+ if (t->has_signal)
+ tuner->signal = t->has_signal(client);
+
+ if (t->is_stereo) {
+ if (t->is_stereo(client)) {
+ tuner->rxsubchans =
+ V4L2_TUNER_SUB_STEREO |
+ V4L2_TUNER_SUB_MONO;
+ } else {
+ tuner->rxsubchans =
+ V4L2_TUNER_SUB_MONO;
+ }
}
+
+ tuner->capability |=
+ V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+
+ tuner->audmode = t->audmode;
+
+ tuner->rangelow = radio_range[0] * 16000;
+ tuner->rangehigh = radio_range[1] * 16000;
+ } else {
+ tuner->rangelow = tv_range[0] * 16;
+ tuner->rangehigh = tv_range[1] * 16;
}
- tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- tuner->audmode = t->audmode;
-
- tuner->rangelow = radio_range[0] * 16000;
- tuner->rangehigh = radio_range[1] * 16000;
- } else {
- tuner->rangelow = tv_range[0] * 16;
- tuner->rangehigh = tv_range[1] * 16;
+ break;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *tuner = arg;
+
+ if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
+ return 0;
+
+ switch_v4l2();
+
+ if (V4L2_TUNER_RADIO == t->mode) {
+ t->audmode = tuner->audmode;
+ set_radio_freq(client, t->freq);
+ }
+ break;
}
- break;
- }
- case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
- {
- struct v4l2_tuner *tuner = arg;
-
- CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
- SWITCH_V4L2;
-
- /* To switch the audio mode, applications initialize the
- index and audmode fields and the reserved array and
- call the VIDIOC_S_TUNER ioctl. */
- /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
- V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
- V4L2_TUNER_MODE_SAP */
-
- if (tuner->audmode == V4L2_TUNER_MODE_MONO)
- t->audmode = V4L2_TUNER_MODE_MONO;
- else
- t->audmode = V4L2_TUNER_MODE_STEREO;
-
- set_radio_freq(client, t->freq);
- break;
- }
- case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
- break;
default:
- tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
- /* nothing */
+ tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
break;
}
return 0;
}
-static int tuner_suspend(struct device * dev, u32 state, u32 level)
+static int tuner_suspend(struct device *dev, u32 state, u32 level)
{
- struct i2c_client *c = container_of(dev, struct i2c_client, dev);
- struct tuner *t = i2c_get_clientdata(c);
+ struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+ struct tuner *t = i2c_get_clientdata (c);
- tuner_dbg("suspend\n");
+ tuner_dbg ("suspend\n");
/* FIXME: power down ??? */
return 0;
}
-static int tuner_resume(struct device * dev, u32 level)
+static int tuner_resume(struct device *dev, u32 level)
{
- struct i2c_client *c = container_of(dev, struct i2c_client, dev);
- struct tuner *t = i2c_get_clientdata(c);
+ struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+ struct tuner *t = i2c_get_clientdata (c);
- tuner_dbg("resume\n");
+ tuner_dbg ("resume\n");
if (t->freq)
- set_freq(c,t->freq);
+ set_freq(c, t->freq);
return 0;
}
/* ----------------------------------------------------------------------- */
static struct i2c_driver driver = {
- .owner = THIS_MODULE,
- .name = "tuner",
- .id = I2C_DRIVERID_TUNER,
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = tuner_probe,
- .detach_client = tuner_detach,
- .command = tuner_command,
+ .owner = THIS_MODULE,
+ .name = "tuner",
+ .id = I2C_DRIVERID_TUNER,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = tuner_probe,
+ .detach_client = tuner_detach,
+ .command = tuner_command,
.driver = {
- .suspend = tuner_suspend,
- .resume = tuner_resume,
- },
+ .suspend = tuner_suspend,
+ .resume = tuner_resume,
+ },
};
-static struct i2c_client client_template =
-{
+static struct i2c_client client_template = {
I2C_DEVNAME("(tuner unset)"),
- .flags = I2C_CLIENT_ALLOW_USE,
- .driver = &driver,
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
};
static int __init tuner_init_module(void)
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index c39ed6226ee..a3f8e83f531 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $
+ * $Id: tuner-simple.c,v 1.39 2005/07/07 01:49:30 mkrufky Exp $
*
* i2c tv tuner chip device driver
* controls all those simple 4-control-bytes style tuners.
@@ -54,6 +54,27 @@
#define PHILIPS_MF_SET_PAL_L 0x03 // France
#define PHILIPS_MF_SET_PAL_L2 0x02 // L'
+/* Control byte */
+
+#define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
+#define TUNER_RATIO_SELECT_50 0x00
+#define TUNER_RATIO_SELECT_32 0x02
+#define TUNER_RATIO_SELECT_166 0x04
+#define TUNER_RATIO_SELECT_62 0x06
+
+#define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
+
+/* Status byte */
+
+#define TUNER_POR 0x80
+#define TUNER_FL 0x40
+#define TUNER_MODE 0x38
+#define TUNER_AFC 0x07
+#define TUNER_SIGNAL 0x07
+#define TUNER_STEREO 0x10
+
+#define TUNER_PLL_LOCKED 0x40
+#define TUNER_STEREO_MK3 0x04
/* ---------------------------------------------------------------------- */
@@ -211,21 +232,17 @@ static struct tunertype tuners[] = {
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
{ "Philips FQ1236A MK4", Philips, NTSC,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
-
- /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
- { "Ymec TVision TVF-8531MF", Philips, NTSC,
+ { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC,
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
- /* Should work for TNF9533-D/IF, TNF9533-B/DF */
- { "Tena TNF9533-D/IF", Philips, PAL,
+ { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
-
- /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */
- { TEA5767_TUNER_NAME, Philips, RADIO,
- -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
+ { "Philips TEA5767HN FM Radio", Philips, RADIO,
+ /* see tea5767.c for details */},
{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
};
@@ -244,15 +261,6 @@ static int tuner_getstatus(struct i2c_client *c)
return byte;
}
-#define TUNER_POR 0x80
-#define TUNER_FL 0x40
-#define TUNER_MODE 0x38
-#define TUNER_AFC 0x07
-
-#define TUNER_STEREO 0x10 /* radio mode */
-#define TUNER_STEREO_MK3 0x04 /* radio mode */
-#define TUNER_SIGNAL 0x07 /* radio mode */
-
static int tuner_signal(struct i2c_client *c)
{
return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
@@ -278,22 +286,6 @@ static int tuner_stereo(struct i2c_client *c)
return stereo;
}
-#if 0 /* unused */
-static int tuner_islocked (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_FL);
-}
-
-static int tuner_afcstatus (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_AFC) - 2;
-}
-
-static int tuner_mode (struct i2c_client *c)
-{
- return (tuner_getstatus (c) & TUNER_MODE) >> 3;
-}
-#endif
/* ---------------------------------------------------------------------- */
@@ -376,7 +368,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
case TUNER_MICROTUNE_4042FI5:
/* Set the charge pump for fast tuning */
- tun->config |= 0x40;
+ tun->config |= TUNER_CHARGE_PUMP;
break;
}
@@ -425,14 +417,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
break;
}
- /* bit 6 is PLL locked indicator */
- if (status_byte & 0x40)
+ if (status_byte & TUNER_PLL_LOCKED)
break;
udelay(10);
}
/* Set the charge pump for optimized phase noise figure */
- tun->config &= ~0x40;
+ tun->config &= ~TUNER_CHARGE_PUMP;
buffer[0] = (div>>8) & 0x7f;
buffer[1] = div & 0xff;
buffer[2] = tun->config;
@@ -453,26 +444,22 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
unsigned div;
int rc;
- tun=&tuners[t->type];
- div = (freq / 1000) + (int)(16*10.7);
- buffer[2] = tun->config;
+ tun = &tuners[t->type];
+ div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
+ buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
switch (t->type) {
case TUNER_TENA_9533_DI:
case TUNER_YMEC_TVF_5533MF:
- /*These values are empirically determinated */
- div = (freq * 122) / 16000 - 20;
- buffer[2] = 0x88; /* could be also 0x80 */
- buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
- break;
+ tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
+ return;
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FMD1216ME_MK3:
buffer[3] = 0x19;
break;
case TUNER_PHILIPS_FM1256_IH3:
- div = (20 * freq) / 16000 + 333 * 2;
- buffer[2] = 0x80;
+ div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
buffer[3] = 0x19;
break;
case TUNER_LG_PAL_FM:
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 9a493bea76d..d8b78f1d686 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -864,13 +864,8 @@ static int tda9874a_getmode(struct CHIPSTATE *chip)
* But changing the mode to VIDEO_SOUND_MONO would switch
* external 4052 multiplexer in audio_hook().
*/
-#if 0
- if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */
- mode |= VIDEO_SOUND_STEREO;
-#else
if(nsr & 0x02) /* NSR.S/MB=1 */
mode |= VIDEO_SOUND_STEREO;
-#endif
if(nsr & 0x01) /* NSR.D/SB=1 */
mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
} else {
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 0f03c25489f..e8d9440977c 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -400,14 +400,6 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
}
}
-#if 0
- if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {
- tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;
- t_fmt_name = hauppauge_tuner_fmt[t_format].name;
- } else {
- t_fmt_name = "<unknown>";
- }
-#endif
TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
tvee->model,
@@ -482,6 +474,7 @@ static unsigned short normal_i2c[] = {
0xa0 >> 1,
I2C_CLIENT_END,
};
+
I2C_CLIENT_INSMOD;
struct i2c_driver i2c_driver_tveeprom;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 8b623278ccd..ffbe6f4720e 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1363,19 +1363,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
u32 device_state;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
- switch(state)
- {
- case 1: /* S1 */
- device_state=1; /* D1 */;
- break;
- case 3: /* S3 */
- case 4: /* S4 */
- device_state=3; /* D3 */;
- break;
- default:
- return -EAGAIN /*FIXME*/;
- break;
- }
+ device_state=pci_choose_state(pdev, state);
printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 5ea89bf0df1..debb8ac5954 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -84,7 +84,7 @@
extern void mptscsih_remove(struct pci_dev *);
extern void mptscsih_shutdown(struct pci_dev *);
#ifdef CONFIG_PM
-extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
+extern int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
extern int mptscsih_resume(struct pci_dev *pdev);
#endif
extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
index d0267609a94..fe2e7afc9ea 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/message/i2o/config-osm.c
@@ -15,7 +15,9 @@
#include <linux/module.h>
#include <linux/i2o.h>
+#include <linux/dcache.h>
#include <linux/namei.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 4cecdafeb87..7fc692a8f5b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -6,8 +6,7 @@ menu "Misc devices"
config IBM_ASM
tristate "Device driver for IBM RSA service processor"
- depends on X86 && EXPERIMENTAL
- default n
+ depends on X86 && PCI && EXPERIMENTAL
---help---
This option enables device driver support for in-band access to the
IBM RSA (Condor) service processor in eServer xSeries systems.
@@ -22,7 +21,7 @@ config IBM_ASM
WARNING: This software may not be supported or function
correctly on your IBM server. Please consult the IBM ServerProven
- website <http://www.pc.ibm/ww/eserver/xseries/serverproven> for
+ website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
information on the specific driver level and support statement
for your IBM server.
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 3a5f6ac5b36..7a42966d755 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -20,6 +20,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/protocol.h>
+#include <asm/div64.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/scatterlist.h>
@@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host)
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
unsigned int datactrl, timeout, irqmask;
+ unsigned long long clks;
void __iomem *base;
DBG(host, "blksz %04x blks %04x flags %08x\n",
@@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
mmci_init_sg(host, data);
- timeout = data->timeout_clks +
- ((unsigned long long)data->timeout_ns * host->cclk) /
- 1000000000ULL;
+ clks = (unsigned long long)data->timeout_ns * host->cclk;
+ do_div(clks, 1000000000UL);
+
+ timeout = data->timeout_clks + (unsigned int)clks;
base = host->base;
writel(timeout, base + MMCIDATATIMER);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index b7fbd30b49a..0c41d4b41a6 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -54,28 +54,6 @@
#define DBGF(x...) do { } while (0)
#endif
-#ifdef CONFIG_MMC_DEBUG
-void DBG_REG(int reg, u8 value)
-{
- int i;
-
- printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ",
- reg, (int)value, (int)value, (value < 0x20)?'.':value);
-
- for (i = 7;i >= 0;i--)
- {
- if (value & (1 << i))
- printk("x");
- else
- printk(".");
- }
-
- printk("\n");
-}
-#else
-#define DBG_REG(r, v) do {} while (0)
-#endif
-
/*
* Device resources
*/
@@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
#endif /* CONFIG_PNP */
+static const int config_ports[] = { 0x2E, 0x4E };
+static const int unlock_codes[] = { 0x83, 0x87 };
+
+static const int valid_ids[] = {
+ 0x7112,
+ };
+
#ifdef CONFIG_PNP
static unsigned int nopnp = 0;
#else
@@ -1051,6 +1036,20 @@ static struct mmc_host_ops wbsd_ops = {
\*****************************************************************************/
/*
+ * Helper function for card detection
+ */
+static void wbsd_detect_card(unsigned long data)
+{
+ struct wbsd_host *host = (struct wbsd_host*)data;
+
+ BUG_ON(host == NULL);
+
+ DBG("Executing card detection\n");
+
+ mmc_detect_change(host->mmc);
+}
+
+/*
* Tasklets
*/
@@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
u8 csr;
- int change = 0;
spin_lock(&host->lock);
@@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned long param)
{
DBG("Card inserted\n");
host->flags |= WBSD_FCARD_PRESENT;
- change = 1;
+
+ /*
+ * Delay card detection to allow electrical connections
+ * to stabilise.
+ */
+ mod_timer(&host->timer, jiffies + HZ/2);
}
+
+ spin_unlock(&host->lock);
}
else if (host->flags & WBSD_FCARD_PRESENT)
{
DBG("Card removed\n");
host->flags &= ~WBSD_FCARD_PRESENT;
- change = 1;
if (host->mrq)
{
@@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned long param)
host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
}
- }
-
- /*
- * Unlock first since we might get a call back.
- */
- spin_unlock(&host->lock);
+
+ /*
+ * Unlock first since we might get a call back.
+ */
+ spin_unlock(&host->lock);
- if (change)
mmc_detect_change(host->mmc);
+ }
}
static void wbsd_tasklet_fifo(unsigned long param)
@@ -1325,6 +1328,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
spin_lock_init(&host->lock);
/*
+ * Set up detection timer
+ */
+ init_timer(&host->timer);
+ host->timer.data = (unsigned long)host;
+ host->timer.function = wbsd_detect_card;
+
+ /*
* Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512.
*/
@@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
static void __devexit wbsd_free_mmc(struct device* dev)
{
struct mmc_host* mmc;
+ struct wbsd_host* host;
mmc = dev_get_drvdata(dev);
if (!mmc)
return;
+ host = mmc_priv(mmc);
+ BUG_ON(host == NULL);
+
+ del_timer_sync(&host->timer);
+
mmc_free_host(mmc);
dev_set_drvdata(dev, NULL);
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index 864f30828d0..661a9f6a6e6 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -8,13 +8,6 @@
* published by the Free Software Foundation.
*/
-const int config_ports[] = { 0x2E, 0x4E };
-const int unlock_codes[] = { 0x83, 0x87 };
-
-const int valid_ids[] = {
- 0x7112,
- };
-
#define LOCK_CODE 0xAA
#define WBSD_CONF_SWRST 0x02
@@ -187,4 +180,6 @@ struct wbsd_host
struct tasklet_struct timeout_tasklet;
struct tasklet_struct finish_tasklet;
struct tasklet_struct block_tasklet;
+
+ struct timer_list timer; /* Card detection timer */
};
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index d682dbc8157..b5dc59389bb 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/chips/Kconfig
-# $Id: Kconfig,v 1.13 2004/12/01 15:49:10 nico Exp $
+# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $
menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n
@@ -155,6 +155,31 @@ config MTD_CFI_I8
If your flash chips are interleaved in eights - i.e. you have eight
flash chips addressed by each bus cycle, then say 'Y'.
+config MTD_OTP
+ bool "Protection Registers aka one-time programmable (OTP) bits"
+ depends on MTD_CFI_ADV_OPTIONS
+ default n
+ help
+ This enables support for reading, writing and locking so called
+ "Protection Registers" present on some flash chips.
+ A subset of them are pre-programmed at the factory with a
+ unique set of values. The rest is user-programmable.
+
+ The user-programmable Protection Registers contain one-time
+ programmable (OTP) bits; when programmed, register bits cannot be
+ erased. Each Protection Register can be accessed multiple times to
+ program individual bits, as long as the register remains unlocked.
+
+ Each Protection Register has an associated Lock Register bit. When a
+ Lock Register bit is programmed, the associated Protection Register
+ can only be read; it can no longer be programmed. Additionally,
+ because the Lock Register bits themselves are OTP, when programmed,
+ Lock Register bits cannot be erased. Therefore, when a Protection
+ Register is locked, it cannot be unlocked.
+
+ This feature should therefore be used with extreme care. Any mistake
+ in the programming of OTP bits will waste them.
+
config MTD_CFI_INTELEXT
tristate "Support for Intel/Sharp flash chips"
depends on MTD_GEN_PROBE
@@ -275,7 +300,7 @@ config MTD_JEDEC
config MTD_XIP
bool "XIP aware MTD support"
- depends on !SMP && MTD_CFI_INTELEXT && EXPERIMENTAL
+ depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL
default y if XIP_KERNEL
help
This allows MTD support to work with flash memory which is also
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 41e2e3e3160..2dafeba3f3d 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
- * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
@@ -67,7 +67,6 @@
#define AM29LV160DT 0x22C4
#define AM29LV160DB 0x2249
#define AM29BDS323D 0x22D1
-#define AM29BDS643D 0x227E
/* Atmel */
#define AT49xV16x 0x00C0
@@ -618,17 +617,6 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
{ .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 },
}
}, {
- .mfr_id = MANUFACTURER_AMD,
- .dev_id = AM29BDS643D,
- .name = "AMD AM29BDS643D",
- .size = 0x00800000,
- .numeraseregions = 3,
- .regions = {
- { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
- { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
- { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 },
- }
- }, {
.mfr_id = MANUFACTURER_ATMEL,
.dev_id = AT49xV16x,
.name = "Atmel AT49xV16x",
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index c268bcd7172..0cfcd88468e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.164 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $
*
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/reboot.h>
#include <linux/mtd/xip.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
@@ -48,16 +49,25 @@
#define M50LPW080 0x002F
static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-//static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-//static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_intelext_sync (struct mtd_info *);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
+#ifdef CONFIG_MTD_OTP
+static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
+static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
+ struct otp_info *, size_t);
+static int cfi_intelext_get_user_prot_info (struct mtd_info *,
+ struct otp_info *, size_t);
+#endif
static int cfi_intelext_suspend (struct mtd_info *);
static void cfi_intelext_resume (struct mtd_info *);
+static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
static void cfi_intelext_destroy(struct mtd_info *);
@@ -252,7 +262,8 @@ read_pri_intelext(struct map_info *map, __u16 adr)
int nb_parts, i;
/* Protection Register info */
- extra_size += (extp->NumProtectionFields - 1) * (4 + 6);
+ extra_size += (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
extra_size += 6;
@@ -324,7 +335,9 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
mtd->resume = cfi_intelext_resume;
mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name;
-
+
+ mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
+
if (cfi->cfi_mode == CFI_MODE_CFI) {
/*
* It's a real CFI chip, not one for which the probe
@@ -422,9 +435,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
mtd->eraseregions[i].numblocks);
}
-#if 0
- mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+#ifdef CONFIG_MTD_OTP
mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
+ mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+ mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg;
+ mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
+ mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info;
+ mtd->get_user_prot_info = cfi_intelext_get_user_prot_info;
#endif
/* This function has the potential to distort the reality
@@ -433,6 +450,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
goto setup_err;
__module_get(THIS_MODULE);
+ register_reboot_notifier(&mtd->reboot_notifier);
return mtd;
setup_err:
@@ -471,7 +489,8 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
int offs, numregions, numparts, partshift, numvirtchips, i, j;
/* Protection Register info */
- offs = (extp->NumProtectionFields - 1) * (4 + 6);
+ offs = (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
offs += 6;
@@ -563,7 +582,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
resettime:
timeo = jiffies + HZ;
retry:
- if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)) {
+ if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) {
/*
* OK. We have possibility for contension on the write/erase
* operations which are global to the real chip and not per
@@ -807,10 +826,6 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
* assembly to make sure inline functions were actually inlined and that gcc
* didn't emit calls to its own support functions). Also configuring MTD CFI
* support to a single buswidth and a single interleave is also recommended.
- * Note that not only IRQs are disabled but the preemption count is also
- * increased to prevent other locking primitives (namely spin_unlock) from
- * decrementing the preempt count to zero and scheduling the CPU away while
- * not in array mode.
*/
static void xip_disable(struct map_info *map, struct flchip *chip,
@@ -818,7 +833,6 @@ static void xip_disable(struct map_info *map, struct flchip *chip,
{
/* TODO: chips with no XIP use should ignore and return */
(void) map_read(map, adr); /* ensure mmu mapping is up to date */
- preempt_disable();
local_irq_disable();
}
@@ -831,9 +845,8 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
chip->state = FL_READY;
}
(void) map_read(map, adr);
- asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */
+ xip_iprefetch();
local_irq_enable();
- preempt_enable();
}
/*
@@ -909,7 +922,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
(void) map_read(map, adr);
asm volatile (".rep 8; nop; .endr");
local_irq_enable();
- preempt_enable();
+ spin_unlock(chip->mutex);
asm volatile (".rep 8; nop; .endr");
cond_resched();
@@ -919,15 +932,15 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
* a suspended erase state. If so let's wait
* until it's done.
*/
- preempt_disable();
+ spin_lock(chip->mutex);
while (chip->state != newstate) {
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- preempt_enable();
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
- preempt_disable();
+ spin_lock(chip->mutex);
}
/* Disallow XIP again */
local_irq_disable();
@@ -956,12 +969,14 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
* The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
* the flash is actively programming or erasing since we have to poll for
* the operation to complete anyway. We can't do that in a generic way with
- * a XIP setup so do it before the actual flash operation in this case.
+ * a XIP setup so do it before the actual flash operation in this case
+ * and stub it out from INVALIDATE_CACHE_UDELAY.
*/
-#undef INVALIDATE_CACHED_RANGE
-#define INVALIDATE_CACHED_RANGE(x...)
-#define XIP_INVAL_CACHED_RANGE(map, from, size) \
- do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
+#define XIP_INVAL_CACHED_RANGE(map, from, size) \
+ INVALIDATE_CACHED_RANGE(map, from, size)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
+ UDELAY(map, chip, adr, usec)
/*
* Extra notes:
@@ -984,11 +999,23 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
#define xip_disable(map, chip, adr)
#define xip_enable(map, chip, adr)
-
-#define UDELAY(map, chip, adr, usec) cfi_udelay(usec)
-
#define XIP_INVAL_CACHED_RANGE(x...)
+#define UDELAY(map, chip, adr, usec) \
+do { \
+ spin_unlock(chip->mutex); \
+ cfi_udelay(usec); \
+ spin_lock(chip->mutex); \
+} while (0)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
+do { \
+ spin_unlock(chip->mutex); \
+ INVALIDATE_CACHED_RANGE(map, adr, len); \
+ cfi_udelay(usec); \
+ spin_lock(chip->mutex); \
+} while (0)
+
#endif
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1176,111 +1203,11 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
return ret;
}
-#if 0
-static int __xipram cfi_intelext_read_prot_reg (struct mtd_info *mtd,
- loff_t from, size_t len,
- size_t *retlen,
- u_char *buf,
- int base_offst, int reg_sz)
-{
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- struct flchip *chip;
- int ofs_factor = cfi->interleave * cfi->device_type;
- int count = len;
- int chip_num, offst;
- int ret;
-
- chip_num = ((unsigned int)from/reg_sz);
- offst = from - (reg_sz*chip_num)+base_offst;
-
- while (count) {
- /* Calculate which chip & protection register offset we need */
-
- if (chip_num >= cfi->numchips)
- goto out;
-
- chip = &cfi->chips[chip_num];
-
- spin_lock(chip->mutex);
- ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
- if (ret) {
- spin_unlock(chip->mutex);
- return (len-count)?:ret;
- }
-
- xip_disable(map, chip, chip->start);
-
- if (chip->state != FL_JEDEC_QUERY) {
- map_write(map, CMD(0x90), chip->start);
- chip->state = FL_JEDEC_QUERY;
- }
-
- while (count && ((offst-base_offst) < reg_sz)) {
- *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
- buf++;
- offst++;
- count--;
- }
-
- xip_enable(map, chip, chip->start);
- put_chip(map, chip, chip->start);
- spin_unlock(chip->mutex);
-
- /* Move on to the next chip */
- chip_num++;
- offst = base_offst;
- }
-
- out:
- return len-count;
-}
-
-static int cfi_intelext_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- struct cfi_pri_intelext *extp=cfi->cmdset_priv;
- int base_offst,reg_sz;
-
- /* Check that we actually have some protection registers */
- if(!extp || !(extp->FeatureSupport&64)){
- printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
- return 0;
- }
-
- base_offst=(1<<extp->FactProtRegSize);
- reg_sz=(1<<extp->UserProtRegSize);
-
- return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
-}
-
-static int cfi_intelext_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- struct cfi_pri_intelext *extp=cfi->cmdset_priv;
- int base_offst,reg_sz;
-
- /* Check that we actually have some protection registers */
- if(!extp || !(extp->FeatureSupport&64)){
- printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
- return 0;
- }
-
- base_offst=0;
- reg_sz=(1<<extp->FactProtRegSize);
-
- return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
-}
-#endif
-
static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
- unsigned long adr, map_word datum)
+ unsigned long adr, map_word datum, int mode)
{
struct cfi_private *cfi = map->fldrv_priv;
- map_word status, status_OK;
+ map_word status, status_OK, write_cmd;
unsigned long timeo;
int z, ret=0;
@@ -1288,9 +1215,14 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
/* Let's determine this according to the interleave only once */
status_OK = CMD(0x80);
+ switch (mode) {
+ case FL_WRITING: write_cmd = CMD(0x40); break;
+ case FL_OTP_WRITE: write_cmd = CMD(0xc0); break;
+ default: return -EINVAL;
+ }
spin_lock(chip->mutex);
- ret = get_chip(map, chip, adr, FL_WRITING);
+ ret = get_chip(map, chip, adr, mode);
if (ret) {
spin_unlock(chip->mutex);
return ret;
@@ -1299,19 +1231,18 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
ENABLE_VPP(map);
xip_disable(map, chip, adr);
- map_write(map, CMD(0x40), adr);
+ map_write(map, write_cmd, adr);
map_write(map, datum, adr);
- chip->state = FL_WRITING;
+ chip->state = mode;
- spin_unlock(chip->mutex);
- INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map));
- UDELAY(map, chip, adr, chip->word_write_time);
- spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, map_bankwidth(map),
+ chip->word_write_time);
timeo = jiffies + (HZ/2);
z = 0;
for (;;) {
- if (chip->state != FL_WRITING) {
+ if (chip->state != mode) {
/* Someone's suspended the write. Sleep */
DECLARE_WAITQUEUE(wait, current);
@@ -1339,10 +1270,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
}
/* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
z++;
UDELAY(map, chip, adr, 1);
- spin_lock(chip->mutex);
}
if (!z) {
chip->word_write_time--;
@@ -1399,7 +1328,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
datum = map_word_load_partial(map, datum, buf, gap, n);
ret = do_write_oneword(map, &cfi->chips[chipnum],
- bus_ofs, datum);
+ bus_ofs, datum, FL_WRITING);
if (ret)
return ret;
@@ -1420,7 +1349,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
map_word datum = map_word_load(map, buf);
ret = do_write_oneword(map, &cfi->chips[chipnum],
- ofs, datum);
+ ofs, datum, FL_WRITING);
if (ret)
return ret;
@@ -1444,7 +1373,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
datum = map_word_load_partial(map, datum, buf, 0, len);
ret = do_write_oneword(map, &cfi->chips[chipnum],
- ofs, datum);
+ ofs, datum, FL_WRITING);
if (ret)
return ret;
@@ -1506,9 +1435,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
if (map_word_andequal(map, status, status_OK, status_OK))
break;
- spin_unlock(chip->mutex);
UDELAY(map, chip, cmd_adr, 1);
- spin_lock(chip->mutex);
if (++z > 20) {
/* Argh. Not ready for write to buffer */
@@ -1554,10 +1481,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0xd0), cmd_adr);
chip->state = FL_WRITING;
- spin_unlock(chip->mutex);
- INVALIDATE_CACHED_RANGE(map, adr, len);
- UDELAY(map, chip, cmd_adr, chip->buffer_write_time);
- spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ cmd_adr, len,
+ chip->buffer_write_time);
timeo = jiffies + (HZ/2);
z = 0;
@@ -1589,10 +1515,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
}
/* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
- UDELAY(map, chip, cmd_adr, 1);
z++;
- spin_lock(chip->mutex);
+ UDELAY(map, chip, cmd_adr, 1);
}
if (!z) {
chip->buffer_write_time--;
@@ -1720,10 +1644,9 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
chip->state = FL_ERASING;
chip->erase_suspended = 0;
- spin_unlock(chip->mutex);
- INVALIDATE_CACHED_RANGE(map, adr, len);
- UDELAY(map, chip, adr, chip->erase_time*1000/2);
- spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, len,
+ chip->erase_time*1000/2);
/* FIXME. Use a timer to check this, and return immediately. */
/* Once the state machine's known to be working I'll do that */
@@ -1768,9 +1691,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
}
/* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
UDELAY(map, chip, adr, 1000000/HZ);
- spin_lock(chip->mutex);
}
/* We've broken this before. It doesn't hurt to be safe */
@@ -1780,44 +1701,34 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
/* check for lock bit */
if (map_word_bitsset(map, status, CMD(0x3a))) {
- unsigned char chipstatus;
+ unsigned long chipstatus;
/* Reset the error bits */
map_write(map, CMD(0x50), adr);
map_write(map, CMD(0x70), adr);
xip_enable(map, chip, adr);
- chipstatus = status.x[0];
- if (!map_word_equal(map, status, CMD(chipstatus))) {
- int i, w;
- for (w=0; w<map_words(map); w++) {
- for (i = 0; i<cfi_interleave(cfi); i++) {
- chipstatus |= status.x[w] >> (cfi->device_type * 8);
- }
- }
- printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",
- status.x[0], chipstatus);
- }
+ chipstatus = MERGESTATUS(status);
if ((chipstatus & 0x30) == 0x30) {
- printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
+ printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus);
ret = -EIO;
} else if (chipstatus & 0x02) {
/* Protection bit set */
ret = -EROFS;
} else if (chipstatus & 0x8) {
/* Voltage */
- printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus);
+ printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus);
ret = -EIO;
} else if (chipstatus & 0x20) {
if (retries--) {
- printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);
+ printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
timeo = jiffies + HZ;
put_chip(map, chip, adr);
spin_unlock(chip->mutex);
goto retry;
}
- printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);
+ printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
ret = -EIO;
}
} else {
@@ -1882,6 +1793,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
+ chip->oldstate = FL_READY;
wake_up(&chip->wq);
}
spin_unlock(chip->mutex);
@@ -1897,8 +1809,9 @@ static int __xipram do_printlockstatus_oneblock(struct map_info *map,
struct cfi_private *cfi = map->fldrv_priv;
int status, ofs_factor = cfi->interleave * cfi->device_type;
+ adr += chip->start;
xip_disable(map, chip, adr+(2*ofs_factor));
- cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+ map_write(map, CMD(0x90), adr+(2*ofs_factor));
chip->state = FL_JEDEC_QUERY;
status = cfi_read_query(map, adr+(2*ofs_factor));
xip_enable(map, chip, 0);
@@ -1915,6 +1828,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
+ struct cfi_pri_intelext *extp = cfi->cmdset_priv;
map_word status, status_OK;
unsigned long timeo = jiffies + HZ;
int ret;
@@ -1944,9 +1858,13 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
} else
BUG();
- spin_unlock(chip->mutex);
- UDELAY(map, chip, adr, 1000000/HZ);
- spin_lock(chip->mutex);
+ /*
+ * If Instant Individual Block Locking supported then no need
+ * to delay.
+ */
+
+ if (!extp || !(extp->FeatureSupport & (1 << 5)))
+ UDELAY(map, chip, adr, 1000000/HZ);
/* FIXME. Use a timer to check this, and return immediately. */
/* Once the state machine's known to be working I'll do that */
@@ -1973,9 +1891,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
}
/* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
UDELAY(map, chip, adr, 1);
- spin_lock(chip->mutex);
}
/* Done and happy. */
@@ -2034,6 +1950,274 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
return ret;
}
+#ifdef CONFIG_MTD_OTP
+
+typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
+ u_long data_offset, u_char *buf, u_int size,
+ u_long prot_offset, u_int groupno, u_int groupsize);
+
+static int __xipram
+do_otp_read(struct map_info *map, struct flchip *chip, u_long offset,
+ u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ int ret;
+
+ spin_lock(chip->mutex);
+ ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
+ if (ret) {
+ spin_unlock(chip->mutex);
+ return ret;
+ }
+
+ /* let's ensure we're not reading back cached data from array mode */
+ INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
+
+ xip_disable(map, chip, chip->start);
+ if (chip->state != FL_JEDEC_QUERY) {
+ map_write(map, CMD(0x90), chip->start);
+ chip->state = FL_JEDEC_QUERY;
+ }
+ map_copy_from(map, buf, chip->start + offset, size);
+ xip_enable(map, chip, chip->start);
+
+ /* then ensure we don't keep OTP data in the cache */
+ INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
+
+ put_chip(map, chip, chip->start);
+ spin_unlock(chip->mutex);
+ return 0;
+}
+
+static int
+do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
+ u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+ int ret;
+
+ while (size) {
+ unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1);
+ int gap = offset - bus_ofs;
+ int n = min_t(int, size, map_bankwidth(map)-gap);
+ map_word datum = map_word_ff(map);
+
+ datum = map_word_load_partial(map, datum, buf, gap, n);
+ ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
+ if (ret)
+ return ret;
+
+ offset += n;
+ buf += n;
+ size -= n;
+ }
+
+ return 0;
+}
+
+static int
+do_otp_lock(struct map_info *map, struct flchip *chip, u_long offset,
+ u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ map_word datum;
+
+ /* make sure area matches group boundaries */
+ if (size != grpsz)
+ return -EXDEV;
+
+ datum = map_word_ff(map);
+ datum = map_word_clr(map, datum, CMD(1 << grpno));
+ return do_write_oneword(map, chip, prot, datum, FL_OTP_WRITE);
+}
+
+static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf,
+ otp_op_t action, int user_regs)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ struct cfi_pri_intelext *extp = cfi->cmdset_priv;
+ struct flchip *chip;
+ struct cfi_intelext_otpinfo *otp;
+ u_long devsize, reg_prot_offset, data_offset;
+ u_int chip_num, chip_step, field, reg_fact_size, reg_user_size;
+ u_int groups, groupno, groupsize, reg_fact_groups, reg_user_groups;
+ int ret;
+
+ *retlen = 0;
+
+ /* Check that we actually have some OTP registers */
+ if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields)
+ return -ENODATA;
+
+ /* we need real chips here not virtual ones */
+ devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave;
+ chip_step = devsize >> cfi->chipshift;
+ chip_num = 0;
+
+ /* Some chips have OTP located in the _top_ partition only.
+ For example: Intel 28F256L18T (T means top-parameter device) */
+ if (cfi->mfr == MANUFACTURER_INTEL) {
+ switch (cfi->id) {
+ case 0x880b:
+ case 0x880c:
+ case 0x880d:
+ chip_num = chip_step - 1;
+ }
+ }
+
+ for ( ; chip_num < cfi->numchips; chip_num += chip_step) {
+ chip = &cfi->chips[chip_num];
+ otp = (struct cfi_intelext_otpinfo *)&extp->extra[0];
+
+ /* first OTP region */
+ field = 0;
+ reg_prot_offset = extp->ProtRegAddr;
+ reg_fact_groups = 1;
+ reg_fact_size = 1 << extp->FactProtRegSize;
+ reg_user_groups = 1;
+ reg_user_size = 1 << extp->UserProtRegSize;
+
+ while (len > 0) {
+ /* flash geometry fixup */
+ data_offset = reg_prot_offset + 1;
+ data_offset *= cfi->interleave * cfi->device_type;
+ reg_prot_offset *= cfi->interleave * cfi->device_type;
+ reg_fact_size *= cfi->interleave;
+ reg_user_size *= cfi->interleave;
+
+ if (user_regs) {
+ groups = reg_user_groups;
+ groupsize = reg_user_size;
+ /* skip over factory reg area */
+ groupno = reg_fact_groups;
+ data_offset += reg_fact_groups * reg_fact_size;
+ } else {
+ groups = reg_fact_groups;
+ groupsize = reg_fact_size;
+ groupno = 0;
+ }
+
+ while (len > 0 && groups > 0) {
+ if (!action) {
+ /*
+ * Special case: if action is NULL
+ * we fill buf with otp_info records.
+ */
+ struct otp_info *otpinfo;
+ map_word lockword;
+ len -= sizeof(struct otp_info);
+ if (len <= 0)
+ return -ENOSPC;
+ ret = do_otp_read(map, chip,
+ reg_prot_offset,
+ (u_char *)&lockword,
+ map_bankwidth(map),
+ 0, 0, 0);
+ if (ret)
+ return ret;
+ otpinfo = (struct otp_info *)buf;
+ otpinfo->start = from;
+ otpinfo->length = groupsize;
+ otpinfo->locked =
+ !map_word_bitsset(map, lockword,
+ CMD(1 << groupno));
+ from += groupsize;
+ buf += sizeof(*otpinfo);
+ *retlen += sizeof(*otpinfo);
+ } else if (from >= groupsize) {
+ from -= groupsize;
+ data_offset += groupsize;
+ } else {
+ int size = groupsize;
+ data_offset += from;
+ size -= from;
+ from = 0;
+ if (size > len)
+ size = len;
+ ret = action(map, chip, data_offset,
+ buf, size, reg_prot_offset,
+ groupno, groupsize);
+ if (ret < 0)
+ return ret;
+ buf += size;
+ len -= size;
+ *retlen += size;
+ data_offset += size;
+ }
+ groupno++;
+ groups--;
+ }
+
+ /* next OTP region */
+ if (++field == extp->NumProtectionFields)
+ break;
+ reg_prot_offset = otp->ProtRegAddr;
+ reg_fact_groups = otp->FactGroups;
+ reg_fact_size = 1 << otp->FactProtRegSize;
+ reg_user_groups = otp->UserGroups;
+ reg_user_size = 1 << otp->UserProtRegSize;
+ otp++;
+ }
+ }
+
+ return 0;
+}
+
+static int cfi_intelext_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen,
+ u_char *buf)
+{
+ return cfi_intelext_otp_walk(mtd, from, len, retlen,
+ buf, do_otp_read, 0);
+}
+
+static int cfi_intelext_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen,
+ u_char *buf)
+{
+ return cfi_intelext_otp_walk(mtd, from, len, retlen,
+ buf, do_otp_read, 1);
+}
+
+static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen,
+ u_char *buf)
+{
+ return cfi_intelext_otp_walk(mtd, from, len, retlen,
+ buf, do_otp_write, 1);
+}
+
+static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
+ loff_t from, size_t len)
+{
+ size_t retlen;
+ return cfi_intelext_otp_walk(mtd, from, len, &retlen,
+ NULL, do_otp_lock, 1);
+}
+
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ size_t retlen;
+ int ret;
+
+ ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0);
+ return ret ? : retlen;
+}
+
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ size_t retlen;
+ int ret;
+
+ ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1);
+ return ret ? : retlen;
+}
+
+#endif
+
static int cfi_intelext_suspend(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
@@ -2125,10 +2309,46 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
}
}
+static int cfi_intelext_reset(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ int i, ret;
+
+ for (i=0; i < cfi->numchips; i++) {
+ struct flchip *chip = &cfi->chips[i];
+
+ /* force the completion of any ongoing operation
+ and switch to array mode so any bootloader in
+ flash is accessible for soft reboot. */
+ spin_lock(chip->mutex);
+ ret = get_chip(map, chip, chip->start, FL_SYNCING);
+ if (!ret) {
+ map_write(map, CMD(0xff), chip->start);
+ chip->state = FL_READY;
+ }
+ spin_unlock(chip->mutex);
+ }
+
+ return 0;
+}
+
+static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
+ void *v)
+{
+ struct mtd_info *mtd;
+
+ mtd = container_of(nb, struct mtd_info, reboot_notifier);
+ cfi_intelext_reset(mtd);
+ return NOTIFY_DONE;
+}
+
static void cfi_intelext_destroy(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
+ cfi_intelext_reset(mtd);
+ unregister_reboot_notifier(&mtd->reboot_notifier);
kfree(cfi->cmdset_priv);
kfree(cfi->cfiq);
kfree(cfi->chips[0].priv);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index fca8ff6f7e1..8505f118f2d 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -4,16 +4,20 @@
*
* Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
* Copyright (C) 2004 Arcom Control Systems Ltd <linux@arcom.com>
+ * Copyright (C) 2005 MontaVista Software Inc. <source@mvista.com>
*
* 2_by_8 routines added by Simon Munton
*
* 4_by_16 work by Carolyn J. Smith
*
+ * XIP support hooks by Vitaly Wool (based on code for Intel flash
+ * by Nicolas Pitre)
+ *
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
*
* This code is GPL
*
- * $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $
*
*/
@@ -34,6 +38,7 @@
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/cfi.h>
+#include <linux/mtd/xip.h>
#define AMD_BOOTLOC_BUG
#define FORCE_WORD_WRITE 0
@@ -43,6 +48,7 @@
#define MANUFACTURER_AMD 0x0001
#define MANUFACTURER_SST 0x00BF
#define SST49LF004B 0x0060
+#define SST49LF008A 0x005a
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -191,6 +197,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
};
static struct cfi_fixup jedec_fixup_table[] = {
{ MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
+ { MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
{ 0, 0, NULL, NULL }
};
@@ -391,7 +398,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
* correctly and is therefore not done (particulary with interleaved chips
* as each chip must be checked independantly of the others).
*/
-static int chip_ready(struct map_info *map, unsigned long addr)
+static int __xipram chip_ready(struct map_info *map, unsigned long addr)
{
map_word d, t;
@@ -401,6 +408,32 @@ static int chip_ready(struct map_info *map, unsigned long addr)
return map_word_equal(map, d, t);
}
+/*
+ * Return true if the chip is ready and has the correct value.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and it is indicated by no bits toggling.
+ *
+ * Error are indicated by toggling bits or bits held with the wrong value,
+ * or with bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done (particulary with interleaved chips
+ * as each chip must be checked independantly of the others).
+ *
+ */
+static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)
+{
+ map_word oldd, curd;
+
+ oldd = map_read(map, addr);
+ curd = map_read(map, addr);
+
+ return map_word_equal(map, oldd, curd) &&
+ map_word_equal(map, curd, expected);
+}
+
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
{
DECLARE_WAITQUEUE(wait, current);
@@ -420,12 +453,12 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
if (time_after(jiffies, timeo)) {
printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return -EIO;
}
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
/* Someone else might have been playing with it. */
goto retry;
}
@@ -473,15 +506,23 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
return -EIO;
}
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
/* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
So we can just loop here. */
}
chip->state = FL_READY;
return 0;
+ case FL_XIP_WHILE_ERASING:
+ if (mode != FL_READY && mode != FL_POINT &&
+ (!cfip || !(cfip->EraseSuspend&2)))
+ goto sleep;
+ chip->oldstate = chip->state;
+ chip->state = FL_READY;
+ return 0;
+
case FL_POINT:
/* Only if there's no operation suspended... */
if (mode == FL_READY && chip->oldstate == FL_READY)
@@ -491,10 +532,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
sleep:
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
goto resettime;
}
}
@@ -512,6 +553,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
chip->state = FL_ERASING;
break;
+ case FL_XIP_WHILE_ERASING:
+ chip->state = chip->oldstate;
+ chip->oldstate = FL_READY;
+ break;
+
case FL_READY:
case FL_STATUS:
/* We should really make set_vpp() count, rather than doing this */
@@ -523,6 +569,198 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
wake_up(&chip->wq);
}
+#ifdef CONFIG_MTD_XIP
+
+/*
+ * No interrupt what so ever can be serviced while the flash isn't in array
+ * mode. This is ensured by the xip_disable() and xip_enable() functions
+ * enclosing any code path where the flash is known not to be in array mode.
+ * And within a XIP disabled code path, only functions marked with __xipram
+ * may be called and nothing else (it's a good thing to inspect generated
+ * assembly to make sure inline functions were actually inlined and that gcc
+ * didn't emit calls to its own support functions). Also configuring MTD CFI
+ * support to a single buswidth and a single interleave is also recommended.
+ */
+
+static void xip_disable(struct map_info *map, struct flchip *chip,
+ unsigned long adr)
+{
+ /* TODO: chips with no XIP use should ignore and return */
+ (void) map_read(map, adr); /* ensure mmu mapping is up to date */
+ local_irq_disable();
+}
+
+static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
+ unsigned long adr)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+
+ if (chip->state != FL_POINT && chip->state != FL_READY) {
+ map_write(map, CMD(0xf0), adr);
+ chip->state = FL_READY;
+ }
+ (void) map_read(map, adr);
+ xip_iprefetch();
+ local_irq_enable();
+}
+
+/*
+ * When a delay is required for the flash operation to complete, the
+ * xip_udelay() function is polling for both the given timeout and pending
+ * (but still masked) hardware interrupts. Whenever there is an interrupt
+ * pending then the flash erase operation is suspended, array mode restored
+ * and interrupts unmasked. Task scheduling might also happen at that
+ * point. The CPU eventually returns from the interrupt or the call to
+ * schedule() and the suspended flash operation is resumed for the remaining
+ * of the delay period.
+ *
+ * Warning: this function _will_ fool interrupt latency tracing tools.
+ */
+
+static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
+ unsigned long adr, int usec)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
+ map_word status, OK = CMD(0x80);
+ unsigned long suspended, start = xip_currtime();
+ flstate_t oldstate;
+
+ do {
+ cpu_relax();
+ if (xip_irqpending() && extp &&
+ ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
+ (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
+ /*
+ * Let's suspend the erase operation when supported.
+ * Note that we currently don't try to suspend
+ * interleaved chips if there is already another
+ * operation suspended (imagine what happens
+ * when one chip was already done with the current
+ * operation while another chip suspended it, then
+ * we resume the whole thing at once). Yes, it
+ * can happen!
+ */
+ map_write(map, CMD(0xb0), adr);
+ usec -= xip_elapsed_since(start);
+ suspended = xip_currtime();
+ do {
+ if (xip_elapsed_since(suspended) > 100000) {
+ /*
+ * The chip doesn't want to suspend
+ * after waiting for 100 msecs.
+ * This is a critical error but there
+ * is not much we can do here.
+ */
+ return;
+ }
+ status = map_read(map, adr);
+ } while (!map_word_andequal(map, status, OK, OK));
+
+ /* Suspend succeeded */
+ oldstate = chip->state;
+ if (!map_word_bitsset(map, status, CMD(0x40)))
+ break;
+ chip->state = FL_XIP_WHILE_ERASING;
+ chip->erase_suspended = 1;
+ map_write(map, CMD(0xf0), adr);
+ (void) map_read(map, adr);
+ asm volatile (".rep 8; nop; .endr");
+ local_irq_enable();
+ spin_unlock(chip->mutex);
+ asm volatile (".rep 8; nop; .endr");
+ cond_resched();
+
+ /*
+ * We're back. However someone else might have
+ * decided to go write to the chip if we are in
+ * a suspended erase state. If so let's wait
+ * until it's done.
+ */
+ spin_lock(chip->mutex);
+ while (chip->state != FL_XIP_WHILE_ERASING) {
+ DECLARE_WAITQUEUE(wait, current);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+ spin_unlock(chip->mutex);
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+ spin_lock(chip->mutex);
+ }
+ /* Disallow XIP again */
+ local_irq_disable();
+
+ /* Resume the write or erase operation */
+ map_write(map, CMD(0x30), adr);
+ chip->state = oldstate;
+ start = xip_currtime();
+ } else if (usec >= 1000000/HZ) {
+ /*
+ * Try to save on CPU power when waiting delay
+ * is at least a system timer tick period.
+ * No need to be extremely accurate here.
+ */
+ xip_cpu_idle();
+ }
+ status = map_read(map, adr);
+ } while (!map_word_andequal(map, status, OK, OK)
+ && xip_elapsed_since(start) < usec);
+}
+
+#define UDELAY(map, chip, adr, usec) xip_udelay(map, chip, adr, usec)
+
+/*
+ * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
+ * the flash is actively programming or erasing since we have to poll for
+ * the operation to complete anyway. We can't do that in a generic way with
+ * a XIP setup so do it before the actual flash operation in this case
+ * and stub it out from INVALIDATE_CACHE_UDELAY.
+ */
+#define XIP_INVAL_CACHED_RANGE(map, from, size) \
+ INVALIDATE_CACHED_RANGE(map, from, size)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
+ UDELAY(map, chip, adr, usec)
+
+/*
+ * Extra notes:
+ *
+ * Activating this XIP support changes the way the code works a bit. For
+ * example the code to suspend the current process when concurrent access
+ * happens is never executed because xip_udelay() will always return with the
+ * same chip state as it was entered with. This is why there is no care for
+ * the presence of add_wait_queue() or schedule() calls from within a couple
+ * xip_disable()'d areas of code, like in do_erase_oneblock for example.
+ * The queueing and scheduling are always happening within xip_udelay().
+ *
+ * Similarly, get_chip() and put_chip() just happen to always be executed
+ * with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
+ * is in array mode, therefore never executing many cases therein and not
+ * causing any problem with XIP.
+ */
+
+#else
+
+#define xip_disable(map, chip, adr)
+#define xip_enable(map, chip, adr)
+#define XIP_INVAL_CACHED_RANGE(x...)
+
+#define UDELAY(map, chip, adr, usec) \
+do { \
+ spin_unlock(chip->mutex); \
+ cfi_udelay(usec); \
+ spin_lock(chip->mutex); \
+} while (0)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
+do { \
+ spin_unlock(chip->mutex); \
+ INVALIDATE_CACHED_RANGE(map, adr, len); \
+ cfi_udelay(usec); \
+ spin_lock(chip->mutex); \
+} while (0)
+
+#endif
static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
{
@@ -535,10 +773,10 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
/* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -551,7 +789,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
put_chip(map, chip, cmd_addr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return 0;
}
@@ -605,7 +843,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
struct cfi_private *cfi = map->fldrv_priv;
retry:
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
if (chip->state != FL_READY){
#if 0
@@ -614,7 +852,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
@@ -643,7 +881,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
wake_up(&chip->wq);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return 0;
}
@@ -692,7 +930,7 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len,
}
-static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
+static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
@@ -712,10 +950,10 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
adr += chip->start;
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_WRITING);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -735,7 +973,9 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
goto op_done;
}
+ XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
ENABLE_VPP(map);
+ xip_disable(map, chip, adr);
retry:
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
@@ -743,9 +983,9 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
map_write(map, datum, adr);
chip->state = FL_WRITING;
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(chip->word_write_time);
- cfi_spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, map_bankwidth(map),
+ chip->word_write_time);
/* See comment above for timeout value. */
timeo = jiffies + uWriteTimeout;
@@ -756,39 +996,43 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
continue;
}
if (chip_ready(map, adr))
- goto op_done;
+ break;
- if (time_after(jiffies, timeo))
+ if (time_after(jiffies, timeo)) {
+ xip_enable(map, chip, adr);
+ printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
+ xip_disable(map, chip, adr);
break;
+ }
/* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
+ UDELAY(map, chip, adr, 1);
}
+ /* Did we succeed? */
+ if (!chip_good(map, adr, datum)) {
+ /* reset on all failures. */
+ map_write( map, CMD(0xF0), chip->start );
+ /* FIXME - should have reset delay before continuing */
- printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
-
- /* reset on all failures. */
- map_write( map, CMD(0xF0), chip->start );
- /* FIXME - should have reset delay before continuing */
- if (++retry_cnt <= MAX_WORD_RETRIES)
- goto retry;
+ if (++retry_cnt <= MAX_WORD_RETRIES)
+ goto retry;
- ret = -EIO;
+ ret = -EIO;
+ }
+ xip_enable(map, chip, adr);
op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -820,7 +1064,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
map_word tmp_buf;
retry:
- cfi_spin_lock(cfi->chips[chipnum].mutex);
+ spin_lock(cfi->chips[chipnum].mutex);
if (cfi->chips[chipnum].state != FL_READY) {
#if 0
@@ -829,7 +1073,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&cfi->chips[chipnum].wq, &wait);
- cfi_spin_unlock(cfi->chips[chipnum].mutex);
+ spin_unlock(cfi->chips[chipnum].mutex);
schedule();
remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -843,7 +1087,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
/* Load 'tmp_buf' with old contents of flash */
tmp_buf = map_read(map, bus_ofs+chipstart);
- cfi_spin_unlock(cfi->chips[chipnum].mutex);
+ spin_unlock(cfi->chips[chipnum].mutex);
/* Number of bytes to copy from buffer */
n = min_t(int, len, map_bankwidth(map)-i);
@@ -898,7 +1142,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
map_word tmp_buf;
retry1:
- cfi_spin_lock(cfi->chips[chipnum].mutex);
+ spin_lock(cfi->chips[chipnum].mutex);
if (cfi->chips[chipnum].state != FL_READY) {
#if 0
@@ -907,7 +1151,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&cfi->chips[chipnum].wq, &wait);
- cfi_spin_unlock(cfi->chips[chipnum].mutex);
+ spin_unlock(cfi->chips[chipnum].mutex);
schedule();
remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -920,7 +1164,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
tmp_buf = map_read(map, ofs + chipstart);
- cfi_spin_unlock(cfi->chips[chipnum].mutex);
+ spin_unlock(cfi->chips[chipnum].mutex);
tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
@@ -939,8 +1183,9 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
/*
* FIXME: interleaved mode not tested, and probably not supported!
*/
-static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const u_char *buf, int len)
+static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
+ unsigned long adr, const u_char *buf,
+ int len)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
@@ -954,10 +1199,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
adr += chip->start;
cmd_adr = adr;
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_WRITING);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -966,7 +1211,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
__func__, adr, datum.x[0] );
+ XIP_INVAL_CACHED_RANGE(map, adr, len);
ENABLE_VPP(map);
+ xip_disable(map, chip, cmd_adr);
+
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -996,9 +1244,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0x29), cmd_adr);
chip->state = FL_WRITING;
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(chip->buffer_write_time);
- cfi_spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, map_bankwidth(map),
+ chip->word_write_time);
timeo = jiffies + uWriteTimeout;
@@ -1009,38 +1257,39 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
continue;
}
- if (chip_ready(map, adr))
+ if (chip_ready(map, adr)) {
+ xip_enable(map, chip, adr);
goto op_done;
+ }
if( time_after(jiffies, timeo))
break;
/* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
+ UDELAY(map, chip, adr, 1);
}
- printk(KERN_WARNING "MTD %s(): software timeout\n",
- __func__ );
-
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
+ xip_enable(map, chip, adr);
/* FIXME - should have reset delay before continuing */
+ printk(KERN_WARNING "MTD %s(): software timeout\n",
+ __func__ );
+
ret = -EIO;
op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -1130,7 +1379,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
* Handle devices with one erase region, that only implement
* the chip erase command.
*/
-static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
+static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
@@ -1140,17 +1389,20 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
adr = cfi->addr_unlock1;
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_WRITING);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
__func__, chip->start );
+ XIP_INVAL_CACHED_RANGE(map, adr, map->size);
ENABLE_VPP(map);
+ xip_disable(map, chip, adr);
+
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1162,9 +1414,9 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
chip->erase_suspended = 0;
chip->in_progress_block_addr = adr;
- cfi_spin_unlock(chip->mutex);
- msleep(chip->erase_time/2);
- cfi_spin_lock(chip->mutex);
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, map->size,
+ chip->erase_time*500);
timeo = jiffies + (HZ*20);
@@ -1173,10 +1425,10 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
/* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
continue;
}
if (chip->erase_suspended) {
@@ -1187,36 +1439,36 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
}
if (chip_ready(map, adr))
- goto op_done;
+ break;
- if (time_after(jiffies, timeo))
+ if (time_after(jiffies, timeo)) {
+ printk(KERN_WARNING "MTD %s(): software timeout\n",
+ __func__ );
break;
+ }
/* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- cfi_spin_lock(chip->mutex);
+ UDELAY(map, chip, adr, 1000000/HZ);
}
+ /* Did we succeed? */
+ if (!chip_good(map, adr, map_word_ff(map))) {
+ /* reset on all failures. */
+ map_write( map, CMD(0xF0), chip->start );
+ /* FIXME - should have reset delay before continuing */
- printk(KERN_WARNING "MTD %s(): software timeout\n",
- __func__ );
-
- /* reset on all failures. */
- map_write( map, CMD(0xF0), chip->start );
- /* FIXME - should have reset delay before continuing */
+ ret = -EIO;
+ }
- ret = -EIO;
- op_done:
chip->state = FL_READY;
+ xip_enable(map, chip, adr);
put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
-static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
+static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
@@ -1225,17 +1477,20 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
adr += chip->start;
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_ERASING);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
__func__, adr );
+ XIP_INVAL_CACHED_RANGE(map, adr, len);
ENABLE_VPP(map);
+ xip_disable(map, chip, adr);
+
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1246,10 +1501,10 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
chip->state = FL_ERASING;
chip->erase_suspended = 0;
chip->in_progress_block_addr = adr;
-
- cfi_spin_unlock(chip->mutex);
- msleep(chip->erase_time/2);
- cfi_spin_lock(chip->mutex);
+
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, len,
+ chip->erase_time*500);
timeo = jiffies + (HZ*20);
@@ -1258,10 +1513,10 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
/* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
continue;
}
if (chip->erase_suspended) {
@@ -1271,31 +1526,33 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr))
- goto op_done;
+ if (chip_ready(map, adr)) {
+ xip_enable(map, chip, adr);
+ break;
+ }
- if (time_after(jiffies, timeo))
+ if (time_after(jiffies, timeo)) {
+ xip_enable(map, chip, adr);
+ printk(KERN_WARNING "MTD %s(): software timeout\n",
+ __func__ );
break;
+ }
/* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- cfi_spin_lock(chip->mutex);
+ UDELAY(map, chip, adr, 1000000/HZ);
+ }
+ /* Did we succeed? */
+ if (!chip_good(map, adr, map_word_ff(map))) {
+ /* reset on all failures. */
+ map_write( map, CMD(0xF0), chip->start );
+ /* FIXME - should have reset delay before continuing */
+
+ ret = -EIO;
}
-
- printk(KERN_WARNING "MTD %s(): software timeout\n",
- __func__ );
-
- /* reset on all failures. */
- map_write( map, CMD(0xF0), chip->start );
- /* FIXME - should have reset delay before continuing */
- ret = -EIO;
- op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -1355,7 +1612,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
chip = &cfi->chips[i];
retry:
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
switch(chip->state) {
case FL_READY:
@@ -1369,14 +1626,14 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
* with the chip now anyway.
*/
case FL_SYNCING:
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
break;
default:
/* Not an idle state */
add_wait_queue(&chip->wq, &wait);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
schedule();
@@ -1391,13 +1648,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
}
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
}
}
@@ -1413,7 +1670,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
for (i=0; !ret && i<cfi->numchips; i++) {
chip = &cfi->chips[i];
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
switch(chip->state) {
case FL_READY:
@@ -1433,7 +1690,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
ret = -EAGAIN;
break;
}
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
}
/* Unlock the chips again */
@@ -1442,13 +1699,13 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
}
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
}
}
@@ -1467,7 +1724,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
chip = &cfi->chips[i];
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) {
chip->state = FL_READY;
@@ -1477,7 +1734,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
else
printk(KERN_ERR "Argh. Chip not in PM_SUSPENDED state upon resume()\n");
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
}
}
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index fbf44708a86..e1a5b76596c 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -58,10 +58,10 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
* to flash memory - that means that we don't have to check status
* and timeout.
*/
- cfi_spin_lock(chip->mutex);
+ spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_LOCKING);
if (ret) {
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return ret;
}
@@ -71,7 +71,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
/* Done and happy. */
chip->state = FL_READY;
put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
+ spin_unlock(chip->mutex);
return 0;
}
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index fc982c4671f..dc065b22f79 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
* Routines common to all CFI-type probes.
* (C) 2001-2003 Red Hat, Inc.
* GPL'd
- * $Id: gen_probe.c,v 1.21 2004/08/14 15:14:05 dwmw2 Exp $
+ * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $
*/
#include <linux/kernel.h>
@@ -162,7 +162,7 @@ static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
int max_chips = map_bankwidth(map); /* And minimum 1 */
int nr_chips, type;
- for (nr_chips = min_chips; nr_chips <= max_chips; nr_chips <<= 1) {
+ for (nr_chips = max_chips; nr_chips >= min_chips; nr_chips >>= 1) {
if (!cfi_interleave_supported(nr_chips))
continue;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 30325a25ab9..30da428eb7b 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
- $Id: jedec_probe.c,v 1.61 2004/11/19 20:52:16 thayne Exp $
+ $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
for the standard this probe goes back to.
@@ -142,6 +142,7 @@
#define SST29LE512 0x003d
#define SST39LF800 0x2781
#define SST39LF160 0x2782
+#define SST39VF1601 0x234b
#define SST39LF512 0x00D4
#define SST39LF010 0x00D5
#define SST39LF020 0x00D6
@@ -1448,6 +1449,21 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x1000,256),
ERASEINFO(0x1000,256)
}
+ }, {
+ .mfr_id = MANUFACTURER_SST, /* should be CFI */
+ .dev_id = SST39VF1601,
+ .name = "SST 39VF1601",
+ .uaddr = {
+ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
+ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
+ },
+ .DevSize = SIZE_2MiB,
+ .CmdSet = P_ID_AMD_STD,
+ .NumEraseRegions= 2,
+ .regions = {
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256)
+ }
}, {
.mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
@@ -1856,6 +1872,16 @@ static inline int jedec_match( __u32 base,
case CFI_DEVICETYPE_X8:
mfr = (__u8)finfo->mfr_id;
id = (__u8)finfo->dev_id;
+
+ /* bjd: it seems that if we do this, we can end up
+ * detecting 16bit flashes as an 8bit device, even though
+ * there aren't.
+ */
+ if (finfo->dev_id > 0xff) {
+ DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
+ __func__);
+ goto match_done;
+ }
break;
case CFI_DEVICETYPE_X16:
mfr = (__u16)finfo->mfr_id;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 60ab4b89a2f..ef24837019d 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,5 +1,5 @@
/*
- * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
+ * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $
*
* Read flash partition table from command line
*
@@ -239,7 +239,8 @@ static int mtdpart_setup_real(char *s)
&num_parts, /* out: number of parts */
0, /* first partition */
(unsigned char**)&this_mtd, /* out: extra mem */
- mtd_id_len + 1 + sizeof(*this_mtd));
+ mtd_id_len + 1 + sizeof(*this_mtd) +
+ sizeof(void*)-1 /*alignment*/);
if(!parts)
{
/*
@@ -252,6 +253,9 @@ static int mtdpart_setup_real(char *s)
return 0;
}
+ /* align this_mtd */
+ this_mtd = (struct cmdline_mtd_partition *)
+ ALIGN((unsigned long)this_mtd, sizeof(void*));
/* enter results */
this_mtd->parts = parts;
this_mtd->num_parts = num_parts;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index cfe6ccf0797..4a7a805e756 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,10 +1,9 @@
/*
- * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 Exp $
+ * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $
*
* block2mtd.c - create an mtd from a block device
*
* Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk>
- * Copyright (C) 2004 Gareth Bult <Gareth@Encryptec.net>
* Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de>
*
* Licence: GPL
@@ -20,7 +19,7 @@
#include <linux/mtd/mtd.h>
#include <linux/buffer_head.h>
-#define VERSION "$Revision: 1.23 $"
+#define VERSION "$Revision: 1.28 $"
#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -89,7 +88,6 @@ void cache_readahead(struct address_space *mapping, int index)
static struct page* page_readahead(struct address_space *mapping, int index)
{
filler_t *filler = (filler_t*)mapping->a_ops->readpage;
- //do_page_cache_readahead(mapping, index, XXX, 64);
cache_readahead(mapping, index);
return read_cache_page(mapping, index, filler, NULL);
}
@@ -157,7 +155,7 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
struct block2mtd_dev *dev = mtd->priv;
struct page *page;
int index = from >> PAGE_SHIFT;
- int offset = from & (PAGE_SHIFT-1);
+ int offset = from & (PAGE_SIZE-1);
int cpylen;
if (from > mtd->size)
@@ -370,16 +368,16 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
}
-static int parse_num32(u32 *num32, const char *token)
+static int parse_num(size_t *num, const char *token)
{
char *endp;
- unsigned long n;
+ size_t n;
- n = ustrtoul(token, &endp, 0);
+ n = (size_t) ustrtoul(token, &endp, 0);
if (*endp)
return -EINVAL;
- *num32 = n;
+ *num = n;
return 0;
}
@@ -422,7 +420,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
char *token[2];
char *name;
- u32 erase_size = PAGE_SIZE;
+ size_t erase_size = PAGE_SIZE;
int i, ret;
if (strnlen(val, sizeof(buf)) >= sizeof(buf))
@@ -449,7 +447,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
return 0;
if (token[1]) {
- ret = parse_num32(&erase_size, token[1]);
+ ret = parse_num(&erase_size, token[1]);
if (ret)
parse_err("illegal erase size");
}
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 380ff08d29e..f5026cee087 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -6,7 +6,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * $Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $
*/
#include <linux/init.h>
@@ -99,8 +99,8 @@ static inline uint ms02nv_probe_one(ulong addr)
* The firmware writes MS02NV_ID at MS02NV_MAGIC and also
* a diagnostic status at MS02NV_DIAG.
*/
- ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG));
- ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC));
+ ms02nv_diagp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_DIAG));
+ ms02nv_magicp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_MAGIC));
err = get_dbe(ms02nv_magic, ms02nv_magicp);
if (err)
return 0;
@@ -233,7 +233,7 @@ static int __init ms02nv_init_one(ulong addr)
goto err_out_csr_res;
}
- printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n",
+ printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %zuMiB.\n",
mtd->index, ms02nv_name, addr, size >> 20);
mp->next = root_ms02nv_mtd;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index edac4156d69..bb713fed2f3 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -1,9 +1,10 @@
/*
* mtdram - a test mtd device
- * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $
* Author: Alexander Larsson <alex@cendio.se>
*
* Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
+ * Copyright (c) 2005 Joern Engel <joern@wh.fh-wedel.de>
*
* This code is GPL
*
@@ -18,213 +19,140 @@
#include <linux/mtd/compatmac.h>
#include <linux/mtd/mtd.h>
-#ifndef CONFIG_MTDRAM_ABS_POS
- #define CONFIG_MTDRAM_ABS_POS 0
-#endif
-
-#if CONFIG_MTDRAM_ABS_POS > 0
- #include <asm/io.h>
-#endif
-
-#ifdef MODULE
static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
-module_param(total_size,ulong,0);
-MODULE_PARM_DESC(total_size, "Total device size in KiB");
-module_param(erase_size,ulong,0);
-MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
#define MTDRAM_TOTAL_SIZE (total_size * 1024)
#define MTDRAM_ERASE_SIZE (erase_size * 1024)
-#else
-#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
-#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
-#endif
+#ifdef MODULE
+module_param(total_size, ulong, 0);
+MODULE_PARM_DESC(total_size, "Total device size in KiB");
+module_param(erase_size, ulong, 0);
+MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
+#endif
// We could store these in the mtd structure, but we only support 1 device..
static struct mtd_info *mtd_info;
-
-static int
-ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
{
- DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len);
- if (instr->addr + instr->len > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size);
- return -EINVAL;
- }
-
- memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
-
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return 0;
+ if (instr->addr + instr->len > mtd->size)
+ return -EINVAL;
+
+ memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
+
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
}
-static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char **mtdbuf)
{
- if (from + len > mtd->size)
- return -EINVAL;
-
- *mtdbuf = mtd->priv + from;
- *retlen = len;
- return 0;
+ if (from + len > mtd->size)
+ return -EINVAL;
+
+ *mtdbuf = mtd->priv + from;
+ *retlen = len;
+ return 0;
}
-static void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len)
+static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
+ size_t len)
{
- DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n");
}
static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char *buf)
+ size_t *retlen, u_char *buf)
{
- DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len);
- if (from + len > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size);
- return -EINVAL;
- }
+ if (from + len > mtd->size)
+ return -EINVAL;
- memcpy(buf, mtd->priv + from, len);
+ memcpy(buf, mtd->priv + from, len);
- *retlen=len;
- return 0;
+ *retlen = len;
+ return 0;
}
static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf)
+ size_t *retlen, const u_char *buf)
{
- DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len);
- if (to + len > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size);
- return -EINVAL;
- }
+ if (to + len > mtd->size)
+ return -EINVAL;
- memcpy ((char *)mtd->priv + to, buf, len);
+ memcpy((char *)mtd->priv + to, buf, len);
- *retlen=len;
- return 0;
+ *retlen = len;
+ return 0;
}
static void __exit cleanup_mtdram(void)
{
- if (mtd_info) {
- del_mtd_device(mtd_info);
-#if CONFIG_MTDRAM_TOTAL_SIZE > 0
- if (mtd_info->priv)
-#if CONFIG_MTDRAM_ABS_POS > 0
- iounmap(mtd_info->priv);
-#else
- vfree(mtd_info->priv);
-#endif
-#endif
- kfree(mtd_info);
- }
-}
-
-int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
- unsigned long size, char *name)
-{
- memset(mtd, 0, sizeof(*mtd));
-
- /* Setup the MTD structure */
- mtd->name = name;
- mtd->type = MTD_RAM;
- mtd->flags = MTD_CAP_RAM;
- mtd->size = size;
- mtd->erasesize = MTDRAM_ERASE_SIZE;
- mtd->priv = mapped_address;
-
- mtd->owner = THIS_MODULE;
- mtd->erase = ram_erase;
- mtd->point = ram_point;
- mtd->unpoint = ram_unpoint;
- mtd->read = ram_read;
- mtd->write = ram_write;
-
- if (add_mtd_device(mtd)) {
- return -EIO;
- }
-
- return 0;
-}
-
-#if CONFIG_MTDRAM_TOTAL_SIZE > 0
-#if CONFIG_MTDRAM_ABS_POS > 0
-static int __init init_mtdram(void)
-{
- void *addr;
- int err;
- /* Allocate some memory */
- mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
- if (!mtd_info)
- return -ENOMEM;
-
- addr = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
- if (!addr) {
- DEBUG(MTD_DEBUG_LEVEL1,
- "Failed to ioremap) memory region of size %ld at ABS_POS:%ld\n",
- (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS);
- kfree(mtd_info);
- mtd_info = NULL;
- return -ENOMEM;
- }
- err = mtdram_init_device(mtd_info, addr,
- MTDRAM_TOTAL_SIZE, "mtdram test device");
- if (err)
- {
- iounmap(addr);
- kfree(mtd_info);
- mtd_info = NULL;
- return err;
- }
- memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
- return err;
+ if (mtd_info) {
+ del_mtd_device(mtd_info);
+ if (mtd_info->priv)
+ vfree(mtd_info->priv);
+ kfree(mtd_info);
+ }
}
-#else /* CONFIG_MTDRAM_ABS_POS > 0 */
-
-static int __init init_mtdram(void)
+int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
+ unsigned long size, char *name)
{
- void *addr;
- int err;
- /* Allocate some memory */
- mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
- if (!mtd_info)
- return -ENOMEM;
-
- addr = vmalloc(MTDRAM_TOTAL_SIZE);
- if (!addr) {
- DEBUG(MTD_DEBUG_LEVEL1,
- "Failed to vmalloc memory region of size %ld\n",
- (long)MTDRAM_TOTAL_SIZE);
- kfree(mtd_info);
- mtd_info = NULL;
- return -ENOMEM;
- }
- err = mtdram_init_device(mtd_info, addr,
- MTDRAM_TOTAL_SIZE, "mtdram test device");
- if (err)
- {
- vfree(addr);
- kfree(mtd_info);
- mtd_info = NULL;
- return err;
- }
- memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
- return err;
+ memset(mtd, 0, sizeof(*mtd));
+
+ /* Setup the MTD structure */
+ mtd->name = name;
+ mtd->type = MTD_RAM;
+ mtd->flags = MTD_CAP_RAM;
+ mtd->size = size;
+ mtd->erasesize = MTDRAM_ERASE_SIZE;
+ mtd->priv = mapped_address;
+
+ mtd->owner = THIS_MODULE;
+ mtd->erase = ram_erase;
+ mtd->point = ram_point;
+ mtd->unpoint = ram_unpoint;
+ mtd->read = ram_read;
+ mtd->write = ram_write;
+
+ if (add_mtd_device(mtd)) {
+ return -EIO;
+ }
+
+ return 0;
}
-#endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */
-
-#else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */
static int __init init_mtdram(void)
{
- return 0;
+ void *addr;
+ int err;
+
+ if (!total_size)
+ return -EINVAL;
+
+ /* Allocate some memory */
+ mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+ if (!mtd_info)
+ return -ENOMEM;
+
+ addr = vmalloc(MTDRAM_TOTAL_SIZE);
+ if (!addr) {
+ kfree(mtd_info);
+ mtd_info = NULL;
+ return -ENOMEM;
+ }
+ err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device");
+ if (err) {
+ vfree(addr);
+ kfree(mtd_info);
+ mtd_info = NULL;
+ return err;
+ }
+ memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
+ return err;
}
-#endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */
module_init(init_mtdram);
module_exit(cleanup_mtdram);
@@ -232,4 +160,3 @@ module_exit(cleanup_mtdram);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
MODULE_DESCRIPTION("Simulated MTD driver for testing");
-
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 5f8e164ddb7..a423a382095 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
/**
- * $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $
+ * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $
*
* Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
* Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -15,9 +15,7 @@
*
* Example:
* phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
- *
*/
-
#include <asm/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -36,7 +34,6 @@ struct phram_mtd_list {
static LIST_HEAD(phram_list);
-
static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
{
u_char *start = mtd->priv;
@@ -71,7 +68,8 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
return 0;
}
-static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
+ size_t len)
{
}
@@ -80,8 +78,11 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
{
u_char *start = mtd->priv;
- if (from + len > mtd->size)
+ if (from >= mtd->size)
return -EINVAL;
+
+ if (len > mtd->size - from)
+ len = mtd->size - from;
memcpy(buf, start + from, len);
@@ -94,8 +95,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
{
u_char *start = mtd->priv;
- if (to + len > mtd->size)
+ if (to >= mtd->size)
return -EINVAL;
+
+ if (len > mtd->size - to)
+ len = mtd->size - to;
memcpy(start + to, buf, len);
@@ -107,9 +111,9 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
static void unregister_devices(void)
{
- struct phram_mtd_list *this;
+ struct phram_mtd_list *this, *safe;
- list_for_each_entry(this, &phram_list, list) {
+ list_for_each_entry_safe(this, safe, &phram_list, list) {
del_mtd_device(&this->mtd);
iounmap(this->mtd.priv);
kfree(this);
@@ -145,7 +149,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
new->mtd.write = phram_write;
new->mtd.owner = THIS_MODULE;
new->mtd.type = MTD_RAM;
- new->mtd.erasesize = 0;
+ new->mtd.erasesize = PAGE_SIZE;
ret = -EAGAIN;
if (add_mtd_device(&new->mtd)) {
@@ -214,6 +218,15 @@ static int parse_name(char **pname, const char *token)
return 0;
}
+
+static inline void kill_final_newline(char *str)
+{
+ char *newline = strrchr(str, '\n');
+ if (newline && !newline[1])
+ *newline = 0;
+}
+
+
#define parse_err(fmt, args...) do { \
ERROR(fmt , ## args); \
return 0; \
@@ -232,6 +245,7 @@ static int phram_setup(const char *val, struct kernel_param *kp)
parse_err("parameter too long\n");
strcpy(str, val);
+ kill_final_newline(str);
for (i=0; i<3; i++)
token[i] = strsep(&str, ",");
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 5ab15e643be..84fa91392a8 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
/*======================================================================
- $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 Exp $
+ $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $
This driver provides a method to access memory not used by the kernel
itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -50,6 +50,7 @@
#include <linux/mtd/mtd.h>
#define SLRAM_MAX_DEVICES_PARAMS 6 /* 3 parameters / device */
+#define SLRAM_BLK_SZ 0x4000
#define T(fmt, args...) printk(KERN_DEBUG fmt, ## args)
#define E(fmt, args...) printk(KERN_NOTICE fmt, ## args)
@@ -108,6 +109,9 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
{
slram_priv_t *priv = mtd->priv;
+ if (from + len > mtd->size)
+ return -EINVAL;
+
*mtdbuf = priv->start + from;
*retlen = len;
return(0);
@@ -121,7 +125,13 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
slram_priv_t *priv = mtd->priv;
-
+
+ if (from > mtd->size)
+ return -EINVAL;
+
+ if (from + len > mtd->size)
+ len = mtd->size - from;
+
memcpy(buf, priv->start + from, len);
*retlen = len;
@@ -133,6 +143,9 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
{
slram_priv_t *priv = mtd->priv;
+ if (to + len > mtd->size)
+ return -EINVAL;
+
memcpy(priv->start + to, buf, len);
*retlen = len;
@@ -188,7 +201,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
(*curmtd)->mtdinfo->name = name;
(*curmtd)->mtdinfo->size = length;
(*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS |
- MTD_WRITEB_WRITEABLE | MTD_VOLATILE;
+ MTD_WRITEB_WRITEABLE | MTD_VOLATILE | MTD_CAP_RAM;
(*curmtd)->mtdinfo->erase = slram_erase;
(*curmtd)->mtdinfo->point = slram_point;
(*curmtd)->mtdinfo->unpoint = slram_unpoint;
@@ -196,7 +209,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
(*curmtd)->mtdinfo->write = slram_write;
(*curmtd)->mtdinfo->owner = THIS_MODULE;
(*curmtd)->mtdinfo->type = MTD_RAM;
- (*curmtd)->mtdinfo->erasesize = 0x0;
+ (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
if (add_mtd_device((*curmtd)->mtdinfo)) {
E("slram: Failed to register new device\n");
@@ -261,7 +274,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
}
T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
devname, devstart, devlength);
- if ((devstart < 0) || (devlength < 0)) {
+ if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
E("slram: Illegal start / length parameter.\n");
return(-EINVAL);
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index 18cc8846e73..d9ab60b36fd 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.54 2004/11/16 18:33:15 dwmw2 Exp $
+ * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $
*
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -357,6 +357,7 @@ static int erase_xfer(partition_t *part,
if (!erase)
return -ENOMEM;
+ erase->mtd = part->mbd.mtd;
erase->callback = ftl_erase_callback;
erase->addr = xfer->Offset;
erase->len = 1 << part->header.EraseUnitSize;
@@ -1096,7 +1097,7 @@ struct mtd_blktrans_ops ftl_tr = {
int init_ftl(void)
{
- DEBUG(0, "$Id: ftl.c,v 1.54 2004/11/16 18:33:15 dwmw2 Exp $\n");
+ DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n");
return register_mtd_blktrans(&ftl_tr);
}
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 2bea2e0b06f..44781a83b2e 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $
+# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
@@ -122,16 +122,6 @@ config MTD_SBC_GXX
More info at
<http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>.
-config MTD_ELAN_104NC
- tristate "CFI Flash device mapped on Arcom ELAN-104NC"
- depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS
- help
- This provides a driver for the on-board flash of the Arcom Control
- System's ELAN-104NC development board. By default the flash
- is split into 3 partitions which are accessed as separate MTD
- devices. This board utilizes Intel StrataFlash. More info at
- <http://www.arcomcontrols.com/products/icp/pc104/processors/ELAN104NC.htm>.
-
config MTD_LUBBOCK
tristate "CFI Flash device mapped on Intel Lubbock XScale eval board"
depends on ARCH_LUBBOCK && MTD_CFI_INTELEXT && MTD_PARTITIONS
@@ -139,6 +129,14 @@ config MTD_LUBBOCK
This provides a driver for the on-board flash of the Intel
'Lubbock' XScale evaluation board.
+config MTD_MAINSTONE
+ tristate "CFI Flash device mapped on Intel Mainstone XScale eval board"
+ depends on MACH_MAINSTONE && MTD_CFI_INTELEXT
+ select MTD_PARTITIONS
+ help
+ This provides a driver for the on-board flash of the Intel
+ 'Mainstone PXA27x evaluation board.
+
config MTD_OCTAGON
tristate "JEDEC Flash device mapped on Octagon 5066 SBC"
depends on X86 && MTD_JEDEC && MTD_COMPLEX_MAPPINGS
@@ -213,74 +211,11 @@ config MTD_NETtel
help
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
-config MTD_PB1XXX
- tristate "Flash devices on Alchemy PB1xxx boards"
- depends on MIPS && ( MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 )
- help
- Flash memory access on Alchemy Pb1000/Pb1100/Pb1500 boards
-
-config MTD_PB1XXX_BOOT
- bool "PB1x00 boot flash device"
- depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
- help
- Use the first of the two 32MiB flash banks on Pb1100/Pb1500 board.
- You can say 'Y' to both this and 'MTD_PB1XXX_USER' below, to use
- both banks.
-
-config MTD_PB1XXX_USER
- bool "PB1x00 user flash device"
- depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
- default y if MTD_PB1XX_BOOT = n
- help
- Use the second of the two 32MiB flash banks on Pb1100/Pb1500 board.
- You can say 'Y' to both this and 'MTD_PB1XXX_BOOT' above, to use
- both banks.
-
-config MTD_PB1550
- tristate "Flash devices on Alchemy PB1550 board"
- depends on MIPS && MIPS_PB1550
- help
- Flash memory access on Alchemy Pb1550 board
-
-config MTD_PB1550_BOOT
- bool "PB1550 boot flash device"
- depends on MTD_PB1550
+config MTD_ALCHEMY
+ tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
+ depends on MIPS && SOC_AU1X00
help
- Use the first of the two 64MiB flash banks on Pb1550 board.
- You can say 'Y' to both this and 'MTD_PB1550_USER' below, to use
- both banks.
-
-config MTD_PB1550_USER
- bool "PB1550 user flash device"
- depends on MTD_PB1550
- default y if MTD_PB1550_BOOT = n
- help
- Use the second of the two 64MiB flash banks on Pb1550 board.
- You can say 'Y' to both this and 'MTD_PB1550_BOOT' above, to use
- both banks.
-
-config MTD_DB1550
- tristate "Flash devices on Alchemy DB1550 board"
- depends on MIPS && MIPS_DB1550
- help
- Flash memory access on Alchemy Db1550 board
-
-config MTD_DB1550_BOOT
- bool "DB1550 boot flash device"
- depends on MTD_DB1550
- help
- Use the first of the two 64MiB flash banks on Db1550 board.
- You can say 'Y' to both this and 'MTD_DB1550_USER' below, to use
- both banks.
-
-config MTD_DB1550_USER
- bool "DB1550 user flash device"
- depends on MTD_DB1550
- default y if MTD_DB1550_BOOT = n
- help
- Use the second of the two 64MiB flash banks on Db1550 board.
- You can say 'Y' to both this and 'MTD_DB1550_BOOT' above, to use
- both banks.
+ Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
@@ -588,6 +523,15 @@ config MTD_MPC1211
This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
If you have such a board, say 'Y'.
+config MTD_OMAP_NOR
+ tristate "TI OMAP board mappings"
+ depends on MTD_CFI && ARCH_OMAP
+ help
+ This enables access to the NOR flash chips on TI OMAP-based
+ boards defining flash platform devices and flash platform data.
+ These boards include the Innovator, H2, H3, OSK, Perseus2, and
+ more. If you have such a board, say 'Y'.
+
# This needs CFI or JEDEC, depending on the cards found.
config MTD_PCI
tristate "PCI MTD driver"
@@ -647,13 +591,14 @@ config MTD_DMV182
Map driver for Dy-4 SVME/DMV-182 board.
config MTD_BAST
- tristate "Map driver for Simtec BAST (EB2410ITX)"
- depends on ARCH_BAST
+ tristate "Map driver for Simtec BAST (EB2410ITX) or Thorcom VR1000"
+ depends on ARCH_BAST || MACH_VR1000
select MTD_PARTITIONS
select MTD_MAP_BANK_WIDTH_16
select MTD_JEDECPROBE
help
- Map driver for NOR flash on the Simtec BAST (EB2410ITX).
+ Map driver for NOR flash on the Simtec BAST (EB2410ITX), or the
+ Thorcom VR1000
Note, this driver *cannot* over-ride the WP link on the
board, or currently detect the state of the link.
@@ -669,5 +614,15 @@ config MTD_SHARP_SL
help
This enables access to the flash chip on the Sharp SL Series of PDAs.
+config MTD_PLATRAM
+ tristate "Map driver for platform device RAM (mtd-ram)"
+ depends on MTD
+ select MTD_RAM
+ help
+ Map driver for RAM areas described via the platform device
+ system.
+
+ This selection automatically selects the map_ram driver.
+
endmenu
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7ffe02b8530..7bcbc49e329 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
#
# linux/drivers/maps/Makefile
#
-# $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $
+# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $
ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
obj-$(CONFIG_MTD) += map_funcs.o
@@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
obj-$(CONFIG_MTD_DC21285) += dc21285.o
obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
-obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o
obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
obj-$(CONFIG_MTD_IQ80310) += iq80310.o
obj-$(CONFIG_MTD_L440GX) += l440gx.o
@@ -23,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
+obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
obj-$(CONFIG_MTD_MBX860) += mbx860.o
obj-$(CONFIG_MTD_CEIVA) += ceiva.o
obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
@@ -44,10 +44,7 @@ obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o
obj-$(CONFIG_MTD_OCELOT) += ocelot.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
obj-$(CONFIG_MTD_PCI) += pci.o
-obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
-obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
-obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o
-obj-$(CONFIG_MTD_DB1550) += db1550-flash.o
+obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
obj-$(CONFIG_MTD_LASAT) += lasat.o
obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
@@ -71,3 +68,5 @@ obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
+obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
+obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
new file mode 100644
index 00000000000..27fd2a3c3b6
--- /dev/null
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -0,0 +1,192 @@
+/*
+ * Flash memory access on AMD Alchemy evaluation boards
+ *
+ * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $
+ *
+ * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+
+#ifdef DEBUG_RW
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#ifdef CONFIG_MIPS_PB1000
+#define BOARD_MAP_NAME "Pb1000 Flash"
+#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1500
+#define BOARD_MAP_NAME "Pb1500 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1100
+#define BOARD_MAP_NAME "Pb1100 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1550
+#define BOARD_MAP_NAME "Pb1550 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1200
+#define BOARD_MAP_NAME "Pb1200 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1000
+#define BOARD_MAP_NAME "Db1000 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1500
+#define BOARD_MAP_NAME "Db1500 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1100
+#define BOARD_MAP_NAME "Db1100 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+#define BOARD_MAP_NAME "Db1550 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#define BOARD_MAP_NAME "Db1200 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_HYDROGEN3
+#define BOARD_MAP_NAME "Hydrogen3 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#define USE_LOCAL_ACCESSORS /* why? */
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+#define BOARD_MAP_NAME "Bosporus Flash"
+#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_MIRAGE
+#define BOARD_MAP_NAME "Mirage Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#define USE_LOCAL_ACCESSORS /* why? */
+#endif
+
+static struct map_info alchemy_map = {
+ .name = BOARD_MAP_NAME,
+};
+
+static struct mtd_partition alchemy_partitions[] = {
+ {
+ .name = "User FS",
+ .size = BOARD_FLASH_SIZE - 0x00400000,
+ .offset = 0x0000000
+ },{
+ .name = "YAMON",
+ .size = 0x0100000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE
+ },{
+ .name = "raw kernel",
+ .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *mymtd;
+
+int __init alchemy_mtd_init(void)
+{
+ struct mtd_partition *parts;
+ int nb_parts = 0;
+ unsigned long window_addr;
+ unsigned long window_size;
+
+ /* Default flash buswidth */
+ alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
+
+ window_addr = 0x20000000 - BOARD_FLASH_SIZE;
+ window_size = BOARD_FLASH_SIZE;
+#ifdef CONFIG_MIPS_MIRAGE_WHY
+ /* Boot ROM flash bank only; no user bank */
+ window_addr = 0x1C000000;
+ window_size = 0x04000000;
+ /* USERFS from 0x1C00 0000 to 0x1FC00000 */
+ alchemy_partitions[0].size = 0x03C00000;
+#endif
+
+ /*
+ * Static partition definition selection
+ */
+ parts = alchemy_partitions;
+ nb_parts = NB_OF(alchemy_partitions);
+ alchemy_map.size = window_size;
+
+ /*
+ * Now let's probe for the actual flash. Do it here since
+ * specific machine settings might have been set above.
+ */
+ printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
+ alchemy_map.bankwidth*8);
+ alchemy_map.virt = ioremap(window_addr, window_size);
+ mymtd = do_map_probe("cfi_probe", &alchemy_map);
+ if (!mymtd) {
+ iounmap(alchemy_map.virt);
+ return -ENXIO;
+ }
+ mymtd->owner = THIS_MODULE;
+
+ add_mtd_partitions(mymtd, parts, nb_parts);
+ return 0;
+}
+
+static void __exit alchemy_mtd_cleanup(void)
+{
+ if (mymtd) {
+ del_mtd_partitions(mymtd);
+ map_destroy(mymtd);
+ iounmap(alchemy_map.virt);
+ }
+}
+
+module_init(alchemy_mtd_init);
+module_exit(alchemy_mtd_cleanup);
+
+MODULE_AUTHOR("Embedded Alley Solutions, Inc");
+MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 51e97b05304..e8a900a7768 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
* amd76xrom.c
*
* Normal mappings of chips in physical memory
- * $Id: amd76xrom.c,v 1.19 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $
*/
#include <linux/module.h>
@@ -314,7 +314,7 @@ static int __init init_amd76xrom(void)
}
return -ENXIO;
#if 0
- return pci_module_init(&amd76xrom_driver);
+ return pci_register_driver(&amd76xrom_driver);
#endif
}
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 44de3a81b27..0c45464e3f7 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -1,14 +1,15 @@
/* linux/drivers/mtd/maps/bast_flash.c
*
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
*
* Simtec Bast (EB2410ITX) NOR MTD Mapping driver
*
* Changelog:
* 20-Sep-2004 BJD Initial version
+ * 17-Jan-2005 BJD Add whole device if no partitions found
*
- * $Id: bast-flash.c,v 1.1 2004/09/21 14:29:04 bjd Exp $
+ * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,9 +47,9 @@
#include <asm/arch/bast-cpld.h>
#ifdef CONFIG_MTD_BAST_MAXSIZE
-#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * (1024*1024))
+#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M)
#else
-#define AREA_MAXSIZE (32*1024*1024)
+#define AREA_MAXSIZE (32 * SZ_1M)
#endif
#define PFX "bast-flash: "
@@ -189,6 +190,8 @@ static int bast_flash_probe(struct device *dev)
err = add_mtd_partitions(info->mtd, info->partitions, err);
if (err)
printk(KERN_ERR PFX "cannot add/parse partitions\n");
+ } else {
+ err = add_mtd_device(info->mtd);
}
if (err == 0)
diff --git a/drivers/mtd/maps/db1550-flash.c b/drivers/mtd/maps/db1550-flash.c
deleted file mode 100644
index d213888462a..00000000000
--- a/drivers/mtd/maps/db1550-flash.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Flash memory access on Alchemy Db1550 board
- *
- * $Id: db1550-flash.c,v 1.7 2004/11/04 13:24:14 gleixner Exp $
- *
- * (C) 2004 Embedded Edge, LLC, based on db1550-flash.c:
- * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef DEBUG_RW
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-
-
-static struct map_info db1550_map = {
- .name = "Db1550 flash",
-};
-
-static unsigned char flash_bankwidth = 4;
-
-/*
- * Support only 64MB NOR Flash parts
- */
-
-#if defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_BOTH_BANKS
-#elif defined(CONFIG_MTD_DB1550_BOOT) && !defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_BOOT_ONLY
-#elif !defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_USER_ONLY
-#endif
-
-#ifdef DB1550_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition db1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
- * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
- */
- {
- .name = "User FS",
- .size = (0x1FC00000 - 0x18000000),
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(DB1550_BOOT_ONLY)
-static struct mtd_partition db1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
- */
- {
- .name = "User FS",
- .size = 0x03c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000-0x40000), /* last 256KB is yamon env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(DB1550_USER_ONLY)
-static struct mtd_partition db1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
- */
- {
- .name = "User FS",
- .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
- .offset = 0x0000000
- },{
- .name = "raw kernel",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#else
-#error MTD_DB1550 define combo error /* should never happen */
-#endif
-
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-static struct mtd_info *mymtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
-#if defined(DB1550_BOTH_BANKS)
- window_addr = 0x18000000;
- window_size = 0x8000000;
-#elif defined(DB1550_BOOT_ONLY)
- window_addr = 0x1C000000;
- window_size = 0x4000000;
-#else /* USER ONLY */
- window_addr = 0x18000000;
- window_size = 0x4000000;
-#endif
- return 0;
-}
-
-int __init db1550_mtd_init(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
-
- /* Default flash bankwidth */
- db1550_map.bankwidth = flash_bankwidth;
-
- if (setup_flash_params())
- return -ENXIO;
-
- /*
- * Static partition definition selection
- */
- parts = db1550_partitions;
- nb_parts = NB_OF(db1550_partitions);
- db1550_map.size = window_size;
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Db1550 flash: probing %d-bit flash bus\n",
- db1550_map.bankwidth*8);
- db1550_map.virt = ioremap(window_addr, window_size);
- mymtd = do_map_probe("cfi_probe", &db1550_map);
- if (!mymtd) return -ENXIO;
- mymtd->owner = THIS_MODULE;
-
- add_mtd_partitions(mymtd, parts, nb_parts);
- return 0;
-}
-
-static void __exit db1550_mtd_cleanup(void)
-{
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- iounmap((void *) db1550_map.virt);
- }
-}
-
-module_init(db1550_mtd_init);
-module_exit(db1550_mtd_cleanup);
-
-MODULE_AUTHOR("Embedded Edge, LLC");
-MODULE_DESCRIPTION("Db1550 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/db1x00-flash.c b/drivers/mtd/maps/db1x00-flash.c
deleted file mode 100644
index faa68ec5690..00000000000
--- a/drivers/mtd/maps/db1x00-flash.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Flash memory access on Alchemy Db1xxx boards
- *
- * $Id: db1x00-flash.c,v 1.6 2004/11/04 13:24:14 gleixner Exp $
- *
- * (C) 2003 Pete Popov <ppopov@embeddedalley.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef DEBUG_RW
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* MTD CONFIG OPTIONS */
-#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_BOTH_BANKS
-#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_BOOT_ONLY
-#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_USER_ONLY
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-static unsigned long flash_size;
-
-static unsigned short *bcsr = (unsigned short *)0xAE000000;
-static unsigned char flash_bankwidth = 4;
-
-/*
- * The Db1x boards support different flash densities. We setup
- * the mtd_partition structures below for default of 64Mbit
- * flash densities, and override the partitions sizes, if
- * necessary, after we check the board status register.
- */
-
-#ifdef DB1X00_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition db1x00_partitions[] = {
- {
- .name = "User FS",
- .size = 0x1c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000-0x40000), /* last 256KB is env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(DB1X00_BOOT_ONLY)
-static struct mtd_partition db1x00_partitions[] = {
- {
- .name = "User FS",
- .size = 0x00c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000-0x40000), /* last 256KB is env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(DB1X00_USER_ONLY)
-static struct mtd_partition db1x00_partitions[] = {
- {
- .name = "User FS",
- .size = 0x0e00000,
- .offset = 0x0000000
- },{
- .name = "raw kernel",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#else
-#error MTD_DB1X00 define combo error /* should never happen */
-#endif
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-#define NAME "Db1x00 Linux Flash"
-
-static struct map_info db1xxx_mtd_map = {
- .name = NAME,
-};
-
-static struct mtd_partition *parsed_parts;
-static struct mtd_info *db1xxx_mtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
- switch ((bcsr[2] >> 14) & 0x3) {
- case 0: /* 64Mbit devices */
- flash_size = 0x800000; /* 8MB per part */
-#if defined(DB1X00_BOTH_BANKS)
- window_addr = 0x1E000000;
- window_size = 0x2000000;
-#elif defined(DB1X00_BOOT_ONLY)
- window_addr = 0x1F000000;
- window_size = 0x1000000;
-#else /* USER ONLY */
- window_addr = 0x1E000000;
- window_size = 0x1000000;
-#endif
- break;
- case 1:
- /* 128 Mbit devices */
- flash_size = 0x1000000; /* 16MB per part */
-#if defined(DB1X00_BOTH_BANKS)
- window_addr = 0x1C000000;
- window_size = 0x4000000;
- /* USERFS from 0x1C00 0000 to 0x1FC0 0000 */
- db1x00_partitions[0].size = 0x3C00000;
-#elif defined(DB1X00_BOOT_ONLY)
- window_addr = 0x1E000000;
- window_size = 0x2000000;
- /* USERFS from 0x1E00 0000 to 0x1FC0 0000 */
- db1x00_partitions[0].size = 0x1C00000;
-#else /* USER ONLY */
- window_addr = 0x1C000000;
- window_size = 0x2000000;
- /* USERFS from 0x1C00 0000 to 0x1DE00000 */
- db1x00_partitions[0].size = 0x1DE0000;
-#endif
- break;
- case 2:
- /* 256 Mbit devices */
- flash_size = 0x4000000; /* 64MB per part */
-#if defined(DB1X00_BOTH_BANKS)
- return 1;
-#elif defined(DB1X00_BOOT_ONLY)
- /* Boot ROM flash bank only; no user bank */
- window_addr = 0x1C000000;
- window_size = 0x4000000;
- /* USERFS from 0x1C00 0000 to 0x1FC00000 */
- db1x00_partitions[0].size = 0x3C00000;
-#else /* USER ONLY */
- return 1;
-#endif
- break;
- default:
- return 1;
- }
- db1xxx_mtd_map.size = window_size;
- db1xxx_mtd_map.bankwidth = flash_bankwidth;
- db1xxx_mtd_map.phys = window_addr;
- db1xxx_mtd_map.bankwidth = flash_bankwidth;
- return 0;
-}
-
-int __init db1x00_mtd_init(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
-
- if (setup_flash_params())
- return -ENXIO;
-
- /*
- * Static partition definition selection
- */
- parts = db1x00_partitions;
- nb_parts = NB_OF(db1x00_partitions);
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n",
- db1xxx_mtd_map.bankwidth*8);
- db1xxx_mtd_map.virt = ioremap(window_addr, window_size);
- db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
- if (!db1xxx_mtd) return -ENXIO;
- db1xxx_mtd->owner = THIS_MODULE;
-
- add_mtd_partitions(db1xxx_mtd, parts, nb_parts);
- return 0;
-}
-
-static void __exit db1x00_mtd_cleanup(void)
-{
- if (db1xxx_mtd) {
- del_mtd_partitions(db1xxx_mtd);
- map_destroy(db1xxx_mtd);
- if (parsed_parts)
- kfree(parsed_parts);
- }
-}
-
-module_init(db1x00_mtd_init);
-module_exit(db1x00_mtd_cleanup);
-
-MODULE_AUTHOR("Pete Popov");
-MODULE_DESCRIPTION("Db1x00 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
deleted file mode 100644
index e9465f5c069..00000000000
--- a/drivers/mtd/maps/elan-104nc.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* elan-104nc.c -- MTD map driver for Arcom Control Systems ELAN-104NC
-
- Copyright (C) 2000 Arcom Control System Ltd
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
- $Id: elan-104nc.c,v 1.25 2004/11/28 09:40:39 dwmw2 Exp $
-
-The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
-mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
-
-The flash is accessed as follows:
-
- 32 kbyte memory window at 0xb0000-0xb7fff
-
- 16 bit I/O port (0x22) for some sort of paging.
-
-The single flash device is divided into 3 partition which appear as separate
-MTD devices.
-
-Linux thinks that the I/O port is used by the PIC and hence check_region() will
-always fail. So we don't do it. I just hope it doesn't break anything.
-*/
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-#include <linux/mtd/map.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define WINDOW_START 0xb0000
-/* Number of bits in offset. */
-#define WINDOW_SHIFT 15
-#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
-/* The bits for the offset into the window. */
-#define WINDOW_MASK (WINDOW_LENGTH-1)
-#define PAGE_IO 0x22
-#define PAGE_IO_SIZE 2
-
-static volatile int page_in_window = -1; // Current page in window.
-static void __iomem *iomapadr;
-static DEFINE_SPINLOCK(elan_104nc_spin);
-
-/* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
-static struct mtd_partition partition_info[]={
- { .name = "ELAN-104NC flash boot partition",
- .offset = 0,
- .size = 640*1024 },
- { .name = "ELAN-104NC flash partition 1",
- .offset = 640*1024,
- .size = 896*1024 },
- { .name = "ELAN-104NC flash partition 2",
- .offset = (640+896)*1024 }
-};
-#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
-/*
- * If no idea what is going on here. This is taken from the FlashFX stuff.
- */
-#define ROMCS 1
-
-static inline void elan_104nc_setup(void)
-{
- u16 t;
-
- outw( 0x0023 + ROMCS*2, PAGE_IO );
- t=inb( PAGE_IO+1 );
-
- t=(t & 0xf9) | 0x04;
-
- outw( ((0x0023 + ROMCS*2) | (t << 8)), PAGE_IO );
-}
-
-static inline void elan_104nc_page(struct map_info *map, unsigned long ofs)
-{
- unsigned long page = ofs >> WINDOW_SHIFT;
-
- if( page!=page_in_window ) {
- int cmd1;
- int cmd2;
-
- cmd1=(page & 0x700) + 0x0833 + ROMCS*0x4000;
- cmd2=((page & 0xff) << 8) + 0x0032;
-
- outw( cmd1, PAGE_IO );
- outw( cmd2, PAGE_IO );
-
- page_in_window = page;
- }
-}
-
-
-static map_word elan_104nc_read16(struct map_info *map, unsigned long ofs)
-{
- map_word ret;
- spin_lock(&elan_104nc_spin);
- elan_104nc_page(map, ofs);
- ret.x[0] = readw(iomapadr + (ofs & WINDOW_MASK));
- spin_unlock(&elan_104nc_spin);
- return ret;
-}
-
-static void elan_104nc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
- while (len) {
- unsigned long thislen = len;
- if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
- thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-
- spin_lock(&elan_104nc_spin);
- elan_104nc_page(map, from);
- memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
- spin_unlock(&elan_104nc_spin);
- to += thislen;
- from += thislen;
- len -= thislen;
- }
-}
-
-static void elan_104nc_write16(struct map_info *map, map_word d, unsigned long adr)
-{
- spin_lock(&elan_104nc_spin);
- elan_104nc_page(map, adr);
- writew(d.x[0], iomapadr + (adr & WINDOW_MASK));
- spin_unlock(&elan_104nc_spin);
-}
-
-static void elan_104nc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
- while(len) {
- unsigned long thislen = len;
- if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
- thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-
- spin_lock(&elan_104nc_spin);
- elan_104nc_page(map, to);
- memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
- spin_unlock(&elan_104nc_spin);
- to += thislen;
- from += thislen;
- len -= thislen;
- }
-}
-
-static struct map_info elan_104nc_map = {
- .name = "ELAN-104NC flash",
- .phys = NO_XIP,
- .size = 8*1024*1024, /* this must be set to a maximum possible amount
- of flash so the cfi probe routines find all
- the chips */
- .bankwidth = 2,
- .read = elan_104nc_read16,
- .copy_from = elan_104nc_copy_from,
- .write = elan_104nc_write16,
- .copy_to = elan_104nc_copy_to
-};
-
-/* MTD device for all of the flash. */
-static struct mtd_info *all_mtd;
-
-static void cleanup_elan_104nc(void)
-{
- if( all_mtd ) {
- del_mtd_partitions( all_mtd );
- map_destroy( all_mtd );
- }
-
- iounmap(iomapadr);
-}
-
-static int __init init_elan_104nc(void)
-{
- /* Urg! We use I/O port 0x22 without request_region()ing it,
- because it's already allocated to the PIC. */
-
- iomapadr = ioremap(WINDOW_START, WINDOW_LENGTH);
- if (!iomapadr) {
- printk( KERN_ERR"%s: failed to ioremap memory region\n",
- elan_104nc_map.name );
- return -EIO;
- }
-
- printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
- elan_104nc_map.name,
- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
- WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
-
- elan_104nc_setup();
-
- /* Probe for chip. */
- all_mtd = do_map_probe("cfi_probe", &elan_104nc_map );
- if( !all_mtd ) {
- cleanup_elan_104nc();
- return -ENXIO;
- }
-
- all_mtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
-
- return 0;
-}
-
-module_init(init_elan_104nc);
-module_exit(cleanup_elan_104nc);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arcom Control Systems Ltd.");
-MODULE_DESCRIPTION("MTD map driver for Arcom Control Systems ELAN-104NC");
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index 29d1cc1bb42..e505207cd48 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
* ichxrom.c
*
* Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.16 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $
*/
#include <linux/module.h>
@@ -338,9 +338,9 @@ static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
{ 0, },
};
+#if 0
MODULE_DEVICE_TABLE(pci, ichxrom_pci_tbl);
-#if 0
static struct pci_driver ichxrom_driver = {
.name = MOD_NAME,
.id_table = ichxrom_pci_tbl,
@@ -366,7 +366,7 @@ static int __init init_ichxrom(void)
}
return -ENXIO;
#if 0
- return pci_module_init(&ichxrom_driver);
+ return pci_register_driver(&ichxrom_driver);
#endif
}
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index c5b5f447e34..3e94b616743 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
/*
- * $Id: ixp2000.c,v 1.5 2004/11/16 17:15:48 dsaxena Exp $
+ * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $
*
* drivers/mtd/maps/ixp2000.c
*
@@ -216,11 +216,6 @@ static int ixp2000_flash_probe(struct device *_dev)
goto Error;
}
- /*
- * Setup read mode for FLASH
- */
- *IXP2000_SLOWPORT_FRM = 1;
-
#if defined(__ARMEB__)
/*
* Enable erratum 44 workaround for NPUs with broken slowport
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
new file mode 100644
index 00000000000..87e93fa6058
--- /dev/null
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -0,0 +1,178 @@
+/*
+ * $Id: $
+ *
+ * Map driver for the Mainstone developer platform.
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mainstone.h>
+
+
+#define ROM_ADDR 0x00000000
+#define FLASH_ADDR 0x04000000
+
+#define WINDOW_SIZE 0x04000000
+
+static void mainstone_map_inval_cache(struct map_info *map, unsigned long from,
+ ssize_t len)
+{
+ consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
+}
+
+static struct map_info mainstone_maps[2] = { {
+ .size = WINDOW_SIZE,
+ .phys = PXA_CS0_PHYS,
+ .inval_cache = mainstone_map_inval_cache,
+}, {
+ .size = WINDOW_SIZE,
+ .phys = PXA_CS1_PHYS,
+ .inval_cache = mainstone_map_inval_cache,
+} };
+
+static struct mtd_partition mainstone_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x00400000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00440000
+ }
+};
+
+static struct mtd_info *mymtds[2];
+static struct mtd_partition *parsed_parts[2];
+static int nr_parsed_parts[2];
+
+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+
+static int __init init_mainstone(void)
+{
+ int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
+ int ret = 0, i;
+
+ mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4;
+ mainstone_maps[1].bankwidth = 4;
+
+ /* Compensate for SW7 which swaps the flash banks */
+ mainstone_maps[SW7].name = "processor flash";
+ mainstone_maps[SW7 ^ 1].name = "main board flash";
+
+ printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
+ mainstone_maps[0].name);
+
+ for (i = 0; i < 2; i++) {
+ mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
+ WINDOW_SIZE);
+ if (!mainstone_maps[i].virt) {
+ printk(KERN_WARNING "Failed to ioremap %s\n",
+ mainstone_maps[i].name);
+ if (!ret)
+ ret = -ENOMEM;
+ continue;
+ }
+ mainstone_maps[i].cached =
+ ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
+ if (!mainstone_maps[i].cached)
+ printk(KERN_WARNING "Failed to ioremap cached %s\n",
+ mainstone_maps[i].name);
+ simple_map_init(&mainstone_maps[i]);
+
+ printk(KERN_NOTICE
+ "Probing %s at physical address 0x%08lx"
+ " (%d-bit bankwidth)\n",
+ mainstone_maps[i].name, mainstone_maps[i].phys,
+ mainstone_maps[i].bankwidth * 8);
+
+ mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
+
+ if (!mymtds[i]) {
+ iounmap((void *)mainstone_maps[i].virt);
+ if (mainstone_maps[i].cached)
+ iounmap(mainstone_maps[i].cached);
+ if (!ret)
+ ret = -EIO;
+ continue;
+ }
+ mymtds[i]->owner = THIS_MODULE;
+
+ ret = parse_mtd_partitions(mymtds[i], probes,
+ &parsed_parts[i], 0);
+
+ if (ret > 0)
+ nr_parsed_parts[i] = ret;
+ }
+
+ if (!mymtds[0] && !mymtds[1])
+ return ret;
+
+ for (i = 0; i < 2; i++) {
+ if (!mymtds[i]) {
+ printk(KERN_WARNING "%s is absent. Skipping\n",
+ mainstone_maps[i].name);
+ } else if (nr_parsed_parts[i]) {
+ add_mtd_partitions(mymtds[i], parsed_parts[i],
+ nr_parsed_parts[i]);
+ } else if (!i) {
+ printk("Using static partitions on %s\n",
+ mainstone_maps[i].name);
+ add_mtd_partitions(mymtds[i], mainstone_partitions,
+ ARRAY_SIZE(mainstone_partitions));
+ } else {
+ printk("Registering %s as whole device\n",
+ mainstone_maps[i].name);
+ add_mtd_device(mymtds[i]);
+ }
+ }
+ return 0;
+}
+
+static void __exit cleanup_mainstone(void)
+{
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (!mymtds[i])
+ continue;
+
+ if (nr_parsed_parts[i] || !i)
+ del_mtd_partitions(mymtds[i]);
+ else
+ del_mtd_device(mymtds[i]);
+
+ map_destroy(mymtds[i]);
+ iounmap((void *)mainstone_maps[i].virt);
+ if (mainstone_maps[i].cached)
+ iounmap(mainstone_maps[i].cached);
+ kfree(parsed_parts[i]);
+ }
+}
+
+module_init(init_mainstone);
+module_exit(cleanup_mainstone);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("MTD map driver for Intel Mainstone");
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c
index 38f6a7af53f..9105e6ca0aa 100644
--- a/drivers/mtd/maps/map_funcs.c
+++ b/drivers/mtd/maps/map_funcs.c
@@ -1,5 +1,5 @@
/*
- * $Id: map_funcs.c,v 1.9 2004/07/13 22:33:15 dwmw2 Exp $
+ * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $
*
* Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS
* is enabled.
@@ -9,23 +9,24 @@
#include <linux/module.h>
#include <linux/mtd/map.h>
+#include <linux/mtd/xip.h>
-static map_word simple_map_read(struct map_info *map, unsigned long ofs)
+static map_word __xipram simple_map_read(struct map_info *map, unsigned long ofs)
{
return inline_map_read(map, ofs);
}
-static void simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
+static void __xipram simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
{
inline_map_write(map, datum, ofs);
}
-static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+static void __xipram simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
inline_map_copy_from(map, to, from, len);
}
-static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+static void __xipram simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
inline_map_copy_to(map, to, from, len);
}
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
new file mode 100644
index 00000000000..8cc71409a32
--- /dev/null
+++ b/drivers/mtd/maps/omap_nor.c
@@ -0,0 +1,179 @@
+/*
+ * Flash memory support for various TI OMAP boards
+ *
+ * Copyright (C) 2001-2002 MontaVista Software Inc.
+ * Copyright (C) 2003-2004 Texas Instruments
+ * Copyright (C) 2004 Nokia Corporation
+ *
+ * Assembled using driver code copyright the companies above
+ * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
+ * Tony Lindgren <tony@atomide.com> and others.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/flash.h>
+#include <asm/arch/tc.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
+#endif
+
+struct omapflash_info {
+ struct mtd_partition *parts;
+ struct mtd_info *mtd;
+ struct map_info map;
+};
+
+static void omap_set_vpp(struct map_info *map, int enable)
+{
+ static int count;
+
+ if (enable) {
+ if (count++ == 0)
+ OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP;
+ } else {
+ if (count && (--count == 0))
+ OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP;
+ }
+}
+
+static int __devinit omapflash_probe(struct device *dev)
+{
+ int err;
+ struct omapflash_info *info;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct flash_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *res = pdev->resource;
+ unsigned long size = res->end - res->start + 1;
+
+ info = kmalloc(sizeof(struct omapflash_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ memset(info, 0, sizeof(struct omapflash_info));
+
+ if (!request_mem_region(res->start, size, "flash")) {
+ err = -EBUSY;
+ goto out_free_info;
+ }
+
+ info->map.virt = ioremap(res->start, size);
+ if (!info->map.virt) {
+ err = -ENOMEM;
+ goto out_release_mem_region;
+ }
+ info->map.name = pdev->dev.bus_id;
+ info->map.phys = res->start;
+ info->map.size = size;
+ info->map.bankwidth = pdata->width;
+ info->map.set_vpp = omap_set_vpp;
+
+ simple_map_init(&info->map);
+ info->mtd = do_map_probe(pdata->map_name, &info->map);
+ if (!info->mtd) {
+ err = -EIO;
+ goto out_iounmap;
+ }
+ info->mtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
+ if (err > 0)
+ add_mtd_partitions(info->mtd, info->parts, err);
+ else if (err < 0 && pdata->parts)
+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+ else
+#endif
+ add_mtd_device(info->mtd);
+
+ dev_set_drvdata(&pdev->dev, info);
+
+ return 0;
+
+out_iounmap:
+ iounmap(info->map.virt);
+out_release_mem_region:
+ release_mem_region(res->start, size);
+out_free_info:
+ kfree(info);
+
+ return err;
+}
+
+static int __devexit omapflash_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omapflash_info *info = dev_get_drvdata(&pdev->dev);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ if (info) {
+ if (info->parts) {
+ del_mtd_partitions(info->mtd);
+ kfree(info->parts);
+ } else
+ del_mtd_device(info->mtd);
+ map_destroy(info->mtd);
+ release_mem_region(info->map.phys, info->map.size);
+ iounmap((void __iomem *) info->map.virt);
+ kfree(info);
+ }
+
+ return 0;
+}
+
+static struct device_driver omapflash_driver = {
+ .name = "omapflash",
+ .bus = &platform_bus_type,
+ .probe = omapflash_probe,
+ .remove = __devexit_p(omapflash_remove),
+};
+
+static int __init omapflash_init(void)
+{
+ return driver_register(&omapflash_driver);
+}
+
+static void __exit omapflash_exit(void)
+{
+ driver_unregister(&omapflash_driver);
+}
+
+module_init(omapflash_init);
+module_exit(omapflash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards");
+
diff --git a/drivers/mtd/maps/pb1550-flash.c b/drivers/mtd/maps/pb1550-flash.c
deleted file mode 100644
index 1424726a219..00000000000
--- a/drivers/mtd/maps/pb1550-flash.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Flash memory access on Alchemy Pb1550 board
- *
- * $Id: pb1550-flash.c,v 1.6 2004/11/04 13:24:15 gleixner Exp $
- *
- * (C) 2004 Embedded Edge, LLC, based on pb1550-flash.c:
- * (C) 2003 Pete Popov <ppopov@pacbell.net>
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/au1000.h>
-#include <asm/pb1550.h>
-
-#ifdef DEBUG_RW
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-
-
-static struct map_info pb1550_map = {
- .name = "Pb1550 flash",
-};
-
-static unsigned char flash_bankwidth = 4;
-
-/*
- * Support only 64MB NOR Flash parts
- */
-
-#ifdef PB1550_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition pb1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
- * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
- */
- {
- .name = "User FS",
- .size = (0x1FC00000 - 0x18000000),
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(PB1550_BOOT_ONLY)
-static struct mtd_partition pb1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
- */
- {
- .name = "User FS",
- .size = 0x03c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = MTDPART_OFS_APPEND,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = (0x300000-0x40000), /* last 256KB is yamon env */
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#elif defined(PB1550_USER_ONLY)
-static struct mtd_partition pb1550_partitions[] = {
- /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
- * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
- */
- {
- .name = "User FS",
- .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
- .offset = 0x0000000
- },{
- .name = "raw kernel",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-#else
-#error MTD_PB1550 define combo error /* should never happen */
-#endif
-
-#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-static struct mtd_info *mymtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
- u16 boot_swapboot;
- boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
- ((bcsr->status >> 6) & 0x1);
- printk("Pb1550 MTD: boot:swap %d\n", boot_swapboot);
-
- switch (boot_swapboot) {
- case 0: /* 512Mbit devices, both enabled */
- case 1:
- case 8:
- case 9:
-#if defined(PB1550_BOTH_BANKS)
- window_addr = 0x18000000;
- window_size = 0x8000000;
-#elif defined(PB1550_BOOT_ONLY)
- window_addr = 0x1C000000;
- window_size = 0x4000000;
-#else /* USER ONLY */
- window_addr = 0x1E000000;
- window_size = 0x4000000;
-#endif
- break;
- case 0xC:
- case 0xD:
- case 0xE:
- case 0xF:
- /* 64 MB Boot NOR Flash is disabled */
- /* and the start address is moved to 0x0C00000 */
- window_addr = 0x0C000000;
- window_size = 0x4000000;
- default:
- printk("Pb1550 MTD: unsupported boot:swap setting\n");
- return 1;
- }
- return 0;
-}
-
-int __init pb1550_mtd_init(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
-
- /* Default flash bankwidth */
- pb1550_map.bankwidth = flash_bankwidth;
-
- if (setup_flash_params())
- return -ENXIO;
-
- /*
- * Static partition definition selection
- */
- parts = pb1550_partitions;
- nb_parts = NB_OF(pb1550_partitions);
- pb1550_map.size = window_size;
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Pb1550 flash: probing %d-bit flash bus\n",
- pb1550_map.bankwidth*8);
- pb1550_map.virt = ioremap(window_addr, window_size);
- mymtd = do_map_probe("cfi_probe", &pb1550_map);
- if (!mymtd) return -ENXIO;
- mymtd->owner = THIS_MODULE;
-
- add_mtd_partitions(mymtd, parts, nb_parts);
- return 0;
-}
-
-static void __exit pb1550_mtd_cleanup(void)
-{
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-}
-
-module_init(pb1550_mtd_init);
-module_exit(pb1550_mtd_cleanup);
-
-MODULE_AUTHOR("Embedded Edge, LLC");
-MODULE_DESCRIPTION("Pb1550 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pb1xxx-flash.c b/drivers/mtd/maps/pb1xxx-flash.c
deleted file mode 100644
index 06e73154055..00000000000
--- a/drivers/mtd/maps/pb1xxx-flash.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Flash memory access on Alchemy Pb1xxx boards
- *
- * (C) 2001 Pete Popov <ppopov@mvista.com>
- *
- * $Id: pb1xxx-flash.c,v 1.14 2004/11/04 13:24:15 gleixner Exp $
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef DEBUG_RW
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#ifdef CONFIG_MIPS_PB1000
-
-#define WINDOW_ADDR 0x1F800000
-#define WINDOW_SIZE 0x800000
-
-static struct mtd_partition pb1xxx_partitions[] = {
- {
- .name = "yamon env",
- .size = 0x00020000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE},
- {
- .name = "User FS",
- .size = 0x003e0000,
- .offset = 0x20000,},
- {
- .name = "boot code",
- .size = 0x100000,
- .offset = 0x400000,
- .mask_flags = MTD_WRITEABLE},
- {
- .name = "raw/kernel",
- .size = 0x300000,
- .offset = 0x500000}
-};
-
-#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
-
-#if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
-/* both 32MB banks will be used. Combine the first 32MB bank and the
- * first 28MB of the second bank together into a single jffs/jffs2
- * partition.
- */
-#define WINDOW_ADDR 0x1C000000
-#define WINDOW_SIZE 0x4000000
-static struct mtd_partition pb1xxx_partitions[] = {
- {
- .name = "User FS",
- .size = 0x3c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = 0x3c00000,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = 0x02c0000,
- .offset = 0x3d00000
- }
-};
-#elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
-#define WINDOW_ADDR 0x1E000000
-#define WINDOW_SIZE 0x2000000
-static struct mtd_partition pb1xxx_partitions[] = {
- {
- .name = "User FS",
- .size = 0x1c00000,
- .offset = 0x0000000
- },{
- .name = "yamon",
- .size = 0x0100000,
- .offset = 0x1c00000,
- .mask_flags = MTD_WRITEABLE
- },{
- .name = "raw kernel",
- .size = 0x02c0000,
- .offset = 0x1d00000
- }
-};
-#elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
-#define WINDOW_ADDR 0x1C000000
-#define WINDOW_SIZE 0x2000000
-static struct mtd_partition pb1xxx_partitions[] = {
- {
- .name = "User FS",
- .size = 0x1e00000,
- .offset = 0x0000000
- },{
- .name = "raw kernel",
- .size = 0x0200000,
- .offset = 0x1e00000,
- }
-};
-#else
-#error MTD_PB1500 define combo error /* should never happen */
-#endif
-#else
-#error Unsupported board
-#endif
-
-#define NAME "Pb1x00 Linux Flash"
-#define PADDR WINDOW_ADDR
-#define BUSWIDTH 4
-#define SIZE WINDOW_SIZE
-#define PARTITIONS 4
-
-static struct map_info pb1xxx_mtd_map = {
- .name = NAME,
- .size = SIZE,
- .bankwidth = BUSWIDTH,
- .phys = PADDR,
-};
-
-static struct mtd_info *pb1xxx_mtd;
-
-int __init pb1xxx_mtd_init(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
- char *part_type;
-
- /*
- * Static partition definition selection
- */
- part_type = "static";
- parts = pb1xxx_partitions;
- nb_parts = ARRAY_SIZE(pb1xxx_partitions);
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n",
- BUSWIDTH*8);
- pb1xxx_mtd_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
- simple_map_init(&pb1xxx_mtd_map);
-
- pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map);
- if (!pb1xxx_mtd) return -ENXIO;
- pb1xxx_mtd->owner = THIS_MODULE;
-
- add_mtd_partitions(pb1xxx_mtd, parts, nb_parts);
- return 0;
-}
-
-static void __exit pb1xxx_mtd_cleanup(void)
-{
- if (pb1xxx_mtd) {
- del_mtd_partitions(pb1xxx_mtd);
- map_destroy(pb1xxx_mtd);
- iounmap((void *) pb1xxx_mtd_map.virt);
- }
-}
-
-module_init(pb1xxx_mtd_init);
-module_exit(pb1xxx_mtd_cleanup);
-
-MODULE_AUTHOR("Pete Popov");
-MODULE_DESCRIPTION("Pb1xxx CFI map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 08b60bdc538..18dbd3af1ea 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,7 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * $Id: pci.c,v 1.9 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $
*
* Generic PCI memory map driver. We support the following boards:
* - Intel IQ80310 ATU.
@@ -370,7 +370,7 @@ static struct pci_driver mtd_pci_driver = {
static int __init mtd_pci_maps_init(void)
{
- return pci_module_init(&mtd_pci_driver);
+ return pci_register_driver(&mtd_pci_driver);
}
static void __exit mtd_pci_maps_exit(void)
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index c2655a817e3..ff7c50d1018 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -18,7 +18,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -800,11 +799,6 @@ static dev_link_t *pcmciamtd_attach(void)
/* Register with Card Services */
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &pcmciamtd_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
DEBUG(2, "Calling RegisterClient");
@@ -850,6 +844,7 @@ static struct pcmcia_driver pcmciamtd_driver = {
.name = "pcmciamtd"
},
.attach = pcmciamtd_attach,
+ .event = pcmciamtd_event,
.detach = pcmciamtd_detach,
.owner = THIS_MODULE,
.id_table = pcmciamtd_ids,
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
new file mode 100644
index 00000000000..118b04544ca
--- /dev/null
+++ b/drivers/mtd/maps/plat-ram.c
@@ -0,0 +1,278 @@
+/* drivers/mtd/maps/plat-ram.c
+ *
+ * (c) 2004-2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Generic platfrom device based RAM map
+ *
+ * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/plat-ram.h>
+
+#include <asm/io.h>
+
+/* private structure for each mtd platform ram device created */
+
+struct platram_info {
+ struct device *dev;
+ struct mtd_info *mtd;
+ struct map_info map;
+ struct mtd_partition *partitions;
+ struct resource *area;
+ struct platdata_mtd_ram *pdata;
+};
+
+/* to_platram_info()
+ *
+ * device private data to struct platram_info conversion
+*/
+
+static inline struct platram_info *to_platram_info(struct device *dev)
+{
+ return (struct platram_info *)dev_get_drvdata(dev);
+}
+
+/* platram_setrw
+ *
+ * call the platform device's set rw/ro control
+ *
+ * to = 0 => read-only
+ * = 1 => read-write
+*/
+
+static inline void platram_setrw(struct platram_info *info, int to)
+{
+ if (info->pdata == NULL)
+ return;
+
+ if (info->pdata->set_rw != NULL)
+ (info->pdata->set_rw)(info->dev, to);
+}
+
+/* platram_remove
+ *
+ * called to remove the device from the driver's control
+*/
+
+static int platram_remove(struct device *dev)
+{
+ struct platram_info *info = to_platram_info(dev);
+
+ dev_set_drvdata(dev, NULL);
+
+ dev_dbg(dev, "removing device\n");
+
+ if (info == NULL)
+ return 0;
+
+ if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+ if (info->partitions) {
+ del_mtd_partitions(info->mtd);
+ kfree(info->partitions);
+ }
+#endif
+ del_mtd_device(info->mtd);
+ map_destroy(info->mtd);
+ }
+
+ /* ensure ram is left read-only */
+
+ platram_setrw(info, PLATRAM_RO);
+
+ /* release resources */
+
+ if (info->area) {
+ release_resource(info->area);
+ kfree(info->area);
+ }
+
+ if (info->map.virt != NULL)
+ iounmap(info->map.virt);
+
+ kfree(info);
+
+ return 0;
+}
+
+/* platram_probe
+ *
+ * called from device drive system when a device matching our
+ * driver is found.
+*/
+
+static int platram_probe(struct device *dev)
+{
+ struct platform_device *pd = to_platform_device(dev);
+ struct platdata_mtd_ram *pdata;
+ struct platram_info *info;
+ struct resource *res;
+ int err = 0;
+
+ dev_dbg(dev, "probe entered\n");
+
+ if (dev->platform_data == NULL) {
+ dev_err(dev, "no platform data supplied\n");
+ err = -ENOENT;
+ goto exit_error;
+ }
+
+ pdata = dev->platform_data;
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info == NULL) {
+ dev_err(dev, "no memory for flash info\n");
+ err = -ENOMEM;
+ goto exit_error;
+ }
+
+ memset(info, 0, sizeof(*info));
+ dev_set_drvdata(dev, info);
+
+ info->dev = dev;
+ info->pdata = pdata;
+
+ /* get the resource for the memory mapping */
+
+ res = platform_get_resource(pd, IORESOURCE_MEM, 0);
+
+ if (res == NULL) {
+ dev_err(dev, "no memory resource specified\n");
+ err = -ENOENT;
+ goto exit_free;
+ }
+
+ dev_dbg(dev, "got platform resource %p (0x%lx)\n", res, res->start);
+
+ /* setup map parameters */
+
+ info->map.phys = res->start;
+ info->map.size = (res->end - res->start) + 1;
+ info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
+ info->map.bankwidth = pdata->bankwidth;
+
+ /* register our usage of the memory area */
+
+ info->area = request_mem_region(res->start, info->map.size, pd->name);
+ if (info->area == NULL) {
+ dev_err(dev, "failed to request memory region\n");
+ err = -EIO;
+ goto exit_free;
+ }
+
+ /* remap the memory area */
+
+ info->map.virt = ioremap(res->start, info->map.size);
+ dev_dbg(dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
+
+ if (info->map.virt == NULL) {
+ dev_err(dev, "failed to ioremap() region\n");
+ err = -EIO;
+ goto exit_free;
+ }
+
+ simple_map_init(&info->map);
+
+ dev_dbg(dev, "initialised map, probing for mtd\n");
+
+ /* probe for the right mtd map driver */
+
+ info->mtd = do_map_probe("map_ram" , &info->map);
+ if (info->mtd == NULL) {
+ dev_err(dev, "failed to probe for map_ram\n");
+ err = -ENOMEM;
+ goto exit_free;
+ }
+
+ info->mtd->owner = THIS_MODULE;
+
+ platram_setrw(info, PLATRAM_RW);
+
+ /* check to see if there are any available partitions, or wether
+ * to add this device whole */
+
+#ifdef CONFIG_MTD_PARTITIONS
+ if (pdata->nr_partitions > 0) {
+ const char **probes = { NULL };
+
+ if (pdata->probes)
+ probes = (const char **)pdata->probes;
+
+ err = parse_mtd_partitions(info->mtd, probes,
+ &info->partitions, 0);
+ if (err > 0) {
+ err = add_mtd_partitions(info->mtd, info->partitions,
+ err);
+ }
+ }
+#endif /* CONFIG_MTD_PARTITIONS */
+
+ if (add_mtd_device(info->mtd)) {
+ dev_err(dev, "add_mtd_device() failed\n");
+ err = -ENOMEM;
+ }
+
+ dev_info(dev, "registered mtd device\n");
+ return err;
+
+ exit_free:
+ platram_remove(dev);
+ exit_error:
+ return err;
+}
+
+/* device driver info */
+
+static struct device_driver platram_driver = {
+ .name = "mtd-ram",
+ .bus = &platform_bus_type,
+ .probe = platram_probe,
+ .remove = platram_remove,
+};
+
+/* module init/exit */
+
+static int __init platram_init(void)
+{
+ printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
+ return driver_register(&platram_driver);
+}
+
+static void __exit platram_exit(void)
+{
+ driver_unregister(&platram_driver);
+}
+
+module_init(platram_init);
+module_exit(platram_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("MTD platform RAM map driver");
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c
index 5bb3b600e5d..97a8dfd6925 100644
--- a/drivers/mtd/maps/scb2_flash.c
+++ b/drivers/mtd/maps/scb2_flash.c
@@ -1,6 +1,6 @@
/*
* MTD map driver for BIOS Flash on Intel SCB2 boards
- * $Id: scb2_flash.c,v 1.11 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $
* Copyright (C) 2002 Sun Microsystems, Inc.
* Tim Hockin <thockin@sun.com>
*
@@ -238,7 +238,7 @@ static struct pci_driver scb2_flash_driver = {
static int __init
scb2_flash_init(void)
{
- return pci_module_init(&scb2_flash_driver);
+ return pci_register_driver(&scb2_flash_driver);
}
static void __exit
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b3b39cb7c60..d15da6fd84c 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001 Lineo Japan, Inc.
* Copyright (C) 2002 SHARP
*
- * $Id: sharpsl-flash.c,v 1.2 2004/11/24 20:38:06 rpurdie Exp $
+ * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $
*
* based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
* Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -24,13 +24,14 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
#define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x01000000
+#define WINDOW_SIZE 0x00800000
#define BANK_WIDTH 2
static struct mtd_info *mymtd;
@@ -44,9 +45,7 @@ struct map_info sharpsl_map = {
static struct mtd_partition sharpsl_partitions[1] = {
{
- name: "Filesystem",
- size: 0x006d0000,
- offset: 0x00120000
+ name: "Boot PROM Filesystem",
}
};
@@ -58,12 +57,16 @@ int __init init_sharpsl(void)
int nb_parts = 0;
char *part_type = "static";
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+ printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
+ WINDOW_SIZE, WINDOW_ADDR);
sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
if (!sharpsl_map.virt) {
printk("Failed to ioremap\n");
return -EIO;
}
+
+ simple_map_init(&sharpsl_map);
+
mymtd = do_map_probe("map_rom", &sharpsl_map);
if (!mymtd) {
iounmap(sharpsl_map.virt);
@@ -72,6 +75,22 @@ int __init init_sharpsl(void)
mymtd->owner = THIS_MODULE;
+ if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
+ || machine_is_poodle()) {
+ sharpsl_partitions[0].size=0x006d0000;
+ sharpsl_partitions[0].offset=0x00120000;
+ } else if (machine_is_tosa()) {
+ sharpsl_partitions[0].size=0x006a0000;
+ sharpsl_partitions[0].offset=0x00160000;
+ } else if (machine_is_spitz()) {
+ sharpsl_partitions[0].size=0x006b0000;
+ sharpsl_partitions[0].offset=0x00140000;
+ } else {
+ map_destroy(mymtd);
+ iounmap(sharpsl_map.virt);
+ return -ENODEV;
+ }
+
parts = sharpsl_partitions;
nb_parts = NB_OF(sharpsl_partitions);
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 510ad78312c..1ed602a0f24 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdchar.c,v 1.66 2005/01/05 18:05:11 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $
*
* Character-device access to raw MTD devices.
*
@@ -15,27 +15,30 @@
#include <linux/fs.h>
#include <asm/uaccess.h>
-#ifdef CONFIG_DEVFS_FS
-#include <linux/devfs_fs_kernel.h>
+#include <linux/device.h>
+
+static struct class *mtd_class;
static void mtd_notify_add(struct mtd_info* mtd)
{
if (!mtd)
return;
- devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
-
- devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index);
+ class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ NULL, "mtd%d", mtd->index);
+
+ class_device_create(mtd_class,
+ MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+ NULL, "mtd%dro", mtd->index);
}
static void mtd_notify_remove(struct mtd_info* mtd)
{
if (!mtd)
return;
- devfs_remove("mtd/%d", mtd->index);
- devfs_remove("mtd/%dro", mtd->index);
+
+ class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
+ class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
}
static struct mtd_notifier notifier = {
@@ -43,25 +46,25 @@ static struct mtd_notifier notifier = {
.remove = mtd_notify_remove,
};
-static inline void mtdchar_devfs_init(void)
-{
- devfs_mk_dir("mtd");
- register_mtd_user(&notifier);
-}
+/*
+ * We use file->private_data to store a pointer to the MTDdevice.
+ * Since alighment is at least 32 bits, we have 2 bits free for OTP
+ * modes as well.
+ */
-static inline void mtdchar_devfs_exit(void)
-{
- unregister_mtd_user(&notifier);
- devfs_remove("mtd");
-}
-#else /* !DEVFS */
-#define mtdchar_devfs_init() do { } while(0)
-#define mtdchar_devfs_exit() do { } while(0)
-#endif
+#define TO_MTD(file) (struct mtd_info *)((long)((file)->private_data) & ~3L)
+
+#define MTD_MODE_OTP_FACT 1
+#define MTD_MODE_OTP_USER 2
+#define MTD_MODE(file) ((long)((file)->private_data) & 3)
+
+#define SET_MTD_MODE(file, mode) \
+ do { long __p = (long)((file)->private_data); \
+ (file)->private_data = (void *)((__p & ~3L) | mode); } while (0)
static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
{
- struct mtd_info *mtd = file->private_data;
+ struct mtd_info *mtd = TO_MTD(file);
switch (orig) {
case 0:
@@ -134,7 +137,7 @@ static int mtd_close(struct inode *inode, struct file *file)
DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
- mtd = file->private_data;
+ mtd = TO_MTD(file);
if (mtd->sync)
mtd->sync(mtd);
@@ -151,7 +154,7 @@ static int mtd_close(struct inode *inode, struct file *file)
static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
{
- struct mtd_info *mtd = file->private_data;
+ struct mtd_info *mtd = TO_MTD(file);
size_t retlen=0;
size_t total_retlen=0;
int ret=0;
@@ -178,7 +181,16 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
if (!kbuf)
return -ENOMEM;
- ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
+ switch (MTD_MODE(file)) {
+ case MTD_MODE_OTP_FACT:
+ ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+ break;
+ case MTD_MODE_OTP_USER:
+ ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+ break;
+ default:
+ ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
+ }
/* Nand returns -EBADMSG on ecc errors, but it returns
* the data. For our userspace tools it is important
* to dump areas with ecc errors !
@@ -196,6 +208,8 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
count -= retlen;
buf += retlen;
+ if (retlen == 0)
+ count = 0;
}
else {
kfree(kbuf);
@@ -210,7 +224,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
{
- struct mtd_info *mtd = file->private_data;
+ struct mtd_info *mtd = TO_MTD(file);
char *kbuf;
size_t retlen;
size_t total_retlen=0;
@@ -245,7 +259,20 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
return -EFAULT;
}
- ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
+ switch (MTD_MODE(file)) {
+ case MTD_MODE_OTP_FACT:
+ ret = -EROFS;
+ break;
+ case MTD_MODE_OTP_USER:
+ if (!mtd->write_user_prot_reg) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+ break;
+ default:
+ ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
+ }
if (!ret) {
*ppos += retlen;
total_retlen += retlen;
@@ -276,7 +303,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
static int mtd_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg)
{
- struct mtd_info *mtd = file->private_data;
+ struct mtd_info *mtd = TO_MTD(file);
void __user *argp = (void __user *)arg;
int ret = 0;
u_long size;
@@ -518,6 +545,80 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
break;
}
+#ifdef CONFIG_MTD_OTP
+ case OTPSELECT:
+ {
+ int mode;
+ if (copy_from_user(&mode, argp, sizeof(int)))
+ return -EFAULT;
+ SET_MTD_MODE(file, 0);
+ switch (mode) {
+ case MTD_OTP_FACTORY:
+ if (!mtd->read_fact_prot_reg)
+ ret = -EOPNOTSUPP;
+ else
+ SET_MTD_MODE(file, MTD_MODE_OTP_FACT);
+ break;
+ case MTD_OTP_USER:
+ if (!mtd->read_fact_prot_reg)
+ ret = -EOPNOTSUPP;
+ else
+ SET_MTD_MODE(file, MTD_MODE_OTP_USER);
+ break;
+ default:
+ ret = -EINVAL;
+ case MTD_OTP_OFF:
+ break;
+ }
+ file->f_pos = 0;
+ break;
+ }
+
+ case OTPGETREGIONCOUNT:
+ case OTPGETREGIONINFO:
+ {
+ struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ ret = -EOPNOTSUPP;
+ switch (MTD_MODE(file)) {
+ case MTD_MODE_OTP_FACT:
+ if (mtd->get_fact_prot_info)
+ ret = mtd->get_fact_prot_info(mtd, buf, 4096);
+ break;
+ case MTD_MODE_OTP_USER:
+ if (mtd->get_user_prot_info)
+ ret = mtd->get_user_prot_info(mtd, buf, 4096);
+ break;
+ }
+ if (ret >= 0) {
+ if (cmd == OTPGETREGIONCOUNT) {
+ int nbr = ret / sizeof(struct otp_info);
+ ret = copy_to_user(argp, &nbr, sizeof(int));
+ } else
+ ret = copy_to_user(argp, buf, ret);
+ if (ret)
+ ret = -EFAULT;
+ }
+ kfree(buf);
+ break;
+ }
+
+ case OTPLOCK:
+ {
+ struct otp_info info;
+
+ if (MTD_MODE(file) != MTD_MODE_OTP_USER)
+ return -EINVAL;
+ if (copy_from_user(&info, argp, sizeof(info)))
+ return -EFAULT;
+ if (!mtd->lock_user_prot_reg)
+ return -EOPNOTSUPP;
+ ret = mtd->lock_user_prot_reg(mtd, info.start, info.length);
+ break;
+ }
+#endif
+
default:
ret = -ENOTTY;
}
@@ -543,13 +644,22 @@ static int __init init_mtdchar(void)
return -EAGAIN;
}
- mtdchar_devfs_init();
+ mtd_class = class_create(THIS_MODULE, "mtd");
+
+ if (IS_ERR(mtd_class)) {
+ printk(KERN_ERR "Error creating mtd class.\n");
+ unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
+ return PTR_ERR(mtd_class);
+ }
+
+ register_mtd_user(&notifier);
return 0;
}
static void __exit cleanup_mtdchar(void)
{
- mtdchar_devfs_exit();
+ unregister_mtd_user(&notifier);
+ class_destroy(mtd_class);
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
}
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9c0315d1b1c..dc86df18e94 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdcore.c,v 1.44 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $
*
* Core registration and callback routines for MTD
* drivers and users.
@@ -149,8 +149,8 @@ void register_mtd_user (struct mtd_notifier *new)
}
/**
- * register_mtd_user - unregister a 'user' of MTD devices.
- * @new: pointer to notifier info structure
+ * unregister_mtd_user - unregister a 'user' of MTD devices.
+ * @old: pointer to notifier info structure
*
* Removes a callback function pair from the list of 'users' to be
* notified upon addition or removal of MTD devices. Causes the
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 96ebb52f24b..b92e6bfffaf 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: mtdpart.c,v 1.51 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $
*
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
@@ -116,6 +116,13 @@ static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
len, retlen, buf);
}
+static int part_get_user_prot_info (struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->get_user_prot_info (part->master, buf, len);
+}
+
static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
@@ -124,6 +131,13 @@ static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
len, retlen, buf);
}
+static int part_get_fact_prot_info (struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->get_fact_prot_info (part->master, buf, len);
+}
+
static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
@@ -182,6 +196,12 @@ static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t l
len, retlen, buf);
}
+static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->lock_user_prot_reg (part->master, from, len);
+}
+
static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen)
{
@@ -409,6 +429,12 @@ int add_mtd_partitions(struct mtd_info *master,
slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
if(master->write_user_prot_reg)
slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
+ if(master->lock_user_prot_reg)
+ slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
+ if(master->get_user_prot_info)
+ slave->mtd.get_user_prot_info = part_get_user_prot_info;
+ if(master->get_fact_prot_info)
+ slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
if (master->sync)
slave->mtd.sync = part_sync;
if (!i && master->suspend && master->resume) {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index f7801eb730c..36d34e5e5a5 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.26 2005/01/05 12:42:24 dwmw2 Exp $
+# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $
menu "NAND Flash Device Drivers"
depends on MTD!=n
@@ -58,20 +58,6 @@ config MTD_NAND_TOTO
config MTD_NAND_IDS
tristate
-config MTD_NAND_TX4925NDFMC
- tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
- depends on TOSHIBA_RBTX4925 && MTD_NAND && TOSHIBA_RBTX4925_MPLEX_NAND
- help
- This enables the driver for the NAND flash device found on the
- Toshiba RBTX4925 reference board, which is a SmartMediaCard.
-
-config MTD_NAND_TX4938NDFMC
- tristate "NAND Flash device on Toshiba RBTX4938 reference board"
- depends on TOSHIBA_RBTX4938 && MTD_NAND && TOSHIBA_RBTX4938_MPLEX_NAND
- help
- This enables the driver for the NAND flash device found on the
- Toshiba RBTX4938 reference board.
-
config MTD_NAND_AU1550
tristate "Au1550 NAND support"
depends on SOC_AU1550 && MTD_NAND
@@ -95,10 +81,11 @@ config MTD_NAND_PPCHAMELEONEVB
This enables the NAND flash driver on the PPChameleon EVB Board.
config MTD_NAND_S3C2410
- tristate "NAND Flash support for S3C2410 SoC"
+ tristate "NAND Flash support for S3C2410/S3C2440 SoC"
depends on ARCH_S3C2410 && MTD_NAND
help
- This enables the NAND flash controller on the S3C2410.
+ This enables the NAND flash controller on the S3C2410 and S3C2440
+ SoCs
No board specfic support is done by this driver, each board
must advertise a platform_device for the driver to attach.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d9dc8cc2da8..41742026a52 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,8 +10,6 @@ obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
-obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o
-obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 02135c3ac29..fdb5d4ad3d5 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -16,7 +16,7 @@
*
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
- * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
+ * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $
*/
#include <linux/kernel.h>
@@ -35,13 +35,13 @@
#include <linux/mtd/inftl.h>
/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
-#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
+#ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS
+#define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0
#endif
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
+#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
@@ -81,11 +81,6 @@ struct doc_priv {
struct mtd_info *nextdoc;
};
-/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL
- MediaHeader. The spec says to just keep going, I think, but that's just
- silly. */
-#define MAX_MEDIAHEADER_SCAN 8
-
/* This is the syndrome computed by the HW ecc generator upon reading an empty
page, one with all 0xff for data and stored ecc code. */
static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
@@ -111,10 +106,11 @@ module_param(try_dword, int, 0);
static int no_ecc_failures=0;
module_param(no_ecc_failures, int, 0);
-#ifdef CONFIG_MTD_PARTITIONS
static int no_autopart=0;
module_param(no_autopart, int, 0);
-#endif
+
+static int show_firmware_partition=0;
+module_param(show_firmware_partition, int, 0);
#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
static int inftl_bbt_write=1;
@@ -123,7 +119,7 @@ static int inftl_bbt_write=0;
#endif
module_param(inftl_bbt_write, int, 0);
-static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
+static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS;
module_param(doc_config_location, ulong, 0);
MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
@@ -410,7 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
this->write_byte(mtd, 0);
doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-
+
+ /* We cant' use dev_ready here, but at least we wait for the
+ * command to complete
+ */
+ udelay(50);
+
ret = this->read_byte(mtd) << 8;
ret |= this->read_byte(mtd);
@@ -429,6 +430,8 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
doc2000_write_byte(mtd, 0);
doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
+ udelay(50);
+
ident.dword = readl(docptr + DoC_2k_CDSN_IO);
if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
@@ -1046,11 +1049,21 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
//u_char mydatabuf[528];
+/* The strange out-of-order .oobfree list below is a (possibly unneeded)
+ * attempt to retain compatibility. It used to read:
+ * .oobfree = { {8, 8} }
+ * Since that leaves two bytes unusable, it was changed. But the following
+ * scheme might affect existing jffs2 installs by moving the cleanmarker:
+ * .oobfree = { {6, 10} }
+ * jffs2 seems to handle the above gracefully, but the current scheme seems
+ * safer. The only problem with it is that any code that parses oobfree must
+ * be able to handle out-of-order segments.
+ */
static struct nand_oobinfo doc200x_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 4, 5},
- .oobfree = { {8, 8} }
+ .oobfree = { {8, 8}, {6, 2} }
};
/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1064,12 +1077,11 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = this->priv;
- unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);
+ unsigned offs;
int ret;
size_t retlen;
- end = min(end, mtd->size); // paranoia
- for (offs = 0; offs < end; offs += mtd->erasesize) {
+ for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
if (retlen != mtd->oobblock) continue;
if (ret) {
@@ -1111,6 +1123,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
u_char *buf;
struct NFTLMediaHeader *mh;
const unsigned psize = 1 << this->page_shift;
+ int numparts = 0;
unsigned blocks, maxblocks;
int offs, numheaders;
@@ -1122,8 +1135,10 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
mh = (struct NFTLMediaHeader *) buf;
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
+ mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits);
+ mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN);
+ mh->FormattedSize = le32_to_cpu(mh->FormattedSize);
+
printk(KERN_INFO " DataOrgID = %s\n"
" NumEraseUnits = %d\n"
" FirstPhysicalEUN = %d\n"
@@ -1132,7 +1147,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
mh->DataOrgID, mh->NumEraseUnits,
mh->FirstPhysicalEUN, mh->FormattedSize,
mh->UnitSizeFactor);
-//#endif
blocks = mtd->size >> this->phys_erase_shift;
maxblocks = min(32768U, mtd->erasesize - psize);
@@ -1175,23 +1189,28 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
offs <<= this->page_shift;
offs += mtd->erasesize;
- //parts[0].name = " DiskOnChip Boot / Media Header partition";
- //parts[0].offset = 0;
- //parts[0].size = offs;
+ if (show_firmware_partition == 1) {
+ parts[0].name = " DiskOnChip Firmware / Media Header partition";
+ parts[0].offset = 0;
+ parts[0].size = offs;
+ numparts = 1;
+ }
- parts[0].name = " DiskOnChip BDTL partition";
- parts[0].offset = offs;
- parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
+ parts[numparts].name = " DiskOnChip BDTL partition";
+ parts[numparts].offset = offs;
+ parts[numparts].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
+
+ offs += parts[numparts].size;
+ numparts++;
- offs += parts[0].size;
if (offs < mtd->size) {
- parts[1].name = " DiskOnChip Remainder partition";
- parts[1].offset = offs;
- parts[1].size = mtd->size - offs;
- ret = 2;
- goto out;
+ parts[numparts].name = " DiskOnChip Remainder partition";
+ parts[numparts].offset = offs;
+ parts[numparts].size = mtd->size - offs;
+ numparts++;
}
- ret = 1;
+
+ ret = numparts;
out:
kfree(buf);
return ret;
@@ -1233,8 +1252,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
printk(KERN_INFO " bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n"
@@ -1252,7 +1269,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
((unsigned char *) &mh->OsakVersion)[2] & 0xf,
((unsigned char *) &mh->OsakVersion)[3] & 0xf,
mh->PercentUsed);
-//#endif
vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
@@ -1278,8 +1294,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
ip->spareUnits = le32_to_cpu(ip->spareUnits);
ip->Reserved0 = le32_to_cpu(ip->Reserved0);
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
printk(KERN_INFO " PARTITION[%d] ->\n"
" virtualUnits = %d\n"
" firstUnit = %d\n"
@@ -1289,16 +1303,14 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
i, ip->virtualUnits, ip->firstUnit,
ip->lastUnit, ip->flags,
ip->spareUnits);
-//#endif
-/*
- if ((i == 0) && (ip->firstUnit > 0)) {
+ if ((show_firmware_partition == 1) &&
+ (i == 0) && (ip->firstUnit > 0)) {
parts[0].name = " DiskOnChip IPL / Media Header partition";
parts[0].offset = 0;
parts[0].size = mtd->erasesize * ip->firstUnit;
numparts = 1;
}
-*/
if (ip->flags & INFTL_BINARY)
parts[numparts].name = " DiskOnChip BDK partition";
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 44d5b128911..1bd71a598c7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -28,6 +28,24 @@
* among multiple independend devices. Suggestions and initial patch
* from Ben Dooks <ben-mtd@fluff.org>
*
+ * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
+ * Basically, any block not rewritten may lose data when surrounding blocks
+ * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
+ * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
+ * do not lose data, force them to be rewritten when some of the surrounding
+ * blocks are erased. Rather than tracking a specific nearby block (which
+ * could itself go bad), use a page address 'mask' to select several blocks
+ * in the same area, and rewrite the BBT when any of them are erased.
+ *
+ * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
+ * AG-AND chips. If there was a sudden loss of power during an erase operation,
+ * a "device recovery" operation must be performed when power is restored
+ * to ensure correct operation.
+ *
+ * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
+ * perform extra error status checks on erase and write failures. This required
+ * adding a wrapper function for nand_read_ecc.
+ *
* Credits:
* David Woodhouse for adding multichip support
*
@@ -41,7 +59,7 @@
* The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go.
*
- * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $
+ * $Id: nand_base.c,v 1.146 2005/06/17 15:02:06 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -149,17 +167,21 @@ static void nand_release_device (struct mtd_info *mtd)
/* De-select the NAND device */
this->select_chip(mtd, -1);
- /* Do we have a hardware controller ? */
+
if (this->controller) {
+ /* Release the controller and the chip */
spin_lock(&this->controller->lock);
this->controller->active = NULL;
+ this->state = FL_READY;
+ wake_up(&this->controller->wq);
spin_unlock(&this->controller->lock);
+ } else {
+ /* Release the chip */
+ spin_lock(&this->chip_lock);
+ this->state = FL_READY;
+ wake_up(&this->wq);
+ spin_unlock(&this->chip_lock);
}
- /* Release the chip */
- spin_lock (&this->chip_lock);
- this->state = FL_READY;
- wake_up (&this->wq);
- spin_unlock (&this->chip_lock);
}
/**
@@ -443,7 +465,8 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* Get block number */
block = ((int) ofs) >> this->bbt_erase_shift;
- this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+ if (this->bbt)
+ this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
/* Do we have a flash based bad block table ? */
if (this->options & NAND_USE_FLASH_BBT)
@@ -466,7 +489,7 @@ static int nand_check_wp (struct mtd_info *mtd)
struct nand_chip *this = mtd->priv;
/* Check the WP bit */
this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
- return (this->read_byte(mtd) & 0x80) ? 0 : 1;
+ return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
}
/**
@@ -490,6 +513,22 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
return nand_isbad_bbt (mtd, ofs, allowbbt);
}
+/*
+ * Wait for the ready pin, after a command
+ * The timeout is catched later.
+ */
+static void nand_wait_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long timeo = jiffies + 2;
+
+ /* wait until command is processed or timeout occures */
+ do {
+ if (this->dev_ready(mtd))
+ return;
+ } while (time_before(jiffies, timeo));
+}
+
/**
* nand_command - [DEFAULT] Send command to NAND device
* @mtd: MTD device structure
@@ -571,7 +610,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
this->hwcontrol(mtd, NAND_CTL_SETCLE);
this->write_byte(mtd, NAND_CMD_STATUS);
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- while ( !(this->read_byte(mtd) & 0x40));
+ while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
return;
/* This applies to read commands */
@@ -585,12 +624,11 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
return;
}
}
-
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
ndelay (100);
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
+
+ nand_wait_ready(mtd);
}
/**
@@ -619,7 +657,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/* Begin command latch cycle */
this->hwcontrol(mtd, NAND_CTL_SETCLE);
/* Write out the command to the device. */
- this->write_byte(mtd, command);
+ this->write_byte(mtd, (command & 0xff));
/* End command latch cycle */
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
@@ -647,8 +685,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/*
* program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
+ * status, sequential in, and deplete1 need no delay
+ */
switch (command) {
case NAND_CMD_CACHEDPROG:
@@ -657,8 +695,19 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
case NAND_CMD_ERASE2:
case NAND_CMD_SEQIN:
case NAND_CMD_STATUS:
+ case NAND_CMD_DEPLETE1:
return;
+ /*
+ * read error status commands require only a short delay
+ */
+ case NAND_CMD_STATUS_ERROR:
+ case NAND_CMD_STATUS_ERROR0:
+ case NAND_CMD_STATUS_ERROR1:
+ case NAND_CMD_STATUS_ERROR2:
+ case NAND_CMD_STATUS_ERROR3:
+ udelay(this->chip_delay);
+ return;
case NAND_CMD_RESET:
if (this->dev_ready)
@@ -667,7 +716,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
this->hwcontrol(mtd, NAND_CTL_SETCLE);
this->write_byte(mtd, NAND_CMD_STATUS);
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- while ( !(this->read_byte(mtd) & 0x40));
+ while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
return;
case NAND_CMD_READ0:
@@ -690,12 +739,12 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
return;
}
}
-
+
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
ndelay (100);
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
+
+ nand_wait_ready(mtd);
}
/**
@@ -708,37 +757,34 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
*/
static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
{
- struct nand_chip *active = this;
-
+ struct nand_chip *active;
+ spinlock_t *lock;
+ wait_queue_head_t *wq;
DECLARE_WAITQUEUE (wait, current);
- /*
- * Grab the lock and see if the device is available
- */
+ lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
+ wq = (this->controller) ? &this->controller->wq : &this->wq;
retry:
+ active = this;
+ spin_lock(lock);
+
/* Hardware controller shared among independend devices */
if (this->controller) {
- spin_lock (&this->controller->lock);
if (this->controller->active)
active = this->controller->active;
else
this->controller->active = this;
- spin_unlock (&this->controller->lock);
}
-
- if (active == this) {
- spin_lock (&this->chip_lock);
- if (this->state == FL_READY) {
- this->state = new_state;
- spin_unlock (&this->chip_lock);
- return;
- }
- }
- set_current_state (TASK_UNINTERRUPTIBLE);
- add_wait_queue (&active->wq, &wait);
- spin_unlock (&active->chip_lock);
- schedule ();
- remove_wait_queue (&active->wq, &wait);
+ if (active == this && this->state == FL_READY) {
+ this->state = new_state;
+ spin_unlock(lock);
+ return;
+ }
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(wq, &wait);
+ spin_unlock(lock);
+ schedule();
+ remove_wait_queue(wq, &wait);
goto retry;
}
@@ -785,7 +831,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
if (this->read_byte(mtd) & NAND_STATUS_READY)
break;
}
- yield ();
+ cond_resched();
}
status = (int) this->read_byte(mtd);
return status;
@@ -871,8 +917,14 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
if (!cached) {
/* call wait ready function */
status = this->waitfunc (mtd, this, FL_WRITING);
+
+ /* See if operation failed and additional status checks are available */
+ if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
+ status = this->errstat(mtd, this, FL_WRITING, status, page);
+ }
+
/* See if device thinks it succeeded */
- if (status & 0x01) {
+ if (status & NAND_STATUS_FAIL) {
DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
return -EIO;
}
@@ -975,7 +1027,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
if (!this->dev_ready)
udelay (this->chip_delay);
else
- while (!this->dev_ready(mtd));
+ nand_wait_ready(mtd);
/* All done, return happy */
if (!numpages)
@@ -997,23 +1049,24 @@ out:
#endif
/**
- * nand_read - [MTD Interface] MTD compability function for nand_read_ecc
+ * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
* @mtd: MTD device structure
* @from: offset to read from
* @len: number of bytes to read
* @retlen: pointer to variable to store the number of read bytes
* @buf: the databuffer to put data
*
- * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL
-*/
+ * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
+ * and flags = 0xff
+ */
static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
{
- return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
-}
+ return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
+}
/**
- * nand_read_ecc - [MTD Interface] Read data with ECC
+ * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
* @mtd: MTD device structure
* @from: offset to read from
* @len: number of bytes to read
@@ -1022,11 +1075,39 @@ static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * re
* @oob_buf: filesystem supplied oob data buffer
* @oobsel: oob selection structure
*
- * NAND read with ECC
+ * This function simply calls nand_do_read_ecc with flags = 0xff
*/
static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
{
+ /* use userspace supplied oobinfo, if zero */
+ if (oobsel == NULL)
+ oobsel = &mtd->oobinfo;
+ return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
+}
+
+
+/**
+ * nand_do_read_ecc - [MTD Interface] Read data with ECC
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @retlen: pointer to variable to store the number of read bytes
+ * @buf: the databuffer to put data
+ * @oob_buf: filesystem supplied oob data buffer (can be NULL)
+ * @oobsel: oob selection structure
+ * @flags: flag to indicate if nand_get_device/nand_release_device should be preformed
+ * and how many corrected error bits are acceptable:
+ * bits 0..7 - number of tolerable errors
+ * bit 8 - 0 == do not get/release chip, 1 == get/release chip
+ *
+ * NAND read with ECC
+ */
+int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t * retlen, u_char * buf, u_char * oob_buf,
+ struct nand_oobinfo *oobsel, int flags)
+{
+
int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
struct nand_chip *this = mtd->priv;
@@ -1051,12 +1132,9 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
}
/* Grab the lock and see if the device is available */
- nand_get_device (this, mtd ,FL_READING);
+ if (flags & NAND_GET_DEVICE)
+ nand_get_device (this, mtd, FL_READING);
- /* use userspace supplied oobinfo, if zero */
- if (oobsel == NULL)
- oobsel = &mtd->oobinfo;
-
/* Autoplace of oob data ? Use the default placement scheme */
if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
oobsel = this->autooob;
@@ -1118,7 +1196,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
}
/* get oob area, if we have no oob buffer from fs-driver */
- if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE)
+ if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
+ oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
oob_data = &this->data_buf[end];
eccsteps = this->eccsteps;
@@ -1155,7 +1234,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* We calc error correction directly, it checks the hw
* generator for an error, reads back the syndrome and
* does the error correction on the fly */
- if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) {
+ ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
+ if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
"Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
ecc_failed++;
@@ -1194,7 +1274,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
p[i] = ecc_status;
}
- if (ecc_status == -1) {
+ if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
ecc_failed++;
}
@@ -1206,14 +1286,14 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* without autoplace. Legacy mode used by YAFFS1 */
switch(oobsel->useecc) {
case MTD_NANDECC_AUTOPLACE:
+ case MTD_NANDECC_AUTOPL_USR:
/* Walk through the autoplace chunks */
- for (i = 0, j = 0; j < mtd->oobavail; i++) {
+ for (i = 0; oobsel->oobfree[i][1]; i++) {
int from = oobsel->oobfree[i][0];
int num = oobsel->oobfree[i][1];
memcpy(&oob_buf[oob], &oob_data[from], num);
- j+= num;
+ oob += num;
}
- oob += mtd->oobavail;
break;
case MTD_NANDECC_PLACE:
/* YAFFS1 legacy mode */
@@ -1239,7 +1319,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
if (!this->dev_ready)
udelay (this->chip_delay);
else
- while (!this->dev_ready(mtd));
+ nand_wait_ready(mtd);
if (read == len)
break;
@@ -1264,7 +1344,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
}
/* Deselect and wake up anyone waiting on the device */
- nand_release_device(mtd);
+ if (flags & NAND_GET_DEVICE)
+ nand_release_device(mtd);
/*
* Return success, if no ECC failures, else -EBADMSG
@@ -1337,7 +1418,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
if (!this->dev_ready)
udelay (this->chip_delay);
else
- while (!this->dev_ready(mtd));
+ nand_wait_ready(mtd);
/* Read more ? */
if (i < len) {
@@ -1417,7 +1498,7 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
if (!this->dev_ready)
udelay (this->chip_delay);
else
- while (!this->dev_ready(mtd));
+ nand_wait_ready(mtd);
/* Check, if the chip supports auto page increment */
if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
@@ -1567,6 +1648,8 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
oobsel = this->autooob;
autoplace = 1;
}
+ if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+ autoplace = 1;
/* Setup variables and oob buffer */
totalpages = len >> this->page_shift;
@@ -1733,7 +1816,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
status = this->waitfunc (mtd, this, FL_WRITING);
/* See if device thinks it succeeded */
- if (status & 0x01) {
+ if (status & NAND_STATUS_FAIL) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
ret = -EIO;
goto out;
@@ -1841,6 +1924,8 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
oobsel = this->autooob;
autoplace = 1;
}
+ if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+ autoplace = 1;
/* Setup start page */
page = (int) (to >> this->page_shift);
@@ -1987,6 +2072,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
return nand_erase_nand (mtd, instr, 0);
}
+#define BBT_PAGE_MASK 0xffffff3f
/**
* nand_erase_intern - [NAND Interface] erase block(s)
* @mtd: MTD device structure
@@ -1999,6 +2085,10 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
{
int page, len, status, pages_per_block, ret, chipnr;
struct nand_chip *this = mtd->priv;
+ int rewrite_bbt[NAND_MAX_CHIPS]={0}; /* flags to indicate the page, if bbt needs to be rewritten. */
+ unsigned int bbt_masked_page; /* bbt mask to compare to page being erased. */
+ /* It is used to see if the current page is in the same */
+ /* 256 block group and the same bank as the bbt. */
DEBUG (MTD_DEBUG_LEVEL3,
"nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
@@ -2044,6 +2134,13 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
goto erase_exit;
}
+ /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
+ if (this->options & BBT_AUTO_REFRESH) {
+ bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
+ } else {
+ bbt_masked_page = 0xffffffff; /* should not match anything */
+ }
+
/* Loop through the pages */
len = instr->len;
@@ -2066,13 +2163,26 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
status = this->waitfunc (mtd, this, FL_ERASING);
+ /* See if operation failed and additional status checks are available */
+ if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
+ status = this->errstat(mtd, this, FL_ERASING, status, page);
+ }
+
/* See if block erase succeeded */
- if (status & 0x01) {
+ if (status & NAND_STATUS_FAIL) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
instr->state = MTD_ERASE_FAILED;
instr->fail_addr = (page << this->page_shift);
goto erase_exit;
}
+
+ /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
+ if (this->options & BBT_AUTO_REFRESH) {
+ if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
+ (page != this->bbt_td->pages[chipnr])) {
+ rewrite_bbt[chipnr] = (page << this->page_shift);
+ }
+ }
/* Increment page address and decrement length */
len -= (1 << this->phys_erase_shift);
@@ -2083,6 +2193,13 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
chipnr++;
this->select_chip(mtd, -1);
this->select_chip(mtd, chipnr);
+
+ /* if BBT requires refresh and BBT-PERCHIP,
+ * set the BBT page mask to see if this BBT should be rewritten */
+ if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
+ bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
+ }
+
}
}
instr->state = MTD_ERASE_DONE;
@@ -2097,6 +2214,18 @@ erase_exit:
/* Deselect and wake up anyone waiting on the device */
nand_release_device(mtd);
+ /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
+ if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
+ for (chipnr = 0; chipnr < this->numchips; chipnr++) {
+ if (rewrite_bbt[chipnr]) {
+ /* update the BBT for chip */
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
+ chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
+ nand_update_bbt (mtd, rewrite_bbt[chipnr]);
+ }
+ }
+ }
+
/* Return more or less happy */
return ret;
}
@@ -2168,7 +2297,7 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
*/
int nand_scan (struct mtd_info *mtd, int maxchips)
{
- int i, j, nand_maf_id, nand_dev_id, busw;
+ int i, nand_maf_id, nand_dev_id, busw, maf_id;
struct nand_chip *this = mtd->priv;
/* Get buswidth to select the correct functions*/
@@ -2256,12 +2385,18 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
}
+ /* Try to identify manufacturer */
+ for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
+ if (nand_manuf_ids[maf_id].id == nand_maf_id)
+ break;
+ }
+
/* Check, if buswidth is correct. Hardware drivers should set
* this correct ! */
if (busw != (this->options & NAND_BUSWIDTH_16)) {
printk (KERN_INFO "NAND device: Manufacturer ID:"
" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
- nand_manuf_ids[i].name , mtd->name);
+ nand_manuf_ids[maf_id].name , mtd->name);
printk (KERN_WARNING
"NAND bus width %d instead %d bit\n",
(this->options & NAND_BUSWIDTH_16) ? 16 : 8,
@@ -2300,14 +2435,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
this->cmdfunc = nand_command_lp;
- /* Try to identify manufacturer */
- for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
- if (nand_manuf_ids[j].id == nand_maf_id)
- break;
- }
printk (KERN_INFO "NAND device: Manufacturer ID:"
" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
- nand_manuf_ids[j].name , nand_flash_ids[i].name);
+ nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
break;
}
@@ -2388,12 +2518,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
/* The number of bytes available for the filesystem to place fs dependend
* oob data */
- if (this->options & NAND_BUSWIDTH_16) {
- mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2);
- if (this->autooob->eccbytes & 0x01)
- mtd->oobavail--;
- } else
- mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1);
+ mtd->oobavail = 0;
+ for (i = 0; this->autooob->oobfree[i][1]; i++)
+ mtd->oobavail += this->autooob->oobfree[i][1];
/*
* check ECC mode, default to software
@@ -2524,6 +2651,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
mtd->owner = THIS_MODULE;
+
+ /* Check, if we should skip the bad block table scan */
+ if (this->options & NAND_SKIP_BBTSCAN)
+ return 0;
/* Build bad block table */
return this->scan_bbt (mtd);
@@ -2555,8 +2686,8 @@ void nand_release (struct mtd_info *mtd)
kfree (this->data_buf);
}
-EXPORT_SYMBOL (nand_scan);
-EXPORT_SYMBOL (nand_release);
+EXPORT_SYMBOL_GPL (nand_scan);
+EXPORT_SYMBOL_GPL (nand_release);
MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 9a1949751c1..5ac2d296222 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -6,7 +6,7 @@
*
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
- * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
+ * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -77,7 +77,7 @@
*/
static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
{
- int i, end;
+ int i, end = 0;
uint8_t *p = buf;
end = paglen + td->offs;
@@ -95,9 +95,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
return -1;
}
- p += td->len;
- end += td->len;
if (td->options & NAND_BBT_SCANEMPTY) {
+ p += td->len;
+ end += td->len;
for (i = end; i < len; i++) {
if (*p++ != 0xff)
return -1;
@@ -106,6 +106,32 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
return 0;
}
+/**
+ * check_short_pattern - [GENERIC] check if a pattern is in the buffer
+ * @buf: the buffer to search
+ * @len: the length of buffer to search
+ * @paglen: the pagelength
+ * @td: search pattern descriptor
+ *
+ * Check for a pattern at the given place. Used to search bad block
+ * tables and good / bad block identifiers. Same as check_pattern, but
+ * no optional empty check and the pattern is expected to start
+ * at offset 0.
+ *
+*/
+static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
+{
+ int i;
+ uint8_t *p = buf;
+
+ /* Compare the pattern */
+ for (i = 0; i < td->len; i++) {
+ if (p[i] != td->pattern[i])
+ return -1;
+ }
+ return 0;
+}
+
/**
* read_bbt - [GENERIC] Read the bad block table starting from page
* @mtd: MTD device structure
@@ -252,7 +278,7 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
* Create a bad block table by scanning the device
* for the given good/bad block identify pattern
*/
-static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
+static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
{
struct nand_chip *this = mtd->priv;
int i, j, numblocks, len, scanlen;
@@ -270,9 +296,17 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
else
len = 1;
}
- scanlen = mtd->oobblock + mtd->oobsize;
- readlen = len * mtd->oobblock;
- ooblen = len * mtd->oobsize;
+
+ if (!(bd->options & NAND_BBT_SCANEMPTY)) {
+ /* We need only read few bytes from the OOB area */
+ scanlen = ooblen = 0;
+ readlen = bd->len;
+ } else {
+ /* Full page content should be read */
+ scanlen = mtd->oobblock + mtd->oobsize;
+ readlen = len * mtd->oobblock;
+ ooblen = len * mtd->oobsize;
+ }
if (chip == -1) {
/* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
@@ -284,7 +318,7 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
if (chip >= this->numchips) {
printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
chip + 1, this->numchips);
- return;
+ return -EINVAL;
}
numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
startblock = chip * numblocks;
@@ -293,18 +327,41 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
}
for (i = startblock; i < numblocks;) {
- nand_read_raw (mtd, buf, from, readlen, ooblen);
+ int ret;
+
+ if (bd->options & NAND_BBT_SCANEMPTY)
+ if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
+ return ret;
+
for (j = 0; j < len; j++) {
- if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
- this->bbt[i >> 3] |= 0x03 << (i & 0x6);
- printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
- i >> 1, (unsigned int) from);
- break;
+ if (!(bd->options & NAND_BBT_SCANEMPTY)) {
+ size_t retlen;
+
+ /* No need to read pages fully, just read required OOB bytes */
+ ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
+ readlen, &retlen, &buf[0]);
+ if (ret)
+ return ret;
+
+ if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+ this->bbt[i >> 3] |= 0x03 << (i & 0x6);
+ printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ i >> 1, (unsigned int) from);
+ break;
+ }
+ } else {
+ if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+ this->bbt[i >> 3] |= 0x03 << (i & 0x6);
+ printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ i >> 1, (unsigned int) from);
+ break;
+ }
}
}
i += 2;
from += (1 << this->bbt_erase_shift);
}
+ return 0;
}
/**
@@ -589,14 +646,12 @@ write:
* The function creates a memory based bbt by scanning the device
* for manufacturer / software marked good / bad blocks
*/
-static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
{
struct nand_chip *this = mtd->priv;
- /* Ensure that we only scan for the pattern and nothing else */
- bd->options = 0;
- create_bbt (mtd, this->data_buf, bd, -1);
- return 0;
+ bd->options &= ~NAND_BBT_SCANEMPTY;
+ return create_bbt (mtd, this->data_buf, bd, -1);
}
/**
@@ -808,8 +863,14 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
/* If no primary table decriptor is given, scan the device
* to build a memory based bad block table
*/
- if (!td)
- return nand_memory_bbt(mtd, bd);
+ if (!td) {
+ if ((res = nand_memory_bbt(mtd, bd))) {
+ printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+ kfree (this->bbt);
+ this->bbt = NULL;
+ }
+ return res;
+ }
/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
@@ -904,14 +965,11 @@ out:
}
/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks
- *
- * The memory based patterns just
- */
+ * while scanning a device for factory marked good / bad blocks. */
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr smallpage_memorybased = {
- .options = 0,
+ .options = NAND_BBT_SCAN2NDPAGE,
.offs = 5,
.len = 1,
.pattern = scan_ff_pattern
@@ -1042,7 +1100,7 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
- (unsigned int)offs, res, block >> 1);
+ (unsigned int)offs, block >> 1, res);
switch ((int)res) {
case 0x00: return 0;
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 2d8c4321275..efe246961b6 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -2,8 +2,8 @@
* drivers/mtd/nandids.c
*
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
- *
- * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $
+ *
+ * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -56,17 +56,24 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
+ {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
{"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+ {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
- {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0},
-
/* These are the new chips with large page size. The pagesize
* and the erasesize is determined from the extended id bytes
*/
+ /*512 Megabit */
+ {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+ {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+ {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+ {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+
/* 1 Gigabit */
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -103,7 +110,7 @@ struct nand_flash_dev nand_flash_ids[] = {
* Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
* There are more speed improvements for reads and writes possible, but not implemented now
*/
- {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},
+ {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
{NULL,}
};
@@ -118,6 +125,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_NATIONAL, "National"},
{NAND_MFR_RENESAS, "Renesas"},
{NAND_MFR_STMICRO, "ST Micro"},
+ {NAND_MFR_HYNIX, "Hynix"},
{0x0, "Unknown"}
};
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 13feefd7d8c..754b6ed7ce1 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: nandsim.c,v 1.7 2004/12/06 11:53:06 dedekind Exp $
+ * $Id: nandsim.c,v 1.8 2005/03/19 15:33:56 dedekind Exp $
*/
#include <linux/config.h>
@@ -1484,33 +1484,6 @@ ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
}
/*
- * Having only NAND chip IDs we call nand_scan which detects NAND flash
- * parameters and then calls scan_bbt in order to scan/find/build the
- * NAND flash bad block table. But since at that moment the NAND flash
- * image isn't allocated in the simulator, errors arise. To avoid this
- * we redefine the scan_bbt callback and initialize the nandsim structure
- * before the flash media scanning.
- */
-int ns_scan_bbt(struct mtd_info *mtd)
-{
- struct nand_chip *chip = (struct nand_chip *)mtd->priv;
- struct nandsim *ns = (struct nandsim *)(chip->priv);
- int retval;
-
- if (!NS_IS_INITIALIZED(ns))
- if ((retval = init_nandsim(mtd)) != 0) {
- NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
- return retval;
- }
- if ((retval = nand_default_bbt(mtd)) != 0) {
- free_nandsim(ns);
- return retval;
- }
-
- return 0;
-}
-
-/*
* Module initialization function
*/
int __init ns_init_module(void)
@@ -1544,7 +1517,6 @@ int __init ns_init_module(void)
chip->hwcontrol = ns_hwcontrol;
chip->read_byte = ns_nand_read_byte;
chip->dev_ready = ns_device_ready;
- chip->scan_bbt = ns_scan_bbt;
chip->write_byte = ns_nand_write_byte;
chip->write_buf = ns_nand_write_buf;
chip->read_buf = ns_nand_read_buf;
@@ -1552,6 +1524,7 @@ int __init ns_init_module(void)
chip->write_word = ns_nand_write_word;
chip->read_word = ns_nand_read_word;
chip->eccmode = NAND_ECC_SOFT;
+ chip->options |= NAND_SKIP_BBTSCAN;
/*
* Perform minimum nandsim structure initialization to handle
@@ -1580,6 +1553,16 @@ int __init ns_init_module(void)
goto error;
}
+ if ((retval = init_nandsim(nsmtd)) != 0) {
+ NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
+ goto error;
+ }
+
+ if ((retval = nand_default_bbt(nsmtd)) != 0) {
+ free_nandsim(nand);
+ goto error;
+ }
+
/* Register NAND as one big partition */
add_mtd_partitions(nsmtd, &nand->part, 1);
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 02305a2adca..031051cbde7 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
- * $Id: rtc_from4.c,v 1.7 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -83,13 +83,18 @@ static struct mtd_info *rtc_from4_mtd = NULL;
#define RTC_FROM4_RS_ECC_CHK (RTC_FROM4_NAND_ADDR_FPGA | 0x00000070)
#define RTC_FROM4_RS_ECC_CHK_ERROR (1 << 7)
+#define ERR_STAT_ECC_AVAILABLE 0x20
+
/* Undefine for software ECC */
#define RTC_FROM4_HWECC 1
+/* Define as 1 for no virtual erase blocks (in JFFS2) */
+#define RTC_FROM4_NO_VIRTBLOCKS 0
+
/*
* Module stuff
*/
-static void __iomem *rtc_from4_fio_base = P2SEGADDR(RTC_FROM4_FIO_BASE);
+static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
const static struct mtd_partition partition_info[] = {
{
@@ -267,7 +272,6 @@ static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
}
-
/*
* rtc_from4_nand_device_ready - hardware specific ready/busy check
* @mtd: MTD device structure
@@ -286,6 +290,40 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
}
+
+/*
+ * deplete - code to perform device recovery in case there was a power loss
+ * @mtd: MTD device structure
+ * @chip: Chip to select (0 == slot 3, 1 == slot 4)
+ *
+ * If there was a sudden loss of power during an erase operation, a
+ * "device recovery" operation must be performed when power is restored
+ * to ensure correct operation. This routine performs the required steps
+ * for the requested chip.
+ *
+ * See page 86 of the data sheet for details.
+ *
+ */
+static void deplete(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *this = mtd->priv;
+
+ /* wait until device is ready */
+ while (!this->dev_ready(mtd));
+
+ this->select_chip(mtd, chip);
+
+ /* Send the commands for device recovery, phase 1 */
+ this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
+ this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+
+ /* Send the commands for device recovery, phase 2 */
+ this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
+ this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+
+}
+
+
#ifdef RTC_FROM4_HWECC
/*
* rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -329,6 +367,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
}
+
/*
* rtc_from4_calculate_ecc - hardware specific code to read ECC code
* @mtd: MTD device structure
@@ -356,6 +395,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
ecc_code[7] |= 0x0f; /* set the last four bits (not used) */
}
+
/*
* rtc_from4_correct_data - hardware specific code to correct data using ECC code
* @mtd: MTD device structure
@@ -365,16 +405,14 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
*
* The FPGA tells us fast, if there's an error or not. If no, we go back happy
* else we read the ecc results from the fpga and call the rs library to decode
- * and hopefully correct the error
+ * and hopefully correct the error.
*
- * For now I use the code, which we read from the FLASH to use the RS lib,
- * as the syndrom conversion has a unresolved issue.
*/
static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
{
int i, j, res;
unsigned short status;
- uint16_t par[6], syn[6], tmp;
+ uint16_t par[6], syn[6];
uint8_t ecc[8];
volatile unsigned short *rs_ecc;
@@ -416,15 +454,86 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
}
/* Let the library code do its magic.*/
- res = decode_rs8(rs_decoder, buf, par, 512, syn, 0, NULL, 0xff, NULL);
+ res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
if (res > 0) {
DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
"ECC corrected %d errors on read\n", res);
}
return res;
}
+
+
+/**
+ * rtc_from4_errstat - perform additional error status checks
+ * @mtd: MTD device structure
+ * @this: NAND chip structure
+ * @state: state or the operation
+ * @status: status code returned from read status
+ * @page: startpage inside the chip, must be called with (page & this->pagemask)
+ *
+ * Perform additional error status checks on erase and write failures
+ * to determine if errors are correctable. For this device, correctable
+ * 1-bit errors on erase and write are considered acceptable.
+ *
+ * note: see pages 34..37 of data sheet for details.
+ *
+ */
+static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
+{
+ int er_stat=0;
+ int rtn, retlen;
+ size_t len;
+ uint8_t *buf;
+ int i;
+
+ this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
+
+ if (state == FL_ERASING) {
+ for (i=0; i<4; i++) {
+ if (status & 1<<(i+1)) {
+ this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
+ rtn = this->read_byte(mtd);
+ this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+ if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
+ er_stat |= 1<<(i+1); /* err_ecc_not_avail */
+ }
+ }
+ }
+ } else if (state == FL_WRITING) {
+ /* single bank write logic */
+ this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1);
+ rtn = this->read_byte(mtd);
+ this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+ if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
+ er_stat |= 1<<1; /* err_ecc_not_avail */
+ } else {
+ len = mtd->oobblock;
+ buf = kmalloc (len, GFP_KERNEL);
+ if (!buf) {
+ printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n");
+ er_stat = 1; /* if we can't check, assume failed */
+ } else {
+ /* recovery read */
+ /* page read */
+ rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
+ if (rtn) { /* if read failed or > 1-bit error corrected */
+ er_stat |= 1<<1; /* ECC read failed */
+ }
+ kfree(buf);
+ }
+ }
+ }
+
+ rtn = status;
+ if (er_stat == 0) { /* if ECC is available */
+ rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */
+ }
+
+ return rtn;
+}
#endif
+
/*
* Main initialization routine
*/
@@ -432,6 +541,7 @@ int __init rtc_from4_init (void)
{
struct nand_chip *this;
unsigned short bcr1, bcr2, wcr2;
+ int i;
/* Allocate memory for MTD device structure and private data */
rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
@@ -483,6 +593,8 @@ int __init rtc_from4_init (void)
this->eccmode = NAND_ECC_HW8_512;
this->options |= NAND_HWECC_SYNDROME;
+ /* return the status of extra status and ECC checks */
+ this->errstat = rtc_from4_errstat;
/* set the nand_oobinfo to support FPGA H/W error detection */
this->autooob = &rtc_from4_nand_oobinfo;
this->enable_hwecc = rtc_from4_enable_hwecc;
@@ -504,6 +616,18 @@ int __init rtc_from4_init (void)
return -ENXIO;
}
+ /* Perform 'device recovery' for each chip in case there was a power loss. */
+ for (i=0; i < this->numchips; i++) {
+ deplete(rtc_from4_mtd, i);
+ }
+
+#if RTC_FROM4_NO_VIRTBLOCKS
+ /* use a smaller erase block to minimize wasted space when a block is bad */
+ /* note: this uses eight times as much RAM as using the default and makes */
+ /* mounts take four times as long. */
+ rtc_from4_mtd->flags |= MTD_NO_VIRTBLOCKS;
+#endif
+
/* Register the partitions */
add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS);
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index d05e9b97947..891e3a1b911 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -1,17 +1,24 @@
/* linux/drivers/mtd/nand/s3c2410.c
*
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004,2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
+ * Ben Dooks <ben@simtec.co.uk>
*
- * Samsung S3C2410 NAND driver
+ * Samsung S3C2410/S3C240 NAND driver
*
* Changelog:
* 21-Sep-2004 BJD Initial version
* 23-Sep-2004 BJD Mulitple device support
* 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
* 12-Oct-2004 BJD Fixed errors in use of platform data
+ * 18-Feb-2005 BJD Fix sparse errors
+ * 14-Mar-2005 BJD Applied tglx's code reduction patch
+ * 02-May-2005 BJD Fixed s3c2440 support
+ * 02-May-2005 BJD Reduced hwcontrol decode
+ * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
+ * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
*
- * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 Exp $
+ * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -69,10 +76,10 @@ static int hardware_ecc = 0;
*/
static struct nand_oobinfo nand_hw_eccoob = {
- .useecc = MTD_NANDECC_AUTOPLACE,
- .eccbytes = 3,
- .eccpos = {0, 1, 2 },
- .oobfree = { {8, 8} }
+ .useecc = MTD_NANDECC_AUTOPLACE,
+ .eccbytes = 3,
+ .eccpos = {0, 1, 2 },
+ .oobfree = { {8, 8} }
};
/* controller and mtd information */
@@ -99,8 +106,10 @@ struct s3c2410_nand_info {
struct device *device;
struct resource *area;
struct clk *clk;
- void *regs;
+ void __iomem *regs;
int mtd_count;
+
+ unsigned char is_s3c2440;
};
/* conversion functions */
@@ -165,12 +174,12 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
/* calculate the timing information for the controller */
if (plat != NULL) {
- tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8);
+ tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
} else {
/* default timings */
- tacls = 8;
+ tacls = 4;
twrph0 = 8;
twrph1 = 8;
}
@@ -185,10 +194,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
to_ns(twrph0, clkrate),
to_ns(twrph1, clkrate));
- cfg = S3C2410_NFCONF_EN;
- cfg |= S3C2410_NFCONF_TACLS(tacls-1);
- cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
- cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
+ if (!info->is_s3c2440) {
+ cfg = S3C2410_NFCONF_EN;
+ cfg |= S3C2410_NFCONF_TACLS(tacls-1);
+ cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
+ cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
+ } else {
+ cfg = S3C2440_NFCONF_TACLS(tacls-1);
+ cfg |= S3C2440_NFCONF_TWRPH0(twrph0-1);
+ cfg |= S3C2440_NFCONF_TWRPH1(twrph1-1);
+ }
pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
@@ -203,17 +218,22 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd;
struct nand_chip *this = mtd->priv;
+ void __iomem *reg;
unsigned long cur;
+ unsigned long bit;
nmtd = this->priv;
info = nmtd->info;
- cur = readl(info->regs + S3C2410_NFCONF);
+ bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
+ reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF);
+
+ cur = readl(reg);
if (chip == -1) {
- cur |= S3C2410_NFCONF_nFCE;
+ cur |= bit;
} else {
- if (chip > nmtd->set->nr_chips) {
+ if (nmtd->set != NULL && chip > nmtd->set->nr_chips) {
printk(KERN_ERR PFX "chip %d out of range\n", chip);
return;
}
@@ -223,143 +243,76 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
(info->platform->select_chip)(nmtd->set, chip);
}
- cur &= ~S3C2410_NFCONF_nFCE;
+ cur &= ~bit;
}
- writel(cur, info->regs + S3C2410_NFCONF);
+ writel(cur, reg);
}
-/* command and control functions */
+/* command and control functions
+ *
+ * Note, these all use tglx's method of changing the IO_ADDR_W field
+ * to make the code simpler, and use the nand layer's code to issue the
+ * command and address sequences via the proper IO ports.
+ *
+*/
static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
- unsigned long cur;
+ struct nand_chip *chip = mtd->priv;
switch (cmd) {
case NAND_CTL_SETNCE:
- cur = readl(info->regs + S3C2410_NFCONF);
- cur &= ~S3C2410_NFCONF_nFCE;
- writel(cur, info->regs + S3C2410_NFCONF);
- break;
-
case NAND_CTL_CLRNCE:
- cur = readl(info->regs + S3C2410_NFCONF);
- cur |= S3C2410_NFCONF_nFCE;
- writel(cur, info->regs + S3C2410_NFCONF);
+ printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
break;
- /* we don't need to implement these */
case NAND_CTL_SETCLE:
- case NAND_CTL_CLRCLE:
+ chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
+ break;
+
case NAND_CTL_SETALE:
- case NAND_CTL_CLRALE:
- pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd);
+ chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
+ break;
+
+ /* NAND_CTL_CLRCLE: */
+ /* NAND_CTL_CLRALE: */
+ default:
+ chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
break;
}
}
-/* s3c2410_nand_command
- *
- * This function implements sending commands and the relevant address
- * information to the chip, via the hardware controller. Since the
- * S3C2410 generates the correct ALE/CLE signaling automatically, we
- * do not need to use hwcontrol.
-*/
+/* command and control functions */
-static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command,
- int column, int page_addr)
+static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
- register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
- register struct nand_chip *this = mtd->priv;
+ struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+ struct nand_chip *chip = mtd->priv;
- /*
- * Write out the command to the device.
- */
- if (command == NAND_CMD_SEQIN) {
- int readcmd;
-
- if (column >= mtd->oobblock) {
- /* OOB area */
- column -= mtd->oobblock;
- readcmd = NAND_CMD_READOOB;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- readcmd = NAND_CMD_READ0;
- } else {
- column -= 256;
- readcmd = NAND_CMD_READ1;
- }
-
- writeb(readcmd, info->regs + S3C2410_NFCMD);
- }
- writeb(command, info->regs + S3C2410_NFCMD);
+ switch (cmd) {
+ case NAND_CTL_SETNCE:
+ case NAND_CTL_CLRNCE:
+ printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
+ break;
- /* Set ALE and clear CLE to start address cycle */
+ case NAND_CTL_SETCLE:
+ chip->IO_ADDR_W = info->regs + S3C2440_NFCMD;
+ break;
- if (column != -1 || page_addr != -1) {
+ case NAND_CTL_SETALE:
+ chip->IO_ADDR_W = info->regs + S3C2440_NFADDR;
+ break;
- /* Serially input address */
- if (column != -1) {
- /* Adjust columns for 16 bit buswidth */
- if (this->options & NAND_BUSWIDTH_16)
- column >>= 1;
- writeb(column, info->regs + S3C2410_NFADDR);
- }
- if (page_addr != -1) {
- writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR);
- writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR);
- /* One more address cycle for higher density devices */
- if (this->chipsize & 0x0c000000)
- writeb((unsigned char) ((page_addr >> 16) & 0x0f),
- info->regs + S3C2410_NFADDR);
- }
- /* Latch in address */
- }
-
- /*
- * program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
- switch (command) {
-
- case NAND_CMD_PAGEPROG:
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_SEQIN:
- case NAND_CMD_STATUS:
- return;
-
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
-
- udelay(this->chip_delay);
- writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD);
-
- while ( !(this->read_byte(mtd) & 0x40));
- return;
-
- /* This applies to read commands */
+ /* NAND_CTL_CLRCLE: */
+ /* NAND_CTL_CLRALE: */
default:
- /*
- * If we don't have access to the busy pin, we apply the given
- * command delay
- */
- if (!this->dev_ready) {
- udelay (this->chip_delay);
- return;
- }
+ chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
+ break;
}
-
- /* Apply this short delay always to ensure that we do wait tWB in
- * any case on any machine. */
- ndelay (100);
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
}
-
/* s3c2410_nand_devready()
*
* returns 0 if the nand is busy, 1 if it is ready
@@ -369,9 +322,12 @@ static int s3c2410_nand_devready(struct mtd_info *mtd)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+ if (info->is_s3c2440)
+ return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
}
+
/* ECC handling functions */
static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
@@ -394,6 +350,12 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
return -1;
}
+/* ECC functions
+ *
+ * These allow the s3c2410 and s3c2440 to use the controller's ECC
+ * generator block to ECC the data as it passes through]
+*/
+
static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -404,6 +366,15 @@ static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
writel(ctrl, info->regs + S3C2410_NFCONF);
}
+static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+ unsigned long ctrl;
+
+ ctrl = readl(info->regs + S3C2440_NFCONT);
+ writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
+}
+
static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code)
{
@@ -420,7 +391,26 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
}
-/* over-ride the standard functions for a little more speed? */
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
+ const u_char *dat, u_char *ecc_code)
+{
+ struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+ unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
+
+ ecc_code[0] = ecc;
+ ecc_code[1] = ecc >> 8;
+ ecc_code[2] = ecc >> 16;
+
+ pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
+ ecc_code[0], ecc_code[1], ecc_code[2]);
+
+ return 0;
+}
+
+
+/* over-ride the standard functions for a little more speed. We can
+ * use read/write block to move the data buffers to/from the controller
+*/
static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
@@ -523,11 +513,10 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
{
struct nand_chip *chip = &nmtd->chip;
- chip->IO_ADDR_R = (char *)info->regs + S3C2410_NFDATA;
- chip->IO_ADDR_W = (char *)info->regs + S3C2410_NFDATA;
+ chip->IO_ADDR_R = info->regs + S3C2410_NFDATA;
+ chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
chip->hwcontrol = s3c2410_nand_hwcontrol;
chip->dev_ready = s3c2410_nand_devready;
- chip->cmdfunc = s3c2410_nand_command;
chip->write_buf = s3c2410_nand_write_buf;
chip->read_buf = s3c2410_nand_read_buf;
chip->select_chip = s3c2410_nand_select_chip;
@@ -536,6 +525,12 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip->options = 0;
chip->controller = &info->controller;
+ if (info->is_s3c2440) {
+ chip->IO_ADDR_R = info->regs + S3C2440_NFDATA;
+ chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
+ chip->hwcontrol = s3c2440_nand_hwcontrol;
+ }
+
nmtd->info = info;
nmtd->mtd.priv = chip;
nmtd->set = set;
@@ -546,6 +541,11 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip->calculate_ecc = s3c2410_nand_calculate_ecc;
chip->eccmode = NAND_ECC_HW3_512;
chip->autooob = &nand_hw_eccoob;
+
+ if (info->is_s3c2440) {
+ chip->enable_hwecc = s3c2440_nand_enable_hwecc;
+ chip->calculate_ecc = s3c2440_nand_calculate_ecc;
+ }
} else {
chip->eccmode = NAND_ECC_SOFT;
}
@@ -559,7 +559,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
* nand layer to look for devices
*/
-static int s3c2410_nand_probe(struct device *dev)
+static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
{
struct platform_device *pdev = to_platform_device(dev);
struct s3c2410_platform_nand *plat = to_nand_plat(dev);
@@ -585,6 +585,7 @@ static int s3c2410_nand_probe(struct device *dev)
dev_set_drvdata(dev, info);
spin_lock_init(&info->controller.lock);
+ init_waitqueue_head(&info->controller.wq);
/* get the clock source and enable it */
@@ -600,7 +601,8 @@ static int s3c2410_nand_probe(struct device *dev)
/* allocate and map the resource */
- res = pdev->resource; /* assume that the flash has one resource */
+ /* currently we assume we have the one resource */
+ res = pdev->resource;
size = res->end - res->start + 1;
info->area = request_mem_region(res->start, size, pdev->name);
@@ -611,9 +613,10 @@ static int s3c2410_nand_probe(struct device *dev)
goto exit_error;
}
- info->device = dev;
- info->platform = plat;
- info->regs = ioremap(res->start, size);
+ info->device = dev;
+ info->platform = plat;
+ info->regs = ioremap(res->start, size);
+ info->is_s3c2440 = is_s3c2440;
if (info->regs == NULL) {
printk(KERN_ERR PFX "cannot reserve register region\n");
@@ -678,6 +681,18 @@ static int s3c2410_nand_probe(struct device *dev)
return err;
}
+/* driver device registration */
+
+static int s3c2410_nand_probe(struct device *dev)
+{
+ return s3c24xx_nand_probe(dev, 0);
+}
+
+static int s3c2440_nand_probe(struct device *dev)
+{
+ return s3c24xx_nand_probe(dev, 1);
+}
+
static struct device_driver s3c2410_nand_driver = {
.name = "s3c2410-nand",
.bus = &platform_bus_type,
@@ -685,14 +700,24 @@ static struct device_driver s3c2410_nand_driver = {
.remove = s3c2410_nand_remove,
};
+static struct device_driver s3c2440_nand_driver = {
+ .name = "s3c2440-nand",
+ .bus = &platform_bus_type,
+ .probe = s3c2440_nand_probe,
+ .remove = s3c2410_nand_remove,
+};
+
static int __init s3c2410_nand_init(void)
{
- printk("S3C2410 NAND Driver, (c) 2004 Simtec Electronics\n");
+ printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
+
+ driver_register(&s3c2440_nand_driver);
return driver_register(&s3c2410_nand_driver);
}
static void __exit s3c2410_nand_exit(void)
{
+ driver_unregister(&s3c2440_nand_driver);
driver_unregister(&s3c2410_nand_driver);
}
@@ -701,4 +726,4 @@ module_exit(s3c2410_nand_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("S3C2410 MTD NAND driver");
+MODULE_DESCRIPTION("S3C24XX MTD NAND driver");
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 29572793334..9853b87bb75 100755..100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Richard Purdie
*
- * $Id: sharpsl.c,v 1.3 2005/01/03 14:53:50 rpurdie Exp $
+ * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $
*
* Based on Sharp's NAND driver sharp_sl.c
*
@@ -216,7 +216,7 @@ sharpsl_nand_init(void)
nr_partitions = DEFAULT_NUM_PARTITIONS;
sharpsl_partition_info = sharpsl_nand_default_partition_info;
if (machine_is_poodle()) {
- sharpsl_partition_info[1].size=22 * 1024 * 1024;
+ sharpsl_partition_info[1].size=30 * 1024 * 1024;
} else if (machine_is_corgi() || machine_is_shepherd()) {
sharpsl_partition_info[1].size=25 * 1024 * 1024;
} else if (machine_is_husky()) {
diff --git a/drivers/mtd/nand/tx4925ndfmc.c b/drivers/mtd/nand/tx4925ndfmc.c
deleted file mode 100644
index bba688830c9..00000000000
--- a/drivers/mtd/nand/tx4925ndfmc.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * drivers/mtd/tx4925ndfmc.c
- *
- * Overview:
- * This is a device driver for the NAND flash device found on the
- * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports
- * 16MiB, 32MiB and 64MiB cards.
- *
- * Author: MontaVista Software, Inc. source@mvista.com
- *
- * Derived from drivers/mtd/autcpu12.c
- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * $Id: tx4925ndfmc.c,v 1.5 2004/10/05 13:50:20 gleixner Exp $
- *
- * Copyright (C) 2001 Toshiba Corporation
- *
- * 2003 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/tx4925/tx4925_nand.h>
-
-extern struct nand_oobinfo jffs2_oobinfo;
-
-/*
- * MTD structure for RBTX4925 board
- */
-static struct mtd_info *tx4925ndfmc_mtd = NULL;
-
-/*
- * Define partitions for flash devices
- */
-
-static struct mtd_partition partition_info16k[] = {
- { .name = "RBTX4925 flash partition 1",
- .offset = 0,
- .size = 8 * 0x00100000 },
- { .name = "RBTX4925 flash partition 2",
- .offset = 8 * 0x00100000,
- .size = 8 * 0x00100000 },
-};
-
-static struct mtd_partition partition_info32k[] = {
- { .name = "RBTX4925 flash partition 1",
- .offset = 0,
- .size = 8 * 0x00100000 },
- { .name = "RBTX4925 flash partition 2",
- .offset = 8 * 0x00100000,
- .size = 24 * 0x00100000 },
-};
-
-static struct mtd_partition partition_info64k[] = {
- { .name = "User FS",
- .offset = 0,
- .size = 16 * 0x00100000 },
- { .name = "RBTX4925 flash partition 2",
- .offset = 16 * 0x00100000,
- .size = 48 * 0x00100000},
-};
-
-static struct mtd_partition partition_info128k[] = {
- { .name = "Skip bad section",
- .offset = 0,
- .size = 16 * 0x00100000 },
- { .name = "User FS",
- .offset = 16 * 0x00100000,
- .size = 112 * 0x00100000 },
-};
-#define NUM_PARTITIONS16K 2
-#define NUM_PARTITIONS32K 2
-#define NUM_PARTITIONS64K 2
-#define NUM_PARTITIONS128K 2
-
-/*
- * hardware specific access to control-lines
-*/
-static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-
- switch(cmd){
-
- case NAND_CTL_SETCLE:
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
- break;
- case NAND_CTL_CLRCLE:
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
- break;
- case NAND_CTL_SETALE:
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
- break;
- case NAND_CTL_CLRALE:
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
- break;
- case NAND_CTL_SETNCE:
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
- break;
- case NAND_CTL_CLRNCE:
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
- break;
- case NAND_CTL_SETWP:
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
- break;
- case NAND_CTL_CLRWP:
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
- break;
- }
-}
-
-/*
-* read device ready pin
-*/
-static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
-{
- int ready;
- ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
- return ready;
-}
-void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-{
- /* reset first */
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
-}
-static void tx4925ndfmc_disable_ecc(void)
-{
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-}
-static void tx4925ndfmc_enable_read_ecc(void)
-{
- tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
- tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
-}
-void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
- int i;
- u_char *ecc = ecc_code;
- tx4925ndfmc_enable_read_ecc();
- for (i = 0;i < 6;i++,ecc++)
- *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
- tx4925ndfmc_disable_ecc();
-}
-void tx4925ndfmc_device_setup(void)
-{
-
- *(unsigned char *)0xbb005000 &= ~0x08;
-
- /* reset NDFMC */
- tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
- while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);
-
- /* setup BusSeparete, Hold Time, Strobe Pulse Width */
- tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
- tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;
-}
-static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
-{
- struct nand_chip *this = mtd->priv;
- return tx4925_read_nfmc(this->IO_ADDR_R);
-}
-
-static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-{
- struct nand_chip *this = mtd->priv;
- tx4925_write_nfmc(byte, this->IO_ADDR_W);
-}
-
-static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
-}
-
-static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
-}
-
-static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Send command to NAND device
- */
-static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
- register struct nand_chip *this = mtd->priv;
-
- /* Begin command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /*
- * Write out the command to the device.
- */
- if (command == NAND_CMD_SEQIN) {
- int readcmd;
-
- if (column >= mtd->oobblock) {
- /* OOB area */
- column -= mtd->oobblock;
- readcmd = NAND_CMD_READOOB;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- readcmd = NAND_CMD_READ0;
- } else {
- column -= 256;
- readcmd = NAND_CMD_READ1;
- }
- this->write_byte(mtd, readcmd);
- }
- this->write_byte(mtd, command);
-
- /* Set ALE and clear CLE to start address cycle */
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
- if (column != -1 || page_addr != -1) {
- this->hwcontrol(mtd, NAND_CTL_SETALE);
-
- /* Serially input address */
- if (column != -1)
- this->write_byte(mtd, column);
- if (page_addr != -1) {
- this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
- this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
- /* One more address cycle for higher density devices */
- if (mtd->size & 0x0c000000)
- this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
- }
- /* Latch in address */
- this->hwcontrol(mtd, NAND_CTL_CLRALE);
- }
-
- /*
- * program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
- switch (command) {
-
- case NAND_CMD_PAGEPROG:
- /* Turn off WE */
- this->hwcontrol (mtd, NAND_CTL_CLRWP);
- return;
-
- case NAND_CMD_SEQIN:
- /* Turn on WE */
- this->hwcontrol (mtd, NAND_CTL_SETWP);
- return;
-
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_STATUS:
- return;
-
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- this->write_byte(mtd, NAND_CMD_STATUS);
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- while ( !(this->read_byte(mtd) & 0x40));
- return;
-
- /* This applies to read commands */
- default:
- /*
- * If we don't have access to the busy pin, we apply the given
- * command delay
- */
- if (!this->dev_ready) {
- udelay (this->chip_delay);
- return;
- }
- }
-
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
-}
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
-n **pparts, char *);
-#endif
-
-/*
- * Main initialization routine
- */
-extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-int __init tx4925ndfmc_init (void)
-{
- struct nand_chip *this;
- int err = 0;
-
- /* Allocate memory for MTD device structure and private data */
- tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
- GFP_KERNEL);
- if (!tx4925ndfmc_mtd) {
- printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
- err = -ENOMEM;
- goto out;
- }
-
- tx4925ndfmc_device_setup();
-
- /* io is indirect via a register so don't need to ioremap address */
-
- /* Get pointer to private data */
- this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
-
- /* Initialize structures */
- memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
- memset((char *) this, 0, sizeof(struct nand_chip));
-
- /* Link the private data with the MTD structure */
- tx4925ndfmc_mtd->priv = this;
-
- /* Set address of NAND IO lines */
- this->IO_ADDR_R = (void __iomem *)&(tx4925_ndfmcptr->dtr);
- this->IO_ADDR_W = (void __iomem *)&(tx4925_ndfmcptr->dtr);
- this->hwcontrol = tx4925ndfmc_hwcontrol;
- this->enable_hwecc = tx4925ndfmc_enable_hwecc;
- this->calculate_ecc = tx4925ndfmc_readecc;
- this->correct_data = nand_correct_data;
- this->eccmode = NAND_ECC_HW6_512;
- this->dev_ready = tx4925ndfmc_device_ready;
- /* 20 us command delay time */
- this->chip_delay = 20;
- this->read_byte = tx4925ndfmc_nand_read_byte;
- this->write_byte = tx4925ndfmc_nand_write_byte;
- this->cmdfunc = tx4925ndfmc_nand_command;
- this->write_buf = tx4925ndfmc_nand_write_buf;
- this->read_buf = tx4925ndfmc_nand_read_buf;
- this->verify_buf = tx4925ndfmc_nand_verify_buf;
-
- /* Scan to find existance of the device */
- if (nand_scan (tx4925ndfmc_mtd, 1)) {
- err = -ENXIO;
- goto out_ior;
- }
-
- /* Register the partitions */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- {
- int mtd_parts_nb = 0;
- struct mtd_partition *mtd_parts = 0;
- mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
- if (mtd_parts_nb > 0)
- add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
- else
- add_mtd_device(tx4925ndfmc_mtd);
- }
-#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
- switch(tx4925ndfmc_mtd->size){
- case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
- case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
- case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break;
- case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break;
- default: {
- printk ("Unsupported SmartMedia device\n");
- err = -ENXIO;
- goto out_ior;
- }
- }
-#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
- goto out;
-
-out_ior:
-out:
- return err;
-}
-
-module_init(tx4925ndfmc_init);
-
-/*
- * Clean up routine
- */
-#ifdef MODULE
-static void __exit tx4925ndfmc_cleanup (void)
-{
- /* Release resources, unregister device */
- nand_release (tx4925ndfmc_mtd);
-
- /* Free the MTD device structure */
- kfree (tx4925ndfmc_mtd);
-}
-module_exit(tx4925ndfmc_cleanup);
-#endif
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
diff --git a/drivers/mtd/nand/tx4938ndfmc.c b/drivers/mtd/nand/tx4938ndfmc.c
deleted file mode 100644
index df26e58820b..00000000000
--- a/drivers/mtd/nand/tx4938ndfmc.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * drivers/mtd/nand/tx4938ndfmc.c
- *
- * Overview:
- * This is a device driver for the NAND flash device connected to
- * TX4938 internal NAND Memory Controller.
- * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
- *
- * Author: source@mvista.com
- *
- * Based on spia.c by Steven J. Hill
- *
- * $Id: tx4938ndfmc.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $
- *
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
- * 2003 (c) MontaVista Software, Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/bootinfo.h>
-#include <linux/delay.h>
-#include <asm/tx4938/rbtx4938.h>
-
-extern struct nand_oobinfo jffs2_oobinfo;
-
-/*
- * MTD structure for TX4938 NDFMC
- */
-static struct mtd_info *tx4938ndfmc_mtd;
-
-/*
- * Define partitions for flash device
- */
-#define flush_wb() (void)tx4938_ndfmcptr->mcr;
-
-#define NUM_PARTITIONS 3
-#define NUMBER_OF_CIS_BLOCKS 24
-#define SIZE_OF_BLOCK 0x00004000
-#define NUMBER_OF_BLOCK_PER_ZONE 1024
-#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
-#ifndef CONFIG_MTD_CMDLINE_PARTS
-/*
- * You can use the following sample of MTD partitions
- * on the NAND Flash Memory 32MB or more.
- *
- * The following figure shows the image of the sample partition on
- * the 32MB NAND Flash Memory.
- *
- * Block No.
- * 0 +-----------------------------+ ------
- * | CIS | ^
- * 24 +-----------------------------+ |
- * | kernel image | | Zone 0
- * | | |
- * +-----------------------------+ |
- * 1023 | unused area | v
- * +-----------------------------+ ------
- * 1024 | JFFS2 | ^
- * | | |
- * | | | Zone 1
- * | | |
- * | | |
- * | | v
- * 2047 +-----------------------------+ ------
- *
- */
-static struct mtd_partition partition_info[NUM_PARTITIONS] = {
- {
- .name = "RBTX4938 CIS Area",
- .offset = 0,
- .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
- .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
- },
- {
- .name = "RBTX4938 kernel image",
- .offset = MTDPART_OFS_APPEND,
- .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */
- .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
- },
- {
- .name = "Root FS (JFFS2)",
- .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */
- .size = MTDPART_SIZ_FULL
- },
-};
-#endif
-
-static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-{
- switch (cmd) {
- case NAND_CTL_SETCLE:
- tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
- break;
- case NAND_CTL_CLRCLE:
- tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
- break;
- case NAND_CTL_SETALE:
- tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
- break;
- case NAND_CTL_CLRALE:
- tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
- break;
- /* TX4938_NDFMCR_CE bit is 0:high 1:low */
- case NAND_CTL_SETNCE:
- tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
- break;
- case NAND_CTL_CLRNCE:
- tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
- break;
- case NAND_CTL_SETWP:
- tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
- break;
- case NAND_CTL_CLRWP:
- tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
- break;
- }
-}
-static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
-{
- flush_wb();
- return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
-}
-static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-{
- u32 mcr = tx4938_ndfmcptr->mcr;
- mcr &= ~TX4938_NDFMCR_ECC_ALL;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
- ecc_code[1] = tx4938_ndfmcptr->dtr;
- ecc_code[0] = tx4938_ndfmcptr->dtr;
- ecc_code[2] = tx4938_ndfmcptr->dtr;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-}
-static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-{
- u32 mcr = tx4938_ndfmcptr->mcr;
- mcr &= ~TX4938_NDFMCR_ECC_ALL;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
- tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
-}
-
-static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
-{
- struct nand_chip *this = mtd->priv;
- return tx4938_read_nfmc(this->IO_ADDR_R);
-}
-
-static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-{
- struct nand_chip *this = mtd->priv;
- tx4938_write_nfmc(byte, this->IO_ADDR_W);
-}
-
-static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
-}
-
-static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
-}
-
-static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Send command to NAND device
- */
-static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
- register struct nand_chip *this = mtd->priv;
-
- /* Begin command latch cycle */
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /*
- * Write out the command to the device.
- */
- if (command == NAND_CMD_SEQIN) {
- int readcmd;
-
- if (column >= mtd->oobblock) {
- /* OOB area */
- column -= mtd->oobblock;
- readcmd = NAND_CMD_READOOB;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- readcmd = NAND_CMD_READ0;
- } else {
- column -= 256;
- readcmd = NAND_CMD_READ1;
- }
- this->write_byte(mtd, readcmd);
- }
- this->write_byte(mtd, command);
-
- /* Set ALE and clear CLE to start address cycle */
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
- if (column != -1 || page_addr != -1) {
- this->hwcontrol(mtd, NAND_CTL_SETALE);
-
- /* Serially input address */
- if (column != -1)
- this->write_byte(mtd, column);
- if (page_addr != -1) {
- this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
- this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
- /* One more address cycle for higher density devices */
- if (mtd->size & 0x0c000000)
- this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
- }
- /* Latch in address */
- this->hwcontrol(mtd, NAND_CTL_CLRALE);
- }
-
- /*
- * program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
- switch (command) {
-
- case NAND_CMD_PAGEPROG:
- /* Turn off WE */
- this->hwcontrol (mtd, NAND_CTL_CLRWP);
- return;
-
- case NAND_CMD_SEQIN:
- /* Turn on WE */
- this->hwcontrol (mtd, NAND_CTL_SETWP);
- return;
-
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_STATUS:
- return;
-
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
- this->hwcontrol(mtd, NAND_CTL_SETCLE);
- this->write_byte(mtd, NAND_CMD_STATUS);
- this->hwcontrol(mtd, NAND_CTL_CLRCLE);
- while ( !(this->read_byte(mtd) & 0x40));
- return;
-
- /* This applies to read commands */
- default:
- /*
- * If we don't have access to the busy pin, we apply the given
- * command delay
- */
- if (!this->dev_ready) {
- udelay (this->chip_delay);
- return;
- }
- }
-
- /* wait until command is processed */
- while (!this->dev_ready(mtd));
-}
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
-#endif
-/*
- * Main initialization routine
- */
-int __init tx4938ndfmc_init (void)
-{
- struct nand_chip *this;
- int bsprt = 0, hold = 0xf, spw = 0xf;
- int protected = 0;
-
- if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
- printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
- return -ENODEV;
- }
- bsprt = 1;
- hold = 2;
- spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
-
- if ((tx4938_ccfgptr->pcfg &
- (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
- != TX4938_PCFG_NDF_SEL) {
- printk("TX4938 NDFMC: disabled by PCFG.\n");
- return -ENODEV;
- }
-
- /* reset NDFMC */
- tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
- while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
- ;
- /* setup BusSeparete, Hold Time, Strobe Pulse Width */
- tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
- tx4938_ndfmcptr->spr = hold << 4 | spw;
-
- /* Allocate memory for MTD device structure and private data */
- tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
- GFP_KERNEL);
- if (!tx4938ndfmc_mtd) {
- printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
- return -ENOMEM;
- }
-
- /* Get pointer to private data */
- this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
-
- /* Initialize structures */
- memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
- memset((char *) this, 0, sizeof(struct nand_chip));
-
- /* Link the private data with the MTD structure */
- tx4938ndfmc_mtd->priv = this;
-
- /* Set address of NAND IO lines */
- this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
- this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
- this->hwcontrol = tx4938ndfmc_hwcontrol;
- this->dev_ready = tx4938ndfmc_dev_ready;
- this->calculate_ecc = tx4938ndfmc_calculate_ecc;
- this->correct_data = nand_correct_data;
- this->enable_hwecc = tx4938ndfmc_enable_hwecc;
- this->eccmode = NAND_ECC_HW3_256;
- this->chip_delay = 100;
- this->read_byte = tx4938ndfmc_nand_read_byte;
- this->write_byte = tx4938ndfmc_nand_write_byte;
- this->cmdfunc = tx4938ndfmc_nand_command;
- this->write_buf = tx4938ndfmc_nand_write_buf;
- this->read_buf = tx4938ndfmc_nand_read_buf;
- this->verify_buf = tx4938ndfmc_nand_verify_buf;
-
- /* Scan to find existance of the device */
- if (nand_scan (tx4938ndfmc_mtd, 1)) {
- kfree (tx4938ndfmc_mtd);
- return -ENXIO;
- }
-
- if (protected) {
- printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
- tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
- }
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- {
- int mtd_parts_nb = 0;
- struct mtd_partition *mtd_parts = 0;
- mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
- if (mtd_parts_nb > 0)
- add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
- else
- add_mtd_device(tx4938ndfmc_mtd);
- }
-#else
- add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
-#endif
-
- return 0;
-}
-module_init(tx4938ndfmc_init);
-
-/*
- * Clean up routine
- */
-static void __exit tx4938ndfmc_cleanup (void)
-{
- /* Release resources, unregister device */
- nand_release (tx4938ndfmc_mtd);
-
- /* Free the MTD device structure */
- kfree (tx4938ndfmc_mtd);
-}
-module_exit(tx4938ndfmc_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2b55687f6ee..9a07ff7a777 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -3,6 +3,8 @@
# Network device configuration
#
+menu "Network device support"
+
config NETDEVICES
depends on NET
bool "Network device support"
@@ -2547,3 +2549,4 @@ config NETCONSOLE
If you want to log kernel messages over the network, enable this.
See <file:Documentation/networking/netconsole.txt> for details.
+endmenu
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 69c488d933a..b14e89004c3 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -1,6 +1,33 @@
#
# Appletalk driver configuration
#
+config ATALK
+ tristate "Appletalk protocol support"
+ select LLC
+ ---help---
+ AppleTalk is the protocol that Apple computers can use to communicate
+ on a network. If your Linux box is connected to such a network and you
+ wish to connect to it, say Y. You will need to use the netatalk package
+ so that your Linux box can act as a print and file server for Macs as
+ well as access AppleTalk printers. Check out
+ <http://www.zettabyte.net/netatalk/> on the WWW for details.
+ EtherTalk is the name used for AppleTalk over Ethernet and the
+ cheaper and slower LocalTalk is AppleTalk over a proprietary Apple
+ network using serial links. EtherTalk and LocalTalk are fully
+ supported by Linux.
+
+ General information about how to connect Linux, Windows machines and
+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. The
+ NET-3-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>, contains valuable
+ information as well.
+
+ To compile this driver as a module, choose M here: the module will be
+ called appletalk. You almost certainly want to compile it as a
+ module so you can restart your AppleTalk stack without rebooting
+ your machine. I hear that the GNU boycott of Apple is over, so
+ even politically correct people are allowed to say Y here.
+
config DEV_APPLETALK
bool "Appletalk interfaces support"
depends on ATALK
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index f1bd45e3da3..94939f570f7 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1930,6 +1930,7 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
b44_free_rings(bp);
spin_unlock_irq(&bp->lock);
+ pci_disable_device(pdev);
return 0;
}
@@ -1939,6 +1940,8 @@ static int b44_resume(struct pci_dev *pdev)
struct b44 *bp = netdev_priv(dev);
pci_restore_state(pdev);
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
if (!netif_running(dev))
return 0;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 00e5257b176..8dc657fc8af 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1261,7 +1261,7 @@ static void bmac_reset_and_enable(struct net_device *dev)
spin_unlock_irqrestore(&bp->lock, flags);
}
-static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
int j, rev, ret;
struct bmac_data *bp;
@@ -1645,16 +1645,13 @@ static int __devexit bmac_remove(struct macio_dev *mdev)
return 0;
}
-static struct of_match bmac_match[] =
+static struct of_device_id bmac_match[] =
{
{
.name = "bmac",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH,
.data = (void *)0,
},
{
- .name = OF_ANY_MATCH,
.type = "network",
.compatible = "bmac+",
.data = (void *)1,
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index ece1b1a1318..c27e417f32b 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -304,7 +304,7 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
scc->tx_buff = NULL;
}
- while (skb_queue_len(&scc->tx_queue))
+ while (!skb_queue_empty(&scc->tx_queue))
dev_kfree_skb(skb_dequeue(&scc->tx_queue));
spin_unlock_irqrestore(&scc->lock, flags);
@@ -1126,8 +1126,7 @@ static void t_dwait(unsigned long channel)
if (scc->stat.tx_state == TXS_WAIT) /* maxkeyup or idle timeout */
{
- if (skb_queue_len(&scc->tx_queue) == 0) /* nothing to send */
- {
+ if (skb_queue_empty(&scc->tx_queue)) { /* nothing to send */
scc->stat.tx_state = TXS_IDLE;
netif_wake_queue(scc->dev); /* t_maxkeyup locked it. */
return;
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 6ed2d7dbd44..81d0a26e4f4 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -109,7 +109,7 @@ bitrev(int b)
}
-static int __devinit mace_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mace = macio_get_of_node(mdev);
struct net_device *dev;
@@ -1009,12 +1009,10 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-static struct of_match mace_match[] =
+static struct of_device_id mace_match[] =
{
{
.name = "mace",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{},
};
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index aad5494c83c..f0996ce5c26 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -369,7 +369,7 @@ static void myri_tx(struct myri_eth *mp, struct net_device *dev)
* assume 802.3 if the type field is short enough to be a length.
* This is normal practice and works for any 'now in use' protocol.
*/
-static unsigned short myri_type_trans(struct sk_buff *skb, struct net_device *dev)
+static __be16 myri_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct ethhdr *eth;
unsigned char *rawp;
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index a1a6c08e7dc..f1c01ac2910 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -660,6 +660,7 @@ static int ne2k_pci_suspend (struct pci_dev *pdev, pm_message_t state)
netif_device_detach(dev);
pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
@@ -671,6 +672,8 @@ static int ne2k_pci_resume (struct pci_dev *pdev)
pci_set_power_state(pdev, 0);
pci_restore_state(pdev);
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
NS8390_init(dev, 1);
netif_device_attach(dev);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index f0fc04bd37c..71fd41122c9 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -86,7 +86,6 @@ earlier 3Com products.
#include <linux/ethtool.h>
#include <linux/bitops.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -312,11 +311,6 @@ static dev_link_t *tc574_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &tc574_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1299,6 +1293,7 @@ static struct pcmcia_driver tc574_driver = {
.name = "3c574_cs",
},
.attach = tc574_attach,
+ .event = tc574_event,
.detach = tc574_detach,
.id_table = tc574_ids,
};
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 8fa1b5f0fb6..d83fdd8c194 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -40,7 +40,6 @@
#include <linux/ioport.h>
#include <linux/bitops.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *tc589_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &tc589_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1074,6 +1068,7 @@ static struct pcmcia_driver tc589_driver = {
.name = "3c589_cs",
},
.attach = tc589_attach,
+ .event = tc589_event,
.detach = tc589_detach,
.id_table = tc589_ids,
};
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 23ce77b1d5b..8bb4e85689e 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -37,7 +37,6 @@
#include <linux/netdevice.h>
#include "../8390.h"
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -181,11 +180,6 @@ static dev_link_t *axnet_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &axnet_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -884,6 +878,7 @@ static struct pcmcia_driver axnet_cs_driver = {
.name = "axnet_cs",
},
.attach = axnet_attach,
+ .event = axnet_event,
.detach = axnet_detach,
.id_table = axnet_ids,
};
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 68d58cc58d3..b9355d9498a 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -43,7 +43,6 @@
#include <linux/arcdevice.h>
#include <linux/com20020.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -200,11 +199,6 @@ static dev_link_t *com20020_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &com20020_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -495,6 +489,7 @@ static struct pcmcia_driver com20020_cs_driver = {
.name = "com20020_cs",
},
.attach = com20020_attach,
+ .event = com20020_event,
.detach = com20020_detach,
.id_table = com20020_ids,
};
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 917adbbf0b5..9d8197bb293 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -49,7 +49,6 @@
#include <linux/ioport.h>
#include <linux/crc32.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -288,11 +287,6 @@ static dev_link_t *fmvj18x_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &fmvj18x_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -797,6 +791,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
.name = "fmvj18x_cs",
},
.attach = fmvj18x_attach,
+ .event = fmvj18x_event,
.detach = fmvj18x_detach,
.id_table = fmvj18x_ids,
};
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index cf6d073ea55..b6c140eb979 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -57,7 +57,6 @@
#include <linux/trdevice.h>
#include <linux/ibmtr.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -190,11 +189,6 @@ static dev_link_t *ibmtr_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &ibmtr_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -521,6 +515,7 @@ static struct pcmcia_driver ibmtr_cs_driver = {
.name = "ibmtr_cs",
},
.attach = ibmtr_attach,
+ .event = ibmtr_event,
.detach = ibmtr_detach,
.id_table = ibmtr_ids,
};
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index b86e7253fbf..dbb941004ae 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -146,7 +146,6 @@ Include Files
#include <linux/ioport.h>
#include <linux/bitops.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h>
@@ -502,11 +501,6 @@ static dev_link_t *nmclan_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &nmclan_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1688,6 +1682,7 @@ static struct pcmcia_driver nmclan_cs_driver = {
.name = "nmclan_cs",
},
.attach = nmclan_attach,
+ .event = nmclan_event,
.detach = nmclan_detach,
.id_table = nmclan_ids,
};
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 855a45d062b..e1664aef3df 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -40,7 +40,6 @@
#include <linux/netdevice.h>
#include <../drivers/net/8390.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -276,11 +275,6 @@ static dev_link_t *pcnet_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &pcnet_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1844,6 +1838,7 @@ static struct pcmcia_driver pcnet_driver = {
.name = "pcnet_cs",
},
.attach = pcnet_attach,
+ .event = pcnet_event,
.detach = pcnet_detach,
.owner = THIS_MODULE,
.id_table = pcnet_ids,
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index bc01c88c670..fbc2f58ff68 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -42,7 +42,6 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -370,10 +369,6 @@ static dev_link_t *smc91c92_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &smc91c92_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2365,6 +2360,7 @@ static struct pcmcia_driver smc91c92_cs_driver = {
.name = "smc91c92_cs",
},
.attach = smc91c92_attach,
+ .event = smc91c92_event,
.detach = smc91c92_detach,
.id_table = smc91c92_ids,
};
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 0cd225e1595..9f33bad174e 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -81,7 +81,6 @@
#include <linux/ioport.h>
#include <linux/bitops.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -619,11 +618,6 @@ xirc2ps_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &xirc2ps_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
@@ -2016,6 +2010,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
.name = "xirc2ps_cs",
},
.attach = xirc2ps_attach,
+ .event = xirc2ps_event,
.detach = xirc2ps_detach,
.id_table = xirc2ps_ids,
};
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index f4b62405d2e..21537ee3a6a 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -540,7 +540,7 @@ plip_receive(unsigned short nibble_timeout, struct net_device *dev,
* in far too many old systems not all even running Linux.
*/
-static unsigned short plip_type_trans(struct sk_buff *skb, struct net_device *dev)
+static __be16 plip_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct ethhdr *eth;
unsigned char *rawp;
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 5e48b9ab304..59e8183c639 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -364,7 +364,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_async_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
- if (skb_queue_len(&ap->rqueue))
+ if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
ap_put(ap);
if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index ab726ab4379..a32668e88e0 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1237,8 +1237,8 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
pch = list_entry(list, struct channel, clist);
navail += pch->avail = (pch->chan != NULL);
if (pch->avail) {
- if (skb_queue_len(&pch->file.xq) == 0
- || !pch->had_frag) {
+ if (skb_queue_empty(&pch->file.xq) ||
+ !pch->had_frag) {
pch->avail = 2;
++nfree;
}
@@ -1374,8 +1374,8 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
/* try to send it down the channel */
chan = pch->chan;
- if (skb_queue_len(&pch->file.xq)
- || !chan->ops->start_xmit(chan, frag))
+ if (!skb_queue_empty(&pch->file.xq) ||
+ !chan->ops->start_xmit(chan, frag))
skb_queue_tail(&pch->file.xq, frag);
pch->had_frag = 1;
p += flen;
@@ -1412,7 +1412,7 @@ ppp_channel_push(struct channel *pch)
spin_lock_bh(&pch->downl);
if (pch->chan != 0) {
- while (skb_queue_len(&pch->file.xq) > 0) {
+ while (!skb_queue_empty(&pch->file.xq)) {
skb = skb_dequeue(&pch->file.xq);
if (!pch->chan->ops->start_xmit(pch->chan, skb)) {
/* put the packet back and try again later */
@@ -1426,7 +1426,7 @@ ppp_channel_push(struct channel *pch)
}
spin_unlock_bh(&pch->downl);
/* see if there is anything from the attached unit to be sent */
- if (skb_queue_len(&pch->file.xq) == 0) {
+ if (skb_queue_empty(&pch->file.xq)) {
read_lock_bh(&pch->upl);
ppp = pch->ppp;
if (ppp != 0)
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index fd9f5018035..4d51c0c8023 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -406,7 +406,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_sync_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
- if (skb_queue_len(&ap->rqueue))
+ if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
sp_put(ap);
if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index 20edeb34579..3ad0b6751f6 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct shaper *shaper = dev->priv;
struct sk_buff *ptr;
-
- if (down_trylock(&shaper->sem))
- return -1;
-
+
+ spin_lock(&shaper->lock);
ptr=shaper->sendq.prev;
/*
@@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
shaper->stats.collisions++;
}
shaper_kick(shaper);
- up(&shaper->sem);
+ spin_unlock(&shaper->lock);
return 0;
}
@@ -271,11 +269,9 @@ static void shaper_timer(unsigned long data)
{
struct shaper *shaper = (struct shaper *)data;
- if (!down_trylock(&shaper->sem)) {
- shaper_kick(shaper);
- up(&shaper->sem);
- } else
- mod_timer(&shaper->timer, jiffies);
+ spin_lock(&shaper->lock);
+ shaper_kick(shaper);
+ spin_unlock(&shaper->lock);
}
/*
@@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *shaper)
/*
- * Flush the shaper queues on a closedown
- */
-
-static void shaper_flush(struct shaper *shaper)
-{
- struct sk_buff *skb;
-
- down(&shaper->sem);
- while((skb=skb_dequeue(&shaper->sendq))!=NULL)
- dev_kfree_skb(skb);
- shaper_kick(shaper);
- up(&shaper->sem);
-}
-
-/*
* Bring the interface up. We just disallow this until a
* bind.
*/
@@ -375,7 +356,15 @@ static int shaper_open(struct net_device *dev)
static int shaper_close(struct net_device *dev)
{
struct shaper *shaper=dev->priv;
- shaper_flush(shaper);
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
+ dev_kfree_skb(skb);
+
+ spin_lock_bh(&shaper->lock);
+ shaper_kick(shaper);
+ spin_unlock_bh(&shaper->lock);
+
del_timer_sync(&shaper->timer);
return 0;
}
@@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_device *dev)
init_timer(&sh->timer);
sh->timer.function=shaper_timer;
sh->timer.data=(unsigned long)sh;
+ spin_lock_init(&sh->lock);
}
/*
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 3dbb1cb09ed..5cacc7ad9e7 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3259,7 +3259,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int skge_suspend(struct pci_dev *pdev, u32 state)
+static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
@@ -3279,7 +3279,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
}
pci_save_state(pdev);
- pci_enable_wake(pdev, state, wol);
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 14d0cc01fb9..fced3d2bc07 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -7,6 +7,7 @@
/* PCI config registers */
#define PCI_DEV_REG1 0x40
#define PCI_DEV_REG2 0x44
+#define PCI_REV_DESC 0x4
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 1f5655655c4..2608e7a3d21 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -3079,7 +3079,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->phy_mii.dev = dev;
gp->phy_mii.mdio_read = _phy_read;
gp->phy_mii.mdio_write = _phy_write;
-
+#ifdef CONFIG_PPC_PMAC
+ gp->phy_mii.platform_data = gp->of_node;
+#endif
/* By default, we start with autoneg */
gp->want_autoneg = 1;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 0fca414d365..d3ddb41d6e5 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -32,6 +32,10 @@
#include <linux/ethtool.h>
#include <linux/delay.h>
+#ifdef CONFIG_PPC_PMAC
+#include <asm/prom.h>
+#endif
+
#include "sungem_phy.h"
/* Link modes of the BCM5400 PHY */
@@ -281,10 +285,12 @@ static int bcm5411_suspend(struct mii_phy* phy)
static int bcm5421_init(struct mii_phy* phy)
{
u16 data;
- int rev;
+ unsigned int id;
- rev = phy_read(phy, MII_PHYSID2) & 0x000f;
- if (rev == 0) {
+ id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
+
+ /* Revision 0 of 5421 needs some fixups */
+ if (id == 0x002060e0) {
/* This is borrowed from MacOS
*/
phy_write(phy, 0x18, 0x1007);
@@ -297,21 +303,28 @@ static int bcm5421_init(struct mii_phy* phy)
data = phy_read(phy, 0x15);
phy_write(phy, 0x15, data | 0x0200);
}
-#if 0
- /* This has to be verified before I enable it */
- /* Enable automatic low-power */
- phy_write(phy, 0x1c, 0x9002);
- phy_write(phy, 0x1c, 0xa821);
- phy_write(phy, 0x1c, 0x941d);
-#endif
- return 0;
-}
-static int bcm5421k2_init(struct mii_phy* phy)
-{
- /* Init code borrowed from OF */
- phy_write(phy, 4, 0x01e1);
- phy_write(phy, 9, 0x0300);
+ /* Pick up some init code from OF for K2 version */
+ if ((id & 0xfffffff0) == 0x002062e0) {
+ phy_write(phy, 4, 0x01e1);
+ phy_write(phy, 9, 0x0300);
+ }
+
+ /* Check if we can enable automatic low power */
+#ifdef CONFIG_PPC_PMAC
+ if (phy->platform_data) {
+ struct device_node *np = of_get_parent(phy->platform_data);
+ int can_low_power = 1;
+ if (np == NULL || get_property(np, "no-autolowpower", NULL))
+ can_low_power = 0;
+ if (can_low_power) {
+ /* Enable automatic low-power */
+ phy_write(phy, 0x1c, 0x9002);
+ phy_write(phy, 0x1c, 0xa821);
+ phy_write(phy, 0x1c, 0x941d);
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
return 0;
}
@@ -762,7 +775,7 @@ static struct mii_phy_def bcm5421_phy_def = {
/* Broadcom BCM 5421 built-in K2 */
static struct mii_phy_ops bcm5421k2_phy_ops = {
- .init = bcm5421k2_init,
+ .init = bcm5421_init,
.suspend = bcm5411_suspend,
.setup_aneg = bcm54xx_setup_aneg,
.setup_forced = bcm54xx_setup_forced,
@@ -779,6 +792,25 @@ static struct mii_phy_def bcm5421k2_phy_def = {
.ops = &bcm5421k2_phy_ops
};
+/* Broadcom BCM 5462 built-in Vesta */
+static struct mii_phy_ops bcm5462V_phy_ops = {
+ .init = bcm5421_init,
+ .suspend = bcm5411_suspend,
+ .setup_aneg = bcm54xx_setup_aneg,
+ .setup_forced = bcm54xx_setup_forced,
+ .poll_link = genmii_poll_link,
+ .read_link = bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5462V_phy_def = {
+ .phy_id = 0x002060d0,
+ .phy_id_mask = 0xfffffff0,
+ .name = "BCM5462-Vesta",
+ .features = MII_GBIT_FEATURES,
+ .magic_aneg = 1,
+ .ops = &bcm5462V_phy_ops
+};
+
/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
* I masked out the 8 last bits to get both, but some specs
* would be useful here) --BenH.
@@ -824,6 +856,7 @@ static struct mii_phy_def* mii_phy_table[] = {
&bcm5411_phy_def,
&bcm5421_phy_def,
&bcm5421k2_phy_def,
+ &bcm5462V_phy_def,
&marvell_phy_def,
&genmii_phy_def,
NULL
diff --git a/drivers/net/sungem_phy.h b/drivers/net/sungem_phy.h
index 822cb58174e..430544496c5 100644
--- a/drivers/net/sungem_phy.h
+++ b/drivers/net/sungem_phy.h
@@ -43,9 +43,10 @@ struct mii_phy
int pause;
/* Provided by host chip */
- struct net_device* dev;
+ struct net_device *dev;
int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
+ void *platform_data;
};
/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7e371b1209a..54640686e98 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -66,8 +66,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.32"
-#define DRV_MODULE_RELDATE "June 24, 2005"
+#define DRV_MODULE_VERSION "3.33"
+#define DRV_MODULE_RELDATE "July 5, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -5117,7 +5117,7 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
}
static void __tg3_set_rx_mode(struct net_device *);
-static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
{
tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
@@ -5460,7 +5460,7 @@ static int tg3_reset_hw(struct tg3 *tp)
udelay(10);
}
- tg3_set_coalesce(tp, &tp->coal);
+ __tg3_set_coalesce(tp, &tp->coal);
/* set status block DMA address */
tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
@@ -7821,6 +7821,60 @@ static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
return 0;
}
+static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+ struct tg3 *tp = netdev_priv(dev);
+ u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
+ u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+ max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT;
+ max_txcoal_tick_int = MAX_TXCOAL_TICK_INT;
+ max_stat_coal_ticks = MAX_STAT_COAL_TICKS;
+ min_stat_coal_ticks = MIN_STAT_COAL_TICKS;
+ }
+
+ if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) ||
+ (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) ||
+ (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) ||
+ (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) ||
+ (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) ||
+ (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) ||
+ (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) ||
+ (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) ||
+ (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) ||
+ (ec->stats_block_coalesce_usecs < min_stat_coal_ticks))
+ return -EINVAL;
+
+ /* No rx interrupts will be generated if both are zero */
+ if ((ec->rx_coalesce_usecs == 0) &&
+ (ec->rx_max_coalesced_frames == 0))
+ return -EINVAL;
+
+ /* No tx interrupts will be generated if both are zero */
+ if ((ec->tx_coalesce_usecs == 0) &&
+ (ec->tx_max_coalesced_frames == 0))
+ return -EINVAL;
+
+ /* Only copy relevant parameters, ignore all others. */
+ tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs;
+ tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs;
+ tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames;
+ tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames;
+ tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq;
+ tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq;
+ tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq;
+ tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq;
+ tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs;
+
+ if (netif_running(dev)) {
+ tg3_full_lock(tp, 0);
+ __tg3_set_coalesce(tp, &tp->coal);
+ tg3_full_unlock(tp);
+ }
+ return 0;
+}
+
static struct ethtool_ops tg3_ethtool_ops = {
.get_settings = tg3_get_settings,
.set_settings = tg3_set_settings,
@@ -7856,6 +7910,7 @@ static struct ethtool_ops tg3_ethtool_ops = {
.get_stats_count = tg3_get_stats_count,
.get_ethtool_stats = tg3_get_ethtool_stats,
.get_coalesce = tg3_get_coalesce,
+ .set_coalesce = tg3_set_coalesce,
};
static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -9800,6 +9855,12 @@ static void __devinit tg3_init_coal(struct tg3 *tp)
ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS;
ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
}
+
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ ec->rx_coalesce_usecs_irq = 0;
+ ec->tx_coalesce_usecs_irq = 0;
+ ec->stats_block_coalesce_usecs = 0;
+ }
}
static int __devinit tg3_init_one(struct pci_dev *pdev,
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 99c5f9675a5..70ad450733e 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -879,31 +879,41 @@
#define LOW_RXCOL_TICKS_CLRTCKS 0x00000014
#define DEFAULT_RXCOL_TICKS 0x00000048
#define HIGH_RXCOL_TICKS 0x00000096
+#define MAX_RXCOL_TICKS 0x000003ff
#define HOSTCC_TXCOL_TICKS 0x00003c0c
#define LOW_TXCOL_TICKS 0x00000096
#define LOW_TXCOL_TICKS_CLRTCKS 0x00000048
#define DEFAULT_TXCOL_TICKS 0x0000012c
#define HIGH_TXCOL_TICKS 0x00000145
+#define MAX_TXCOL_TICKS 0x000003ff
#define HOSTCC_RXMAX_FRAMES 0x00003c10
#define LOW_RXMAX_FRAMES 0x00000005
#define DEFAULT_RXMAX_FRAMES 0x00000008
#define HIGH_RXMAX_FRAMES 0x00000012
+#define MAX_RXMAX_FRAMES 0x000000ff
#define HOSTCC_TXMAX_FRAMES 0x00003c14
#define LOW_TXMAX_FRAMES 0x00000035
#define DEFAULT_TXMAX_FRAMES 0x0000004b
#define HIGH_TXMAX_FRAMES 0x00000052
+#define MAX_TXMAX_FRAMES 0x000000ff
#define HOSTCC_RXCOAL_TICK_INT 0x00003c18
#define DEFAULT_RXCOAL_TICK_INT 0x00000019
#define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define MAX_RXCOAL_TICK_INT 0x000003ff
#define HOSTCC_TXCOAL_TICK_INT 0x00003c1c
#define DEFAULT_TXCOAL_TICK_INT 0x00000019
#define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define MAX_TXCOAL_TICK_INT 0x000003ff
#define HOSTCC_RXCOAL_MAXF_INT 0x00003c20
#define DEFAULT_RXCOAL_MAXF_INT 0x00000005
+#define MAX_RXCOAL_MAXF_INT 0x000000ff
#define HOSTCC_TXCOAL_MAXF_INT 0x00003c24
#define DEFAULT_TXCOAL_MAXF_INT 0x00000005
+#define MAX_TXCOAL_MAXF_INT 0x000000ff
#define HOSTCC_STAT_COAL_TICKS 0x00003c28
#define DEFAULT_STAT_COAL_TICKS 0x000f4240
+#define MAX_STAT_COAL_TICKS 0xd693d400
+#define MIN_STAT_COAL_TICKS 0x00000064
/* 0x3c2c --> 0x3c30 unused */
#define HOSTCC_STATS_BLK_HOST_ADDR 0x00003c30 /* 64-bit */
#define HOSTCC_STATUS_BLK_HOST_ADDR 0x00003c38 /* 64-bit */
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 7bfee366297..effab0b9adc 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -215,7 +215,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
poll_wait(file, &tun->read_wait, wait);
- if (skb_queue_len(&tun->readq))
+ if (!skb_queue_empty(&tun->readq))
mask |= POLLIN | POLLRDNORM;
return mask;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 0b5ca253796..ecfa6f8805c 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1906,9 +1906,9 @@ typhoon_sleep(struct typhoon *tp, pci_power_t state, u16 events)
*/
netif_carrier_off(tp->dev);
- pci_enable_wake(tp->pdev, pci_choose_state(pdev, state), 1);
+ pci_enable_wake(tp->pdev, state, 1);
pci_disable_device(pdev);
- return pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ return pci_set_power_state(pdev, state);
}
static int
@@ -2274,7 +2274,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
goto need_resume;
}
- if(typhoon_sleep(tp, state, tp->wol_events) < 0) {
+ if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
goto need_resume;
}
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 7217d44e885..2c83cca34b8 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -861,8 +861,7 @@ fst_tx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
/*
* Mark it for our own raw sockets interface
*/
-static unsigned short farsync_type_trans(struct sk_buff *skb,
- struct net_device *dev)
+static __be16 farsync_type_trans(struct sk_buff *skb, struct net_device *dev)
{
skb->dev = dev;
skb->mac.raw = skb->data;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 87496843681..48c03c11cd9 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -91,8 +91,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
-static unsigned short cisco_type_trans(struct sk_buff *skb,
- struct net_device *dev)
+static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
{
hdlc_header *data = (hdlc_header*)skb->data;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 7cd6195a2e4..b81263eaede 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -66,8 +66,7 @@ static void ppp_close(struct net_device *dev)
-static unsigned short ppp_type_trans(struct sk_buff *skb,
- struct net_device *dev)
+static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
{
return __constant_htons(ETH_P_WAN_PPP);
}
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index c41fb70b692..9456d31cb1c 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -24,8 +24,7 @@
#include <linux/hdlc.h>
-static unsigned short raw_type_trans(struct sk_buff *skb,
- struct net_device *dev)
+static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
{
return __constant_htons(ETH_P_IP);
}
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index c12648d8192..47f3c5d0203 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2374,7 +2374,7 @@ void stop_airo_card( struct net_device *dev, int freeres )
/*
* Clean out tx queue
*/
- if (test_bit(FLAG_MPI, &ai->flags) && skb_queue_len (&ai->txq) > 0) {
+ if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
struct sk_buff *skb = NULL;
for (;(skb = skb_dequeue(&ai->txq));)
dev_kfree_skb(skb);
@@ -3287,7 +3287,7 @@ exitrx:
if (status & EV_TXEXC)
get_tx_error(apriv, -1);
spin_lock_irqsave(&apriv->aux_lock, flags);
- if (skb_queue_len (&apriv->txq)) {
+ if (!skb_queue_empty(&apriv->txq)) {
spin_unlock_irqrestore(&apriv->aux_lock,flags);
mpi_send_packet (dev);
} else {
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index f10a9523034..bf25584d68d 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -33,7 +33,6 @@
#include <linux/timer.h>
#include <linux/netdevice.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -210,11 +209,6 @@ static dev_link_t *airo_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &airo_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -574,6 +568,7 @@ static struct pcmcia_driver airo_driver = {
.name = "airo_cs",
},
.attach = airo_attach,
+ .event = airo_event,
.detach = airo_detach,
.id_table = airo_ids,
};
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index b4f4bd7956a..9d496703c46 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -184,7 +184,7 @@ static int airport_hard_reset(struct orinoco_private *priv)
}
static int
-airport_attach(struct macio_dev *mdev, const struct of_match *match)
+airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
struct orinoco_private *priv;
struct net_device *dev;
@@ -266,16 +266,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
MODULE_LICENSE("Dual MPL/GPL");
-static struct of_match airport_match[] =
+static struct of_device_id airport_match[] =
{
{
.name = "radio",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{},
};
+MODULE_DEVICE_TABLE (of, airport_match);
+
static struct macio_driver airport_driver =
{
.name = DRIVER_NAME,
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 86379d4998a..ff031a3985b 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -43,7 +43,6 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -218,11 +217,6 @@ static dev_link_t *atmel_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &atmel_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -668,12 +662,13 @@ static struct pcmcia_device_id atmel_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
static struct pcmcia_driver atmel_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "atmel_cs",
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "atmel_cs",
},
- .attach = atmel_attach,
- .detach = atmel_detach,
+ .attach = atmel_attach,
+ .event = atmel_event,
+ .detach = atmel_detach,
.id_table = atmel_ids,
};
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index e12bd75b269..5f507c49907 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -62,7 +62,6 @@
#endif /* WIRELESS_EXT > 12 */
#endif
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -491,11 +490,6 @@ static dev_link_t *netwave_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &netwave_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1680,6 +1674,7 @@ static struct pcmcia_driver netwave_driver = {
.name = "netwave_cs",
},
.attach = netwave_attach,
+ .event = netwave_event,
.detach = netwave_detach,
.id_table = netwave_ids,
};
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 597c4586d04..368d2f962f6 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -31,7 +31,6 @@
#include <linux/etherdevice.h>
#include <linux/wireless.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -186,11 +185,6 @@ orinoco_cs_attach(void)
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &orinoco_cs_event;
client_reg.Version = 0x0210; /* FIXME: what does this mean? */
client_reg.event_callback_args.client_data = link;
@@ -664,6 +658,7 @@ static struct pcmcia_driver orinoco_driver = {
.name = DRIVER_NAME,
},
.attach = orinoco_cs_attach,
+ .event = orinoco_cs_event,
.detach = orinoco_cs_detach,
.id_table = orinoco_cs_ids,
};
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 31652af52ea..0e0ba614259 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -46,7 +46,6 @@
#include <linux/skbuff.h>
#include <linux/ethtool.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -393,11 +392,6 @@ static dev_link_t *ray_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &ray_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -2916,6 +2910,7 @@ static struct pcmcia_driver ray_driver = {
.name = "ray_cs",
},
.attach = ray_attach,
+ .event = ray_event,
.detach = ray_detach,
.id_table = ray_ids,
};
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 89532fd9294..f6130a53b79 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4684,12 +4684,6 @@ wavelan_attach(void)
/* Register with Card Services */
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_REGISTRATION_COMPLETE |
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &wavelan_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -4904,6 +4898,7 @@ static struct pcmcia_driver wavelan_driver = {
.name = "wavelan_cs",
},
.attach = wavelan_attach,
+ .event = wavelan_event,
.detach = wavelan_detach,
.id_table = wavelan_ids,
};
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index ea2ef8dddb9..677ff71883c 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -452,7 +452,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <pcmcia/version.h>
/* Wavelan declarations */
#include "i82593.h" /* Definitions for the Intel chip */
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index e3a900482d9..dd902126d01 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -49,7 +49,6 @@
#include <net/iw_handler.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -2005,13 +2004,6 @@ static dev_link_t *wl3501_attach(void)
link->next = wl3501_dev_list;
wl3501_dev_list = link;
client_reg.dev_info = &wl3501_dev_info;
- client_reg.EventMask = CS_EVENT_CARD_INSERTION |
- CS_EVENT_RESET_PHYSICAL |
- CS_EVENT_CARD_RESET |
- CS_EVENT_CARD_REMOVAL |
- CS_EVENT_PM_SUSPEND |
- CS_EVENT_PM_RESUME;
- client_reg.event_handler = wl3501_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2246,12 +2238,13 @@ static struct pcmcia_device_id wl3501_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, wl3501_ids);
static struct pcmcia_driver wl3501_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "wl3501_cs",
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "wl3501_cs",
},
- .attach = wl3501_attach,
- .detach = wl3501_detach,
+ .attach = wl3501_attach,
+ .event = wl3501_event,
+ .detach = wl3501_detach,
.id_table = wl3501_ids,
};
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index ff45662c4f7..24e6aacddb7 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -48,7 +48,6 @@
#include <linux/parport.h>
#include <linux/parport_pc.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -133,11 +132,6 @@ static dev_link_t *parport_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &parport_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -386,6 +380,7 @@ static struct pcmcia_driver parport_cs_driver = {
.name = "parport_cs",
},
.attach = parport_attach,
+ .event = parport_event,
.detach = parport_detach,
.id_table = parport_ids,
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 80edfa3abd2..4598c6a9212 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3008,7 +3008,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma)
int ret = 0;
while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
- id = pci_match_device (parport_pc_pci_tbl, pdev);
+ id = pci_match_id(parport_pc_pci_tbl, pdev);
if (id == NULL || id->driver_data >= last_sio)
continue;
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 7dea494c0d7..3657f6199c4 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
#
# Some architectures use the generic PCI setup functions
#
+obj-$(CONFIG_X86) += setup-bus.o
obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
obj-$(CONFIG_PARISC) += setup-bus.o
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index 3903f8c559b..b844bc97232 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -54,7 +54,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
envp[i++] = scratch;
length += scnprintf (scratch, buffer_size - length,
- "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+ "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 1a4d4ca2a4d..9c4a39ee89b 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -187,9 +187,10 @@ config HOTPLUG_PCI_RPA_DLPAR
config HOTPLUG_PCI_SGI
tristate "SGI PCI Hotplug Support"
- depends on HOTPLUG_PCI && IA64_SGI_SN2
+ depends on HOTPLUG_PCI && (IA64_SGI_SN2 || IA64_GENERIC)
help
- Say Y here if you have an SGI IA64 Altix system.
+ Say Y here if you want to use the SGI Altix Hotplug
+ Driver for PCI devices.
When in doubt, say N.
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 3e632ff8c71..31a307004b9 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
+obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o
pci_hotplug-objs := pci_hotplug_core.o
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
new file mode 100644
index 00000000000..323041fd41d
--- /dev/null
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -0,0 +1,611 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved.
+ *
+ * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
+ * Work to add BIOS PROM support was completed by Mike Habeck.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/types.h>
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/l1.h>
+#include <asm/sn/module.h>
+#include <asm/sn/pcibr_provider.h>
+#include <asm/sn/pcibus_provider_defs.h>
+#include <asm/sn/pcidev.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/types.h>
+
+#include "../pci.h"
+#include "pci_hotplug.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
+MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
+
+#define PCIIO_ASIC_TYPE_TIOCA 4
+#define PCI_SLOT_ALREADY_UP 2 /* slot already up */
+#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */
+#define PCI_L1_ERR 7 /* L1 console command error */
+#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */
+#define PCI_L1_QSIZE 128 /* our L1 message buffer size */
+#define SN_MAX_HP_SLOTS 32 /* max number of hotplug slots */
+#define SGI_HOTPLUG_PROM_REV 0x0420 /* Min. required PROM version */
+
+/* internal list head */
+static struct list_head sn_hp_list;
+
+/* hotplug_slot struct's private pointer */
+struct slot {
+ int device_num;
+ struct pci_bus *pci_bus;
+ /* this struct for glue internal only */
+ struct hotplug_slot *hotplug_slot;
+ struct list_head hp_list;
+};
+
+struct pcibr_slot_enable_resp {
+ int resp_sub_errno;
+ char resp_l1_msg[PCI_L1_QSIZE + 1];
+};
+
+struct pcibr_slot_disable_resp {
+ int resp_sub_errno;
+ char resp_l1_msg[PCI_L1_QSIZE + 1];
+};
+
+enum sn_pci_req_e {
+ PCI_REQ_SLOT_ELIGIBLE,
+ PCI_REQ_SLOT_DISABLE
+};
+
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+
+static struct hotplug_slot_ops sn_hotplug_slot_ops = {
+ .owner = THIS_MODULE,
+ .enable_slot = enable_slot,
+ .disable_slot = disable_slot,
+ .get_power_status = get_power_status,
+};
+
+static DECLARE_MUTEX(sn_hotplug_sem);
+
+static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
+{
+ struct pcibus_info *pcibus_info;
+ int bricktype;
+ int bus_num;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+ /* Check to see if this is a valid slot on 'pci_bus' */
+ if (!(pcibus_info->pbi_valid_devices & (1 << device)))
+ return -EPERM;
+
+ bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+ bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf;
+
+ /* Do not allow hotplug operations on base I/O cards */
+ if ((bricktype == L1_BRICKTYPE_IX || bricktype == L1_BRICKTYPE_IA) &&
+ (bus_num == 1 && device != 1))
+ return -EPERM;
+
+ return 1;
+}
+
+static int sn_pci_bus_valid(struct pci_bus *pci_bus)
+{
+ struct pcibus_info *pcibus_info;
+ int asic_type;
+ int bricktype;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+ /* Don't register slots hanging off the TIOCA bus */
+ asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
+ if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
+ return -EPERM;
+
+ /* Only register slots in I/O Bricks that support hotplug */
+ bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+ switch (bricktype) {
+ case L1_BRICKTYPE_IX:
+ case L1_BRICKTYPE_PX:
+ case L1_BRICKTYPE_IA:
+ case L1_BRICKTYPE_PA:
+ return 1;
+ break;
+ default:
+ return -EPERM;
+ break;
+ }
+
+ return -EIO;
+}
+
+static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
+ struct pci_bus *pci_bus, int device)
+{
+ struct pcibus_info *pcibus_info;
+ struct slot *slot;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+ bss_hotplug_slot->private = kcalloc(1, sizeof(struct slot),
+ GFP_KERNEL);
+ if (!bss_hotplug_slot->private)
+ return -ENOMEM;
+ slot = (struct slot *)bss_hotplug_slot->private;
+
+ bss_hotplug_slot->name = kmalloc(33, GFP_KERNEL);
+ if (!bss_hotplug_slot->name) {
+ kfree(bss_hotplug_slot->private);
+ return -ENOMEM;
+ }
+
+ slot->device_num = device;
+ slot->pci_bus = pci_bus;
+
+ sprintf(bss_hotplug_slot->name, "module_%c%c%c%c%.2d_b_%d_s_%d",
+ '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+ '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+ '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+ MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
+ MODULE_GET_BPOS(pcibus_info->pbi_moduleid),
+ ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
+ device + 1);
+
+ slot->hotplug_slot = bss_hotplug_slot;
+ list_add(&slot->hp_list, &sn_hp_list);
+
+ return 0;
+}
+
+static struct hotplug_slot * sn_hp_destroy(void)
+{
+ struct slot *slot;
+ struct list_head *list;
+ struct hotplug_slot *bss_hotplug_slot = NULL;
+
+ list_for_each(list, &sn_hp_list) {
+ slot = list_entry(list, struct slot, hp_list);
+ bss_hotplug_slot = slot->hotplug_slot;
+ list_del(&((struct slot *)bss_hotplug_slot->private)->
+ hp_list);
+ break;
+ }
+ return bss_hotplug_slot;
+}
+
+static void sn_bus_alloc_data(struct pci_dev *dev)
+{
+ struct list_head *node;
+ struct pci_bus *subordinate_bus;
+ struct pci_dev *child;
+
+ sn_pci_fixup_slot(dev);
+
+ /* Recursively sets up the sn_irq_info structs */
+ if (dev->subordinate) {
+ subordinate_bus = dev->subordinate;
+ list_for_each(node, &subordinate_bus->devices) {
+ child = list_entry(node, struct pci_dev, bus_list);
+ sn_bus_alloc_data(child);
+ }
+ }
+}
+
+static void sn_bus_free_data(struct pci_dev *dev)
+{
+ struct list_head *node;
+ struct pci_bus *subordinate_bus;
+ struct pci_dev *child;
+
+ /* Recursively clean up sn_irq_info structs */
+ if (dev->subordinate) {
+ subordinate_bus = dev->subordinate;
+ list_for_each(node, &subordinate_bus->devices) {
+ child = list_entry(node, struct pci_dev, bus_list);
+ sn_bus_free_data(child);
+ }
+ }
+ sn_pci_unfixup_slot(dev);
+}
+
+static u8 sn_power_status_get(struct hotplug_slot *bss_hotplug_slot)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+ u8 retval;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+ retval = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
+
+ return retval ? 1 : 0;
+}
+
+static void sn_slot_mark_enable(struct hotplug_slot *bss_hotplug_slot,
+ int device_num)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+ pcibus_info->pbi_enabled_devices |= (1 << device_num);
+}
+
+static void sn_slot_mark_disable(struct hotplug_slot *bss_hotplug_slot,
+ int device_num)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+ pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
+}
+
+static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
+ int device_num)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+ struct pcibr_slot_enable_resp resp;
+ int rc;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+
+ /*
+ * Power-on and initialize the slot in the SN
+ * PCI infrastructure.
+ */
+ rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp);
+
+ if (rc == PCI_SLOT_ALREADY_UP) {
+ dev_dbg(slot->pci_bus->self, "is already active\n");
+ return -EPERM;
+ }
+
+ if (rc == PCI_L1_ERR) {
+ dev_dbg(slot->pci_bus->self,
+ "L1 failure %d with message: %s",
+ resp.resp_sub_errno, resp.resp_l1_msg);
+ return -EPERM;
+ }
+
+ if (rc) {
+ dev_dbg(slot->pci_bus->self,
+ "insert failed with error %d sub-error %d\n",
+ rc, resp.resp_sub_errno);
+ return -EIO;
+ }
+
+ sn_slot_mark_enable(bss_hotplug_slot, device_num);
+
+ return 0;
+}
+
+static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
+ int device_num, int action)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+ struct pcibr_slot_disable_resp resp;
+ int rc;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+
+ rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
+
+ if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_SLOT_ALREADY_DOWN) {
+ dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
+ return -ENODEV;
+ }
+
+ if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_EMPTY_33MHZ) {
+ dev_dbg(slot->pci_bus->self,
+ "Cannot remove last 33MHz card\n");
+ return -EPERM;
+ }
+
+ if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_L1_ERR) {
+ dev_dbg(slot->pci_bus->self,
+ "L1 failure %d with message \n%s\n",
+ resp.resp_sub_errno, resp.resp_l1_msg);
+ return -EPERM;
+ }
+
+ if (action == PCI_REQ_SLOT_ELIGIBLE && rc) {
+ dev_dbg(slot->pci_bus->self,
+ "remove failed with error %d sub-error %d\n",
+ rc, resp.resp_sub_errno);
+ return -EIO;
+ }
+
+ if (action == PCI_REQ_SLOT_ELIGIBLE && !rc)
+ return 0;
+
+ if (action == PCI_REQ_SLOT_DISABLE && !rc) {
+ sn_slot_mark_disable(bss_hotplug_slot, device_num);
+ dev_dbg(slot->pci_bus->self, "remove successful\n");
+ return 0;
+ }
+
+ if (action == PCI_REQ_SLOT_DISABLE && rc) {
+ dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
+ return rc;
+ }
+
+ return rc;
+}
+
+static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pci_bus *new_bus = NULL;
+ struct pci_dev *dev;
+ int func, num_funcs;
+ int new_ppb = 0;
+ int rc;
+
+ /* Serialize the Linux PCI infrastructure */
+ down(&sn_hotplug_sem);
+
+ /*
+ * Power-on and initialize the slot in the SN
+ * PCI infrastructure.
+ */
+ rc = sn_slot_enable(bss_hotplug_slot, slot->device_num);
+ if (rc) {
+ up(&sn_hotplug_sem);
+ return rc;
+ }
+
+ num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num+1,
+ PCI_FUNC(0)));
+ if (!num_funcs) {
+ dev_dbg(slot->pci_bus->self, "no device in slot\n");
+ up(&sn_hotplug_sem);
+ return -ENODEV;
+ }
+
+ sn_pci_controller_fixup(pci_domain_nr(slot->pci_bus),
+ slot->pci_bus->number,
+ slot->pci_bus);
+ /*
+ * Map SN resources for all functions on the card
+ * to the Linux PCI interface and tell the drivers
+ * about them.
+ */
+ for (func = 0; func < num_funcs; func++) {
+ dev = pci_get_slot(slot->pci_bus,
+ PCI_DEVFN(slot->device_num + 1,
+ PCI_FUNC(func)));
+
+
+ if (dev) {
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ unsigned char sec_bus;
+ pci_read_config_byte(dev, PCI_SECONDARY_BUS,
+ &sec_bus);
+ new_bus = pci_add_new_bus(dev->bus, dev,
+ sec_bus);
+ pci_scan_child_bus(new_bus);
+ sn_pci_controller_fixup(pci_domain_nr(new_bus),
+ new_bus->number,
+ new_bus);
+ new_ppb = 1;
+ }
+ sn_bus_alloc_data(dev);
+ pci_dev_put(dev);
+ }
+ }
+
+ /* Call the driver for the new device */
+ pci_bus_add_devices(slot->pci_bus);
+ /* Call the drivers for the new devices subordinate to PPB */
+ if (new_ppb)
+ pci_bus_add_devices(new_bus);
+
+ up(&sn_hotplug_sem);
+
+ if (rc == 0)
+ dev_dbg(slot->pci_bus->self,
+ "insert operation successful\n");
+ else
+ dev_dbg(slot->pci_bus->self,
+ "insert operation failed rc = %d\n", rc);
+
+ return rc;
+}
+
+static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+ struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct pci_dev *dev;
+ int func;
+ int rc;
+
+ /* Acquire update access to the bus */
+ down(&sn_hotplug_sem);
+
+ /* is it okay to bring this slot down? */
+ rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
+ PCI_REQ_SLOT_ELIGIBLE);
+ if (rc)
+ goto leaving;
+
+ /* Free the SN resources assigned to the Linux device.*/
+ for (func = 0; func < 8; func++) {
+ dev = pci_get_slot(slot->pci_bus,
+ PCI_DEVFN(slot->device_num+1,
+ PCI_FUNC(func)));
+ if (dev) {
+ /*
+ * Some drivers may use dma accesses during the
+ * driver remove function. We release the sysdata
+ * areas after the driver remove functions have
+ * been called.
+ */
+ sn_bus_store_sysdata(dev);
+ sn_bus_free_data(dev);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+ }
+
+ /* free the collected sysdata pointers */
+ sn_bus_free_sysdata();
+
+ /* Deactivate slot */
+ rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
+ PCI_REQ_SLOT_DISABLE);
+ leaving:
+ /* Release the bus lock */
+ up(&sn_hotplug_sem);
+
+ return rc;
+}
+
+static int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value)
+{
+ down(&sn_hotplug_sem);
+ *value = sn_power_status_get(bss_hotplug_slot);
+ up(&sn_hotplug_sem);
+ return 0;
+}
+
+static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+ kfree(bss_hotplug_slot->info);
+ kfree(bss_hotplug_slot->name);
+ kfree(bss_hotplug_slot->private);
+ kfree(bss_hotplug_slot);
+}
+
+static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
+{
+ int device;
+ struct hotplug_slot *bss_hotplug_slot;
+ int rc = 0;
+
+ /*
+ * Currently only four devices are supported,
+ * in the future there maybe more -- up to 32.
+ */
+
+ for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
+ if (sn_pci_slot_valid(pci_bus, device) != 1)
+ continue;
+
+ bss_hotplug_slot = kcalloc(1,sizeof(struct hotplug_slot),
+ GFP_KERNEL);
+ if (!bss_hotplug_slot) {
+ rc = -ENOMEM;
+ goto alloc_err;
+ }
+
+ bss_hotplug_slot->info =
+ kcalloc(1,sizeof(struct hotplug_slot_info),
+ GFP_KERNEL);
+ if (!bss_hotplug_slot->info) {
+ rc = -ENOMEM;
+ goto alloc_err;
+ }
+
+ if (sn_hp_slot_private_alloc(bss_hotplug_slot,
+ pci_bus, device)) {
+ rc = -ENOMEM;
+ goto alloc_err;
+ }
+
+ bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
+ bss_hotplug_slot->release = &sn_release_slot;
+
+ rc = pci_hp_register(bss_hotplug_slot);
+ if (rc)
+ goto register_err;
+ }
+ dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
+ return rc;
+
+register_err:
+ dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
+ rc);
+
+alloc_err:
+ if (rc == -ENOMEM)
+ dev_dbg(pci_bus->self, "Memory allocation error\n");
+
+ /* destroy THIS element */
+ if (bss_hotplug_slot)
+ sn_release_slot(bss_hotplug_slot);
+
+ /* destroy anything else on the list */
+ while ((bss_hotplug_slot = sn_hp_destroy()))
+ pci_hp_deregister(bss_hotplug_slot);
+
+ return rc;
+}
+
+static int sn_pci_hotplug_init(void)
+{
+ struct pci_bus *pci_bus = NULL;
+ int rc;
+ int registered = 0;
+
+ INIT_LIST_HEAD(&sn_hp_list);
+
+ if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
+ printk(KERN_ERR "%s: PROM version must be greater than 4.05\n",
+ __FUNCTION__);
+ return -EPERM;
+ }
+
+ while ((pci_bus = pci_find_next_bus(pci_bus))) {
+ if (!pci_bus->sysdata)
+ continue;
+
+ rc = sn_pci_bus_valid(pci_bus);
+ if (rc != 1) {
+ dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
+ continue;
+ }
+ dev_dbg(pci_bus->self, "valid hotplug bus\n");
+
+ rc = sn_hotplug_slot_register(pci_bus);
+ if (!rc)
+ registered = 1;
+ else {
+ registered = 0;
+ break;
+ }
+ }
+
+ return registered == 1 ? 0 : -ENODEV;
+}
+
+static void sn_pci_hotplug_exit(void)
+{
+ struct hotplug_slot *bss_hotplug_slot;
+
+ while ((bss_hotplug_slot = sn_hp_destroy())) {
+ pci_hp_deregister(bss_hotplug_slot);
+ }
+
+ if (!list_empty(&sn_hp_list))
+ printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
+}
+
+module_init(sn_pci_hotplug_init);
+module_exit(sn_pci_hotplug_exit);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index bc01d34e263..e9e37abe1f7 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1,9 +1,10 @@
/*
* File: pci-acpi.c
- * Purpose: Provide PCI supports in ACPI
+ * Purpose: Provide PCI support in ACPI
*
- * Copyright (C) 2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com>
+ * Copyright (C) 2004 Intel Corp.
*/
#include <linux/delay.h>
@@ -16,6 +17,7 @@
#include <acpi/acpi_bus.h>
#include <linux/pci-acpi.h>
+#include "pci.h"
static u32 ctrlset_buf[3] = {0, 0, 0};
static u32 global_ctrlsets = 0;
@@ -207,3 +209,105 @@ acpi_status pci_osc_control_set(u32 flags)
return status;
}
EXPORT_SYMBOL(pci_osc_control_set);
+
+/*
+ * _SxD returns the D-state with the highest power
+ * (lowest D-state number) supported in the S-state "x".
+ *
+ * If the devices does not have a _PRW
+ * (Power Resources for Wake) supporting system wakeup from "x"
+ * then the OS is free to choose a lower power (higher number
+ * D-state) than the return value from _SxD.
+ *
+ * But if _PRW is enabled at S-state "x", the OS
+ * must not choose a power lower than _SxD --
+ * unless the device has an _SxW method specifying
+ * the lowest power (highest D-state number) the device
+ * may enter while still able to wake the system.
+ *
+ * ie. depending on global OS policy:
+ *
+ * if (_PRW at S-state x)
+ * choose from highest power _SxD to lowest power _SxW
+ * else // no _PRW at S-state x
+ * choose highest power _SxD or any lower power
+ *
+ * currently we simply return _SxD, if present.
+ */
+
+static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state)
+{
+ /* TBD */
+
+ return -ENODEV;
+}
+
+static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+{
+ acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
+ static int state_conv[] = {
+ [0] = 0,
+ [1] = 1,
+ [2] = 2,
+ [3] = 3,
+ [4] = 3
+ };
+ int acpi_state = state_conv[(int __force) state];
+
+ if (!handle)
+ return -ENODEV;
+ return acpi_bus_set_power(handle, acpi_state);
+}
+
+
+/* ACPI bus type */
+static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+ struct pci_dev * pci_dev;
+ acpi_integer addr;
+
+ pci_dev = to_pci_dev(dev);
+ /* Please ref to ACPI spec for the syntax of _ADR */
+ addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+ *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+ if (!*handle)
+ return -ENODEV;
+ return 0;
+}
+
+static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
+{
+ int num;
+ unsigned int seg, bus;
+
+ /*
+ * The string should be the same as root bridge's name
+ * Please look at 'pci_scan_bus_parented'
+ */
+ num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus);
+ if (num != 2)
+ return -ENODEV;
+ *handle = acpi_get_pci_rootbridge_handle(seg, bus);
+ if (!*handle)
+ return -ENODEV;
+ return 0;
+}
+
+static struct acpi_bus_type pci_acpi_bus = {
+ .bus = &pci_bus_type,
+ .find_device = pci_acpi_find_device,
+ .find_bridge = pci_acpi_find_root_bridge,
+};
+
+static int __init pci_acpi_init(void)
+{
+ int ret;
+
+ ret = register_acpi_bus_type(&pci_acpi_bus);
+ if (ret)
+ return 0;
+ platform_pci_choose_state = acpi_pci_choose_state;
+ platform_pci_set_power_state = acpi_pci_set_power_state;
+ return 0;
+}
+arch_initcall(pci_acpi_init);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e65bf2b395a..e4115a0d5ba 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,7 +7,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
-#include <linux/pci-dynids.h>
#include "pci.h"
/*
@@ -18,36 +17,12 @@
* Dynamic device IDs are disabled for !CONFIG_HOTPLUG
*/
-#ifdef CONFIG_HOTPLUG
-/**
- * pci_device_probe_dynamic()
- *
- * Walk the dynamic ID list looking for a match.
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
- */
-static int
-pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
- int error = -ENODEV;
- struct list_head *pos;
- struct dynid *dynid;
+struct pci_dynid {
+ struct list_head node;
+ struct pci_device_id id;
+};
- spin_lock(&drv->dynids.lock);
- list_for_each(pos, &drv->dynids.list) {
- dynid = list_entry(pos, struct dynid, node);
- if (pci_match_one_device(&dynid->id, pci_dev)) {
- spin_unlock(&drv->dynids.lock);
- error = drv->probe(pci_dev, &dynid->id);
- if (error >= 0) {
- pci_dev->driver = drv;
- return 0;
- }
- return error;
- }
- }
- spin_unlock(&drv->dynids.lock);
- return error;
-}
+#ifdef CONFIG_HOTPLUG
/**
* store_new_id
@@ -58,8 +33,7 @@ pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
static inline ssize_t
store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
- struct dynid *dynid;
- struct bus_type * bus;
+ struct pci_dynid *dynid;
struct pci_driver *pdrv = to_pci_driver(driver);
__u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
subdevice=PCI_ANY_ID, class=0, class_mask=0;
@@ -91,37 +65,22 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
list_add_tail(&pdrv->dynids.list, &dynid->node);
spin_unlock(&pdrv->dynids.lock);
- bus = get_bus(pdrv->driver.bus);
- if (bus) {
- if (get_driver(&pdrv->driver)) {
- down_write(&bus->subsys.rwsem);
- driver_attach(&pdrv->driver);
- up_write(&bus->subsys.rwsem);
- put_driver(&pdrv->driver);
- }
- put_bus(bus);
+ if (get_driver(&pdrv->driver)) {
+ driver_attach(&pdrv->driver);
+ put_driver(&pdrv->driver);
}
return count;
}
-
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
-static inline void
-pci_init_dynids(struct pci_dynids *dynids)
-{
- spin_lock_init(&dynids->lock);
- INIT_LIST_HEAD(&dynids->list);
-}
static void
pci_free_dynids(struct pci_driver *drv)
{
- struct list_head *pos, *n;
- struct dynid *dynid;
+ struct pci_dynid *dynid, *n;
spin_lock(&drv->dynids.lock);
- list_for_each_safe(pos, n, &drv->dynids.list) {
- dynid = list_entry(pos, struct dynid, node);
+ list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
list_del(&dynid->node);
kfree(dynid);
}
@@ -138,83 +97,70 @@ pci_create_newid_file(struct pci_driver *drv)
return error;
}
-static int
-pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
- struct list_head *pos;
- struct dynid *dynid;
-
- spin_lock(&pci_drv->dynids.lock);
- list_for_each(pos, &pci_drv->dynids.list) {
- dynid = list_entry(pos, struct dynid, node);
- if (pci_match_one_device(&dynid->id, pci_dev)) {
- spin_unlock(&pci_drv->dynids.lock);
- return 1;
- }
- }
- spin_unlock(&pci_drv->dynids.lock);
- return 0;
-}
-
#else /* !CONFIG_HOTPLUG */
-static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
- return -ENODEV;
-}
-static inline void pci_init_dynids(struct pci_dynids *dynids) {}
static inline void pci_free_dynids(struct pci_driver *drv) {}
static inline int pci_create_newid_file(struct pci_driver *drv)
{
return 0;
}
-static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
- return 0;
-}
#endif
/**
- * pci_match_device - Tell if a PCI device structure has a matching
- * PCI device id structure
+ * pci_match_id - See if a pci device matches a given pci_id table
* @ids: array of PCI device id structures to search in
- * @dev: the PCI device structure to match against
- *
+ * @dev: the PCI device structure to match against.
+ *
* Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices.Returns the matching
+ * system is in its list of supported devices. Returns the matching
* pci_device_id structure or %NULL if there is no match.
+ *
+ * Depreciated, don't use this as it will not catch any dynamic ids
+ * that a driver might want to check for.
*/
-const struct pci_device_id *
-pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+ struct pci_dev *dev)
{
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (pci_match_one_device(ids, dev))
- return ids;
- ids++;
+ if (ids) {
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ if (pci_match_one_device(ids, dev))
+ return ids;
+ ids++;
+ }
}
return NULL;
}
/**
- * pci_device_probe_static()
- *
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+ * pci_match_device - Tell if a PCI device structure has a matching
+ * PCI device id structure
+ * @ids: array of PCI device id structures to search in
+ * @dev: the PCI device structure to match against
+ * @drv: the PCI driver to match against
+ *
+ * Used by a driver to check whether a PCI device present in the
+ * system is in its list of supported devices. Returns the matching
+ * pci_device_id structure or %NULL if there is no match.
*/
-static int
-pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
- int error = -ENODEV;
+const struct pci_device_id *pci_match_device(struct pci_driver *drv,
+ struct pci_dev *dev)
+{
const struct pci_device_id *id;
+ struct pci_dynid *dynid;
- if (!drv->id_table)
- return error;
- id = pci_match_device(drv->id_table, pci_dev);
+ id = pci_match_id(drv->id_table, dev);
if (id)
- error = drv->probe(pci_dev, id);
- if (error >= 0) {
- pci_dev->driver = drv;
- error = 0;
+ return id;
+
+ /* static ids didn't match, lets look at the dynamic ones */
+ spin_lock(&drv->dynids.lock);
+ list_for_each_entry(dynid, &drv->dynids.list, node) {
+ if (pci_match_one_device(&dynid->id, dev)) {
+ spin_unlock(&drv->dynids.lock);
+ return &dynid->id;
+ }
}
- return error;
+ spin_unlock(&drv->dynids.lock);
+ return NULL;
}
/**
@@ -225,13 +171,20 @@ pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
*/
static int
__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
+{
+ const struct pci_device_id *id;
int error = 0;
if (!pci_dev->driver && drv->probe) {
- error = pci_device_probe_static(drv, pci_dev);
- if (error == -ENODEV)
- error = pci_device_probe_dynamic(drv, pci_dev);
+ error = -ENODEV;
+
+ id = pci_match_device(drv, pci_dev);
+ if (id)
+ error = drv->probe(pci_dev, id);
+ if (error >= 0) {
+ pci_dev->driver = drv;
+ error = 0;
+ }
}
return error;
}
@@ -371,12 +324,6 @@ static struct kobj_type pci_driver_kobj_type = {
.sysfs_ops = &pci_driver_sysfs_ops,
};
-static int
-pci_populate_driver_dir(struct pci_driver *drv)
-{
- return pci_create_newid_file(drv);
-}
-
/**
* pci_register_driver - register a new pci driver
* @drv: the driver structure to register
@@ -401,13 +348,15 @@ int pci_register_driver(struct pci_driver *drv)
drv->driver.shutdown = pci_device_shutdown;
drv->driver.owner = drv->owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
- pci_init_dynids(&drv->dynids);
+
+ spin_lock_init(&drv->dynids.lock);
+ INIT_LIST_HEAD(&drv->dynids.list);
/* register with core */
error = driver_register(&drv->driver);
if (!error)
- pci_populate_driver_dir(drv);
+ error = pci_create_newid_file(drv);
return error;
}
@@ -463,21 +412,17 @@ pci_dev_driver(const struct pci_dev *dev)
* system is in its list of supported devices.Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
-static int pci_bus_match(struct device * dev, struct device_driver * drv)
+static int pci_bus_match(struct device *dev, struct device_driver *drv)
{
- const struct pci_dev * pci_dev = to_pci_dev(dev);
- struct pci_driver * pci_drv = to_pci_driver(drv);
- const struct pci_device_id * ids = pci_drv->id_table;
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *pci_drv = to_pci_driver(drv);
const struct pci_device_id *found_id;
- if (!ids)
- return 0;
-
- found_id = pci_match_device(ids, pci_dev);
+ found_id = pci_match_device(pci_drv, pci_dev);
if (found_id)
return 1;
- return pci_bus_match_dynids(pci_dev, pci_drv);
+ return 0;
}
/**
@@ -536,6 +481,7 @@ static int __init pci_driver_init(void)
postcore_initcall(pci_driver_init);
+EXPORT_SYMBOL(pci_match_id);
EXPORT_SYMBOL(pci_match_device);
EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f04b9ffe415..1b34fc56067 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -235,7 +235,7 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
* -EIO if device does not support PCI PM.
* 0 if we can successfully change the power state.
*/
-
+int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
int
pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
@@ -299,11 +299,20 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
msleep(10);
else if (state == PCI_D2 || dev->current_state == PCI_D2)
udelay(200);
- dev->current_state = state;
+ /*
+ * Give firmware a chance to be called, such as ACPI _PRx, _PSx
+ * Firmware method after natice method ?
+ */
+ if (platform_pci_set_power_state)
+ platform_pci_set_power_state(dev, state);
+
+ dev->current_state = state;
return 0;
}
+int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+
/**
* pci_choose_state - Choose the power state of a PCI device
* @dev: PCI device to be suspended
@@ -316,10 +325,17 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
{
+ int ret;
+
if (!pci_find_capability(dev, PCI_CAP_ID_PM))
return PCI_D0;
- switch (state) {
+ if (platform_pci_choose_state) {
+ ret = platform_pci_choose_state(dev, state);
+ if (ret >= 0)
+ state = ret;
+ }
+ switch (state) {
case 0: return PCI_D0;
case 3: return PCI_D3hot;
default:
@@ -334,10 +350,6 @@ EXPORT_SYMBOL(pci_choose_state);
/**
* pci_save_state - save the PCI configuration space of a device before suspending
* @dev: - PCI device that we're dealing with
- * @buffer: - buffer to hold config space context
- *
- * @buffer must be large enough to hold the entire PCI 2.2 config space
- * (>= 64 bytes).
*/
int
pci_save_state(struct pci_dev *dev)
@@ -352,8 +364,6 @@ pci_save_state(struct pci_dev *dev)
/**
* pci_restore_state - Restore the saved state of a PCI device
* @dev: - PCI device that we're dealing with
- * @buffer: - saved PCI config space
- *
*/
int
pci_restore_state(struct pci_dev *dev)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 744da0d4ae5..d94d7af4f7a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -11,6 +11,10 @@ extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
void (*alignf)(void *, struct resource *,
unsigned long, unsigned long),
void *alignf_data);
+/* Firmware callbacks */
+extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
+
/* PCI /proc functions */
#ifdef CONFIG_PROC_FS
extern int pci_proc_attach_device(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 537b372dc34..a63bd8f7260 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -27,6 +27,11 @@
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
+struct pcie_port_device_ext {
+ int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */
+ unsigned int saved_msi_config_space[5];
+};
+
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index f5c5f10a3d2..393e0cee91a 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -275,10 +275,17 @@ int pcie_port_device_probe(struct pci_dev *dev)
int pcie_port_device_register(struct pci_dev *dev)
{
+ struct pcie_port_device_ext *p_ext;
int status, type, capabilities, irq_mode, i;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
+ /* Allocate port device extension */
+ if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+ return -ENOMEM;
+
+ pci_set_drvdata(dev, p_ext);
+
/* Get port type */
pci_read_config_word(dev,
pci_find_capability(dev, PCI_CAP_ID_EXP) +
@@ -288,6 +295,7 @@ int pcie_port_device_register(struct pci_dev *dev)
/* Now get port services */
capabilities = get_port_device_capability(dev);
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
+ p_ext->interrupt_mode = irq_mode;
/* Allocate child services if any */
for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
@@ -317,7 +325,7 @@ int pcie_port_device_register(struct pci_dev *dev)
static int suspend_iter(struct device *dev, void *data)
{
struct pcie_port_service_driver *service_driver;
- u32 state = (u32)data;
+ pm_message_t state = * (pm_message_t *) data;
if ((dev->bus == &pcie_port_bus_type) &&
(dev->driver)) {
@@ -328,9 +336,9 @@ static int suspend_iter(struct device *dev, void *data)
return 0;
}
-int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
+int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
{
- device_for_each_child(&dev->dev, (void *)state, suspend_iter);
+ device_for_each_child(&dev->dev, &state, suspend_iter);
return 0;
}
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index e9095ee508e..30bac7ed7c1 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -29,6 +29,78 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
+static void pci_save_msi_state(struct pci_dev *dev)
+{
+ struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+ int i = 0, pos;
+ u16 control;
+
+ if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+ return;
+
+ pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]);
+ control = p_ext->saved_msi_config_space[0] >> 16;
+ pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+ &p_ext->saved_msi_config_space[i++]);
+ if (control & PCI_MSI_FLAGS_64BIT) {
+ pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+ &p_ext->saved_msi_config_space[i++]);
+ pci_read_config_dword(dev, pos + PCI_MSI_DATA_64,
+ &p_ext->saved_msi_config_space[i++]);
+ } else
+ pci_read_config_dword(dev, pos + PCI_MSI_DATA_32,
+ &p_ext->saved_msi_config_space[i++]);
+ if (control & PCI_MSI_FLAGS_MASKBIT)
+ pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+ &p_ext->saved_msi_config_space[i++]);
+}
+
+static void pci_restore_msi_state(struct pci_dev *dev)
+{
+ struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+ int i = 0, pos;
+ u16 control;
+
+ if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+ return;
+
+ control = p_ext->saved_msi_config_space[i++] >> 16;
+ pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
+ pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+ p_ext->saved_msi_config_space[i++]);
+ if (control & PCI_MSI_FLAGS_64BIT) {
+ pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+ p_ext->saved_msi_config_space[i++]);
+ pci_write_config_dword(dev, pos + PCI_MSI_DATA_64,
+ p_ext->saved_msi_config_space[i++]);
+ } else
+ pci_write_config_dword(dev, pos + PCI_MSI_DATA_32,
+ p_ext->saved_msi_config_space[i++]);
+ if (control & PCI_MSI_FLAGS_MASKBIT)
+ pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+ p_ext->saved_msi_config_space[i++]);
+}
+
+static void pcie_portdrv_save_config(struct pci_dev *dev)
+{
+ struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+ pci_save_state(dev);
+ if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+ pci_save_msi_state(dev);
+}
+
+static void pcie_portdrv_restore_config(struct pci_dev *dev)
+{
+ struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+ pci_restore_state(dev);
+ if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+ pci_restore_msi_state(dev);
+ pci_enable_device(dev);
+ pci_set_master(dev);
+}
+
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
* @dev: PCI-Express port device being probed
@@ -64,16 +136,21 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
+ kfree(pci_get_drvdata(dev));
}
#ifdef CONFIG_PM
static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
{
- return pcie_port_device_suspend(dev, state);
+ int ret = pcie_port_device_suspend(dev, state);
+
+ pcie_portdrv_save_config(dev);
+ return ret;
}
static int pcie_portdrv_resume (struct pci_dev *dev)
{
+ pcie_portdrv_restore_config(dev);
return pcie_port_device_resume(dev);
}
#endif
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6a0a82f0508..df3bdae2040 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
if (dev->transparent) {
printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev));
- for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
- child->resource[i] = child->parent->resource[i];
- return;
+ for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
+ child->resource[i] = child->parent->resource[i - 3];
}
for(i=0; i<3; i++)
@@ -398,6 +397,16 @@ static void pci_enable_crs(struct pci_dev *dev)
pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
}
+static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
+{
+ struct pci_bus *parent = child->parent;
+ while (parent->parent && parent->subordinate < max) {
+ parent->subordinate = max;
+ pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
+ parent = parent->parent;
+ }
+}
+
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
/*
@@ -499,7 +508,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
if (!is_cardbus) {
child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA;
-
+ /*
+ * Adjust subordinate busnr in parent buses.
+ * We do this before scanning for children because
+ * some devices may not be detected if the bios
+ * was lazy.
+ */
+ pci_fixup_parent_subordinate_busnr(child, max);
/* Now we can scan all subordinate buses... */
max = pci_scan_child_bus(child);
} else {
@@ -513,6 +528,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
max+i+1))
break;
max += i;
+ pci_fixup_parent_subordinate_busnr(child, max);
}
/*
* Set the subordinate bus number to its real value.
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 968033fd29f..1521fd5d95c 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -767,6 +767,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
switch(dev->subsystem_device) {
+ case 0x8025: /* P4B-LX */
case 0x8070: /* P4B */
case 0x8088: /* P4B533 */
case 0x1626: /* L3C notebook */
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index a90a533eba0..05fa91a31c6 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -379,6 +379,7 @@ exit:
EXPORT_SYMBOL(pci_dev_present);
EXPORT_SYMBOL(pci_find_bus);
+EXPORT_SYMBOL(pci_find_next_bus);
EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_device_reverse);
EXPORT_SYMBOL(pci_find_slot);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6b628de948a..9fe48f712be 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -74,6 +74,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
idx = res - &list->dev->resource[0];
if (pci_assign_resource(list->dev, idx)) {
res->start = 0;
+ res->end = 0;
res->flags = 0;
}
tmp = list;
@@ -273,6 +274,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type)
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
r = bus->resource[i];
+ if (r == &ioport_resource || r == &iomem_resource)
+ continue;
if (r && (r->flags & type_mask) == type && !r->parent)
return r;
}
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 52ea3459436..6485f75d2fb 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -1,8 +1,5 @@
#
-# PCMCIA bus subsystem configuration
-#
-# Right now the non-CardBus choices are not supported
-# by the integrated kernel driver.
+# PCCARD (PCMCIA/CardBus) bus subsystem configuration
#
menu "PCCARD (PCMCIA/CardBus) support"
@@ -32,7 +29,7 @@ config PCMCIA_DEBUG
The kernel command line options are:
pcmcia_core.pc_debug=N
- ds.pc_debug=N
+ pcmcia.pc_debug=N
sa11xx_core.pc_debug=N
The module option is called pc_debug=N
@@ -73,7 +70,7 @@ config PCMCIA_LOAD_CIS
If unsure, say Y.
config PCMCIA_IOCTL
- bool
+ bool "PCMCIA control ioctl (obsolete)"
depends on PCMCIA
default y
help
@@ -81,9 +78,8 @@ config PCMCIA_IOCTL
subsystem will be built. It is needed by cardmgr and cardctl
(pcmcia-cs) to function properly.
- If you do not use the new pcmciautils package, and have a
- yenta, Cirrus PD6729, i82092, i82365 or tcic compatible bridge,
- you need to say Y here to be able to use 16-bit PCMCIA cards.
+ You should use the new pcmciautils package instead (see
+ <file:Documentation/Changes> for location and details).
If unsure, say Y.
@@ -106,7 +102,8 @@ comment "PC-card bridges"
config YENTA
tristate "CardBus yenta-compatible bridge support"
- depends on CARDBUS
+ depends on PCI
+ select CARDBUS if !EMBEDDED
select PCCARD_NONSTATIC
---help---
This option enables support for CardBus host bridges. Virtually
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index 417bc1500ba..d5122b1ea94 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,7 +22,6 @@
#define __ASM_AU1000_PCMCIA_H
/* include the world */
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index df19ce1ea4f..d414a3bb50b 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -33,7 +33,6 @@
#include <linux/version.h>
#include <linux/types.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 1dfc7765366..f113b69d699 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -38,7 +38,6 @@
#include <linux/version.h>
#include <linux/types.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 3ccb5247ec5..1d755e20880 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -31,7 +31,6 @@
#include <asm/io.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e82859d3227..e39178fc59d 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -33,7 +33,6 @@
#include <asm/irq.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -216,6 +215,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
list_add_tail(&socket->socket_list, &pcmcia_socket_list);
up_write(&pcmcia_socket_list_rwsem);
+#ifndef CONFIG_CARDBUS
+ /*
+ * If we do not support Cardbus, ensure that
+ * the Cardbus socket capability is disabled.
+ */
+ socket->features &= ~SS_CAP_CARDBUS;
+#endif
/* set proper values in socket->dev */
socket->dev.class_data = socket;
@@ -449,11 +455,11 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
}
if (status & SS_CARDBUS) {
+ if (!(skt->features & SS_CAP_CARDBUS)) {
+ cs_err(skt, "cardbus cards are not supported.\n");
+ return CS_BAD_TYPE;
+ }
skt->state |= SOCKET_CARDBUS;
-#ifndef CONFIG_CARDBUS
- cs_err(skt, "cardbus cards are not supported.\n");
- return CS_BAD_TYPE;
-#endif
}
/*
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 0b4c18edfa4..6bbfbd0e02a 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -99,23 +99,11 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
}
}
-#define CHECK_HANDLE(h) \
- (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
-
#define CHECK_SOCKET(s) \
(((s) >= sockets) || (socket_table[s]->ops == NULL))
-#define SOCKET(h) (h->Socket)
-#define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
-
-#define CHECK_REGION(r) \
- (((r) == NULL) || ((r)->region_magic != REGION_MAGIC))
-
-#define CHECK_ERASEQ(q) \
- (((q) == NULL) || ((q)->eraseq_magic != ERASEQ_MAGIC))
-
-#define EVENT(h, e, p) \
- ((h)->event_handler((e), (p), &(h)->event_callback_args))
+#define SOCKET(h) (h->socket)
+#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
/* In cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index d5afd557fe3..3e3c6f12bbe 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -158,17 +158,15 @@ static const lookup_t service_table[] = {
};
-static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
+static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
{
int i;
char *serv;
- if (CHECK_HANDLE(handle))
+ if (!p_dev)
printk(KERN_NOTICE);
- else {
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
+ else
printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
- }
for (i = 0; i < ARRAY_SIZE(service_table); i++)
if (service_table[i].key == err->func)
@@ -193,10 +191,10 @@ static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
/*======================================================================*/
-void cs_error(client_handle_t handle, int func, int ret)
+void cs_error(struct pcmcia_device *p_dev, int func, int ret)
{
error_info_t err = { func, ret };
- pcmcia_report_error(handle, &err);
+ pcmcia_report_error(p_dev, &err);
}
EXPORT_SYMBOL(cs_error);
@@ -207,6 +205,10 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
unsigned int i;
u32 hash;
+ if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+ printk(KERN_DEBUG "pcmcia: %s does misses a callback function",
+ p_drv->drv.name);
+
while (did && did->match_flags) {
for (i=0; i<4; i++) {
if (!did->prod_id[i])
@@ -376,7 +378,7 @@ static int pcmcia_device_probe(struct device * dev)
if (p_drv->attach) {
p_dev->instance = p_drv->attach();
- if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) {
+ if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
printk(KERN_NOTICE "ds: unable to create instance "
"of '%s'!\n", p_drv->drv.name);
ret = -EINVAL;
@@ -516,10 +518,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
/* compat */
- p_dev->client.client_magic = CLIENT_MAGIC;
- p_dev->client.Socket = s;
- p_dev->client.Function = function;
- p_dev->client.state = CLIENT_UNBOUND;
+ p_dev->state = CLIENT_UNBOUND;
/* Add to the list in pcmcia_bus_socket */
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -573,8 +572,6 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
else
no_funcs = 1;
- /* this doesn't handle multifunction devices on one pcmcia function
- * yet. */
for (i=0; i < no_funcs; i++)
pcmcia_device_add(s, i);
@@ -914,6 +911,7 @@ struct send_event_data {
static int send_event_callback(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+ struct pcmcia_driver *p_drv;
struct send_event_data *data = _data;
/* we get called for all sockets, but may only pass the event
@@ -921,11 +919,16 @@ static int send_event_callback(struct device *dev, void * _data)
if (p_dev->socket != data->skt)
return 0;
- if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
+ p_drv = to_pcmcia_drv(p_dev->dev.driver);
+ if (!p_drv)
return 0;
- if (p_dev->client.EventMask & data->event)
- return EVENT(&p_dev->client, data->event, data->priority);
+ if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
+ return 0;
+
+ if (p_drv->event)
+ return p_drv->event(data->event, data->priority,
+ &p_dev->event_callback_args);
return 0;
}
@@ -987,11 +990,11 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
+int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
{
- client_t *client = NULL;
struct pcmcia_socket *s = NULL;
struct pcmcia_device *p_dev = NULL;
+ struct pcmcia_driver *p_drv = NULL;
/* Look for unbound client with matching dev_info */
down_read(&pcmcia_socket_list_rwsem);
@@ -1006,18 +1009,16 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
continue;
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
- struct pcmcia_driver *p_drv;
p_dev = pcmcia_get_dev(p_dev);
if (!p_dev)
continue;
- if (!(p_dev->client.state & CLIENT_UNBOUND) ||
+ if (!(p_dev->state & CLIENT_UNBOUND) ||
(!p_dev->dev.driver)) {
pcmcia_put_dev(p_dev);
continue;
}
p_drv = to_pcmcia_drv(p_dev->dev.driver);
if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
- client = &p_dev->client;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
goto found;
}
@@ -1028,26 +1029,20 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
}
found:
up_read(&pcmcia_socket_list_rwsem);
- if (!p_dev || !client)
+ if (!p_dev)
return -ENODEV;
pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
- *handle = client;
- client->state &= ~CLIENT_UNBOUND;
- client->Socket = s;
- client->EventMask = req->EventMask;
- client->event_handler = req->event_handler;
- client->event_callback_args = req->event_callback_args;
- client->event_callback_args.client_handle = client;
+ *handle = p_dev;
+ p_dev->state &= ~CLIENT_UNBOUND;
+ p_dev->event_callback_args = req->event_callback_args;
+ p_dev->event_callback_args.client_handle = p_dev;
- if (s->state & SOCKET_CARDBUS)
- client->state |= CLIENT_CARDBUS;
- if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
- (client->Function != BIND_FN_ALL)) {
+ if (!s->functions) {
cistpl_longlink_mfc_t mfc;
- if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
+ if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
== CS_SUCCESS)
s->functions = mfc.nfn;
else
@@ -1060,13 +1055,13 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
}
ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
- client, p_dev->dev.bus_id);
- if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
- EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
+ p_dev, p_dev->dev.bus_id);
if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
- if (client->EventMask & CS_EVENT_CARD_INSERTION)
- EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+ if (p_drv->event)
+ p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
+ &p_dev->event_callback_args);
+
}
return CS_SUCCESS;
@@ -1099,7 +1094,7 @@ static int unbind_request(struct pcmcia_socket *s)
}
p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
list_del(&p_dev->socket_device_list);
- p_dev->client.state |= CLIENT_STALE;
+ p_dev->state |= CLIENT_STALE;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
device_unregister(&p_dev->dev);
@@ -1108,31 +1103,25 @@ static int unbind_request(struct pcmcia_socket *s)
return 0;
} /* unbind_request */
-int pcmcia_deregister_client(client_handle_t handle)
+int pcmcia_deregister_client(struct pcmcia_device *p_dev)
{
struct pcmcia_socket *s;
int i;
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
-
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- ds_dbg(1, "deregister_client(%p)\n", handle);
+ s = p_dev->socket;
+ ds_dbg(1, "deregister_client(%p)\n", p_dev);
- if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+ if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
goto warn_out;
for (i = 0; i < MAX_WIN; i++)
- if (handle->state & CLIENT_WIN_REQ(i))
+ if (p_dev->state & CLIENT_WIN_REQ(i))
goto warn_out;
- if (handle->state & CLIENT_STALE) {
- handle->client_magic = 0;
- handle->state &= ~CLIENT_STALE;
+ if (p_dev->state & CLIENT_STALE) {
+ p_dev->state &= ~CLIENT_STALE;
pcmcia_put_dev(p_dev);
} else {
- handle->state = CLIENT_UNBOUND;
- handle->event_handler = NULL;
+ p_dev->state = CLIENT_UNBOUND;
}
return CS_SUCCESS;
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 5ab55ae0ac3..316f8bcc878 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -43,7 +43,6 @@
#include <asm/hd64465/hd64465.h>
#include <asm/hd64465/io.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index d72f9a35c8b..a713015e822 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -53,7 +53,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -698,14 +697,6 @@ static void __init add_pcic(int ns, int type)
struct i82365_socket *t = &socket[sockets-ns];
base = sockets-ns;
- if (t->ioaddr > 0) {
- if (!request_region(t->ioaddr, 2, "i82365")) {
- printk(KERN_ERR "i82365: IO region conflict at %#lx, not available\n",
- t->ioaddr);
- return;
- }
- }
-
if (base == 0) printk("\n");
printk(KERN_INFO " %s", pcic[type].name);
printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index b1111c6bf06..65f3ee3d4d3 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -29,7 +29,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index c0997c4714f..7b14d7efd68 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -30,7 +30,6 @@
#include <asm/system.h>
#include <asm/addrspace.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
index 1cc83317e7e..ebb161c4f81 100644
--- a/drivers/pcmcia/pcmcia_compat.c
+++ b/drivers/pcmcia/pcmcia_compat.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
@@ -28,64 +27,39 @@
#include "cs_internal.h"
-int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_first_tuple(s, handle->Function, tuple);
+ return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
}
EXPORT_SYMBOL(pcmcia_get_first_tuple);
-int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_next_tuple(s, handle->Function, tuple);
+ return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
}
EXPORT_SYMBOL(pcmcia_get_next_tuple);
-int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_get_tuple_data(s, tuple);
+ return pccard_get_tuple_data(p_dev->socket, tuple);
}
EXPORT_SYMBOL(pcmcia_get_tuple_data);
-int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
{
return pccard_parse_tuple(tuple, parse);
}
EXPORT_SYMBOL(pcmcia_parse_tuple);
-int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
+int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_validate_cis(s, handle->Function, info);
+ return pccard_validate_cis(p_dev->socket, p_dev->func, info);
}
EXPORT_SYMBOL(pcmcia_validate_cis);
-int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
+int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
{
- struct pcmcia_socket *skt;
-
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- skt = SOCKET(handle);
- if (!skt)
- return CS_BAD_HANDLE;
-
- return pccard_reset_card(skt);
+ return pccard_reset_card(p_dev->socket);
}
EXPORT_SYMBOL(pcmcia_reset_card);
-
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index b883bc151ed..39ba6406fd5 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -31,7 +31,6 @@
#include <linux/workqueue.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -71,29 +70,6 @@ extern int ds_pc_debug;
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
#endif
-static const char *release = "Linux Kernel Card Services";
-
-/** pcmcia_get_card_services_info
- *
- * Return information about this version of Card Services
- */
-static int pcmcia_get_card_services_info(servinfo_t *info)
-{
- unsigned int socket_count = 0;
- struct list_head *tmp;
- info->Signature[0] = 'C';
- info->Signature[1] = 'S';
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each(tmp, &pcmcia_socket_list)
- socket_count++;
- up_read(&pcmcia_socket_list_rwsem);
- info->Count = socket_count;
- info->Revision = CS_RELEASE_CODE;
- info->CSLevel = 0x0210;
- info->VendorString = (char *)release;
- return CS_SUCCESS;
-} /* get_card_services_info */
-
/* backwards-compatible accessing of driver --- by name! */
@@ -591,9 +567,6 @@ static int ds_ioctl(struct inode * inode, struct file * file,
case DS_ADJUST_RESOURCE_INFO:
ret = pcmcia_adjust_resource_info(&buf->adjust);
break;
- case DS_GET_CARD_SERVICES_INFO:
- ret = pcmcia_get_card_services_info(&buf->servinfo);
- break;
case DS_GET_CONFIGURATION_INFO:
if (buf->config.Function &&
(buf->config.Function >= s->functions))
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index c01dc6bf152..184f4f88b2a 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -23,7 +23,6 @@
#include <linux/device.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -202,14 +201,11 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
return CS_SUCCESS;
} /* pccard_access_configuration_register */
-int pcmcia_access_configuration_register(client_handle_t handle,
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
conf_reg_t *reg)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- return pccard_access_configuration_register(s, handle->Function, reg);
+ return pccard_access_configuration_register(p_dev->socket,
+ p_dev->func, reg);
}
EXPORT_SYMBOL(pcmcia_access_configuration_register);
@@ -271,17 +267,11 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
return CS_SUCCESS;
} /* pccard_get_configuration_info */
-int pcmcia_get_configuration_info(client_handle_t handle,
+int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
config_info_t *config)
{
- struct pcmcia_socket *s;
-
- if ((CHECK_HANDLE(handle)) || !config)
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- if (!s)
- return CS_BAD_HANDLE;
- return pccard_get_configuration_info(s, handle->Function, config);
+ return pccard_get_configuration_info(p_dev->socket, p_dev->func,
+ config);
}
EXPORT_SYMBOL(pcmcia_get_configuration_info);
@@ -382,10 +372,8 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
{
struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
s = SOCKET(handle);
- return pccard_get_status(s, handle->Function, status);
+ return pccard_get_status(s, handle->func, status);
}
EXPORT_SYMBOL(pcmcia_get_status);
@@ -426,16 +414,14 @@ EXPORT_SYMBOL(pcmcia_map_mem_page);
*
* Modify a locked socket configuration
*/
-int pcmcia_modify_configuration(client_handle_t handle,
+int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
modconf_t *mod)
{
struct pcmcia_socket *s;
config_t *c;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
- c = CONFIG(handle);
+ s = p_dev->socket;
+ c = CONFIG(p_dev);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
if (!(c->state & CONFIG_LOCKED))
@@ -472,25 +458,18 @@ int pcmcia_modify_configuration(client_handle_t handle,
EXPORT_SYMBOL(pcmcia_modify_configuration);
-int pcmcia_release_configuration(client_handle_t handle)
+int pcmcia_release_configuration(struct pcmcia_device *p_dev)
{
pccard_io_map io = { 0, 0, 0, 0, 1 };
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
int i;
- if (CHECK_HANDLE(handle) ||
- !(handle->state & CLIENT_CONFIG_LOCKED))
+ if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_CONFIG_LOCKED;
- s = SOCKET(handle);
-
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_SUCCESS;
-#endif
+ p_dev->state &= ~CLIENT_CONFIG_LOCKED;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (--(s->lock_count) == 0) {
s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
s->socket.Vpp = 0;
@@ -523,22 +502,16 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
* don't bother checking the port ranges against the current socket
* values.
*/
-int pcmcia_release_io(client_handle_t handle, io_req_t *req)
+int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
+ if (!(p_dev->state & CLIENT_IO_REQ))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IO_REQ;
- s = SOCKET(handle);
-
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_SUCCESS;
-#endif
+ p_dev->state &= ~CLIENT_IO_REQ;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if ((c->io.BasePort1 != req->BasePort1) ||
@@ -558,16 +531,15 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
EXPORT_SYMBOL(pcmcia_release_io);
-int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
+int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
- struct pcmcia_socket *s;
- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
+ struct pcmcia_socket *s = p_dev->socket;
+ if (!(p_dev->state & CLIENT_IRQ_REQ))
return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IRQ_REQ;
- s = SOCKET(handle);
+ p_dev->state &= ~CLIENT_IRQ_REQ;
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
+ if (!(p_dev->state & CLIENT_STALE)) {
+ config_t *c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->irq.Attributes != req->Attributes)
@@ -623,29 +595,21 @@ int pcmcia_release_window(window_handle_t win)
EXPORT_SYMBOL(pcmcia_release_window);
-int pcmcia_request_configuration(client_handle_t handle,
+int pcmcia_request_configuration(struct pcmcia_device *p_dev,
config_req_t *req)
{
int i;
u_int base;
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
pccard_io_map iomap;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
-#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS)
- return CS_UNSUPPORTED_MODE;
-#endif
-
if (req->IntType & INT_CARDBUS)
return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
@@ -746,7 +710,7 @@ int pcmcia_request_configuration(client_handle_t handle,
}
c->state |= CONFIG_LOCKED;
- handle->state |= CLIENT_CONFIG_LOCKED;
+ p_dev->state |= CLIENT_CONFIG_LOCKED;
return CS_SUCCESS;
} /* pcmcia_request_configuration */
EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -757,29 +721,17 @@ EXPORT_SYMBOL(pcmcia_request_configuration);
* Request_io() reserves ranges of port addresses for a socket.
* I have not implemented range sharing or alias addressing.
*/
-int pcmcia_request_io(client_handle_t handle, io_req_t *req)
+int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
- if (handle->state & CLIENT_CARDBUS) {
-#ifdef CONFIG_CARDBUS
- handle->state |= CLIENT_IO_REQ;
- return CS_SUCCESS;
-#else
- return CS_UNSUPPORTED_FUNCTION;
-#endif
- }
-
if (!req)
return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IO_REQ)
@@ -804,7 +756,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
c->io = *req;
c->state |= CONFIG_IO_REQ;
- handle->state |= CLIENT_IO_REQ;
+ p_dev->state |= CLIENT_IO_REQ;
return CS_SUCCESS;
} /* pcmcia_request_io */
EXPORT_SYMBOL(pcmcia_request_io);
@@ -827,19 +779,15 @@ static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
}
#endif
-int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
+int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = p_dev->socket;
config_t *c;
int ret = CS_IN_USE, irq = 0;
- struct pcmcia_device *p_dev = handle_to_pdev(handle);
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
- c = CONFIG(handle);
+ c = CONFIG(p_dev);
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IRQ_REQ)
@@ -903,7 +851,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
s->irq.Config++;
c->state |= CONFIG_IRQ_REQ;
- handle->state |= CLIENT_IRQ_REQ;
+ p_dev->state |= CLIENT_IRQ_REQ;
#ifdef CONFIG_PCMCIA_PROBE
pcmcia_used_irq[irq]++;
@@ -919,16 +867,13 @@ EXPORT_SYMBOL(pcmcia_request_irq);
* Request_window() establishes a mapping between card memory space
* and system memory space.
*/
-int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
+int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
{
- struct pcmcia_socket *s;
+ struct pcmcia_socket *s = (*p_dev)->socket;
window_t *win;
u_long align;
int w;
- if (CHECK_HANDLE(*handle))
- return CS_BAD_HANDLE;
- s = (*handle)->Socket;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
if (req->Attributes & (WIN_PAGED | WIN_SHARED))
@@ -957,7 +902,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
win = &s->win[w];
win->magic = WINDOW_MAGIC;
win->index = w;
- win->handle = *handle;
+ win->handle = *p_dev;
win->sock = s;
if (!(s->features & SS_CAP_STATIC_MAP)) {
@@ -966,7 +911,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
if (!win->ctl.res)
return CS_IN_USE;
}
- (*handle)->state |= CLIENT_WIN_REQ(w);
+ (*p_dev)->state |= CLIENT_WIN_REQ(w);
/* Configure the socket controller */
win->ctl.map = w+1;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index f1bb7915302..e98bb3d80e7 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -34,7 +34,6 @@
#include <linux/init.h>
#include <linux/config.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 700a155fbc7..6f14126889b 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -11,7 +11,6 @@
/* include the world */
#include <linux/cpufreq.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index fcef54c1c2d..1040a6c1a8a 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#define IN_CARD_SERVICES
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index aacbbb5f055..d5a61eae611 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -50,7 +50,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index c7ba99871ac..fbe233e19ce 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -154,8 +154,6 @@
#define ENE_TEST_C9 0xc9 /* 8bit */
#define ENE_TEST_C9_TLTENABLE 0x02
-#ifdef CONFIG_CARDBUS
-
/*
* Texas Instruments CardBus controller overrides.
*/
@@ -843,7 +841,5 @@ static int ti1250_override(struct yenta_socket *socket)
return ti12xx_override(socket);
}
-#endif /* CONFIG_CARDBUS */
-
#endif /* _LINUX_TI113X_H */
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 02b23abc2df..6837491f021 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -18,7 +18,6 @@
#include <linux/delay.h>
#include <linux/module.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
@@ -528,98 +527,144 @@ static int yenta_sock_suspend(struct pcmcia_socket *sock)
* Use an adaptive allocation for the memory resource,
* sometimes the memory behind pci bridges is limited:
* 1/8 of the size of the io window of the parent.
- * max 4 MB, min 16 kB.
+ * max 4 MB, min 16 kB. We try very hard to not get below
+ * the "ACC" values, though.
*/
#define BRIDGE_MEM_MAX 4*1024*1024
+#define BRIDGE_MEM_ACC 128*1024
#define BRIDGE_MEM_MIN 16*1024
-#define BRIDGE_IO_MAX 256
+#define BRIDGE_IO_MAX 512
+#define BRIDGE_IO_ACC 256
#define BRIDGE_IO_MIN 32
#ifndef PCIBIOS_MIN_CARDBUS_IO
#define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO
#endif
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
+static int yenta_search_one_res(struct resource *root, struct resource *res,
+ u32 min)
+{
+ u32 align, size, start, end;
+
+ if (res->flags & IORESOURCE_IO) {
+ align = 1024;
+ size = BRIDGE_IO_MAX;
+ start = PCIBIOS_MIN_CARDBUS_IO;
+ end = ~0U;
+ } else {
+ unsigned long avail = root->end - root->start;
+ int i;
+ size = BRIDGE_MEM_MAX;
+ if (size > avail/8) {
+ size=(avail+1)/8;
+ /* round size down to next power of 2 */
+ i = 0;
+ while ((size /= 2) != 0)
+ i++;
+ size = 1 << i;
+ }
+ if (size < min)
+ size = min;
+ align = size;
+ start = PCIBIOS_MIN_MEM;
+ end = ~0U;
+ }
+
+ do {
+ if (allocate_resource(root, res, size, start, end, align,
+ NULL, NULL)==0) {
+ return 1;
+ }
+ size = size/2;
+ align = size;
+ } while (size >= min);
+
+ return 0;
+}
+
+
+static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
+ u32 min)
+{
+ int i;
+ for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+ struct resource * root = socket->dev->bus->resource[i];
+ if (!root)
+ continue;
+
+ if ((res->flags ^ root->flags) &
+ (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH))
+ continue; /* Wrong type */
+
+ if (yenta_search_one_res(root, res, min))
+ return 1;
+ }
+ return 0;
+}
+
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
{
struct pci_bus *bus;
struct resource *root, *res;
u32 start, end;
- u32 align, size, min;
- unsigned offset;
unsigned mask;
res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
/* Already allocated? */
if (res->parent)
- return 0;
+ return;
/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
mask = ~0xfff;
if (type & IORESOURCE_IO)
mask = ~3;
- offset = 0x1c + 8*nr;
bus = socket->dev->subordinate;
res->name = bus->name;
res->flags = type;
- res->start = 0;
- res->end = 0;
- root = pci_find_parent_resource(socket->dev, res);
- if (!root)
- return;
-
- start = config_readl(socket, offset) & mask;
- end = config_readl(socket, offset+4) | ~mask;
+ start = config_readl(socket, addr_start) & mask;
+ end = config_readl(socket, addr_end) | ~mask;
if (start && end > start && !override_bios) {
res->start = start;
res->end = end;
- if (request_resource(root, res) == 0)
+ root = pci_find_parent_resource(socket->dev, res);
+ if (root && (request_resource(root, res) == 0))
return;
- printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
+ printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
pci_name(socket->dev), nr);
- res->start = res->end = 0;
}
if (type & IORESOURCE_IO) {
- align = 1024;
- size = BRIDGE_IO_MAX;
- min = BRIDGE_IO_MIN;
- start = PCIBIOS_MIN_CARDBUS_IO;
- end = ~0U;
+ if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
+ }
} else {
- unsigned long avail = root->end - root->start;
- int i;
- size = BRIDGE_MEM_MAX;
- if (size > avail/8) {
- size=(avail+1)/8;
- /* round size down to next power of 2 */
- i = 0;
- while ((size /= 2) != 0)
- i++;
- size = 1 << i;
+ if (type & IORESOURCE_PREFETCH) {
+ if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
+ }
+ /* Approximating prefetchable by non-prefetchable */
+ res->flags = IORESOURCE_MEM;
}
- if (size < BRIDGE_MEM_MIN)
- size = BRIDGE_MEM_MIN;
- min = BRIDGE_MEM_MIN;
- align = size;
- start = PCIBIOS_MIN_MEM;
- end = ~0U;
- }
-
- do {
- if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
- config_writel(socket, offset, res->start);
- config_writel(socket, offset+4, res->end);
- return;
+ if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+ config_writel(socket, addr_start, res->start);
+ config_writel(socket, addr_end, res->end);
}
- size = size/2;
- align = size;
- } while (size >= min);
+ }
+
printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
- pci_name(socket->dev), type);
- res->start = res->end = 0;
+ pci_name(socket->dev), type);
+ res->start = res->end = res->flags = 0;
}
/*
@@ -627,10 +672,14 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
*/
static void yenta_allocate_resources(struct yenta_socket *socket)
{
- yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
- yenta_allocate_res(socket, 1, IORESOURCE_MEM);
- yenta_allocate_res(socket, 2, IORESOURCE_IO);
- yenta_allocate_res(socket, 3, IORESOURCE_IO); /* PCI isn't clever enough to use this one yet */
+ yenta_allocate_res(socket, 0, IORESOURCE_IO,
+ PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+ yenta_allocate_res(socket, 1, IORESOURCE_IO,
+ PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+ yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+ PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
+ yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+ PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
}
@@ -869,14 +918,11 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
*/
static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
{
- socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
- socket->socket.map_size = 0x1000;
socket->socket.pci_irq = socket->cb_irq;
if (isa_probe)
socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
else
socket->socket.irq_mask = 0;
- socket->socket.cb_dev = socket->dev;
printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
@@ -942,6 +988,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->socket.dev.dev = &dev->dev;
socket->socket.driver_data = socket;
socket->socket.owner = THIS_MODULE;
+ socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
+ socket->socket.map_size = 0x1000;
+ socket->socket.cb_dev = dev;
/* prepare struct yenta_socket */
socket->dev = dev;
@@ -1012,6 +1061,10 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->poll_timer.data = (unsigned long)socket;
socket->poll_timer.expires = jiffies + HZ;
add_timer(&socket->poll_timer);
+ printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
+ KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
+ } else {
+ socket->socket.features |= SS_CAP_CARDBUS;
}
/* Figure out what the dang thing can do for the PCMCIA layer... */
@@ -1052,6 +1105,7 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
pci_save_state(dev);
pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+ pci_disable_device(dev);
/*
* Some laptops (IBM T22) do not like us putting the Cardbus
@@ -1075,6 +1129,8 @@ static int yenta_dev_resume (struct pci_dev *dev)
pci_restore_state(dev);
pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
+ pci_enable_device(dev);
+ pci_set_master(dev);
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index dd61e09029b..75575f6c349 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -160,7 +160,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
acpi_register_gsi(res->data.irq.interrupts[0],
res->data.irq.edge_level,
res->data.irq.active_high_low));
- pcibios_penalize_isa_irq(res->data.irq.interrupts[0]);
+ pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1);
}
break;
@@ -171,7 +171,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
acpi_register_gsi(res->data.extended_irq.interrupts[0],
res->data.extended_irq.edge_level,
res->data.extended_irq.active_high_low));
- pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0]);
+ pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
}
break;
case ACPI_RSTYPE_DMA:
@@ -444,6 +444,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
struct acpipnp_parse_option_s {
struct pnp_option *option;
+ struct pnp_option *option_independent;
struct pnp_dev *dev;
};
@@ -507,7 +508,14 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
parse_data->option = option;
break;
case ACPI_RSTYPE_END_DPF:
- return AE_CTRL_TERMINATE;
+ /*only one EndDependentFn is allowed*/
+ if (!parse_data->option_independent) {
+ pnp_warn("PnPACPI: more than one EndDependentFn");
+ return AE_ERROR;
+ }
+ parse_data->option = parse_data->option_independent;
+ parse_data->option_independent = NULL;
+ break;
default:
pnp_warn("PnPACPI: unknown resource type %d", res->id);
return AE_ERROR;
@@ -525,6 +533,7 @@ acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
parse_data.option = pnp_register_independent_option(dev);
if (!parse_data.option)
return AE_ERROR;
+ parse_data.option_independent = parse_data.option;
parse_data.dev = dev;
status = acpi_walk_resources(handle, METHOD_NAME__PRS,
pnpacpi_option_resource, &parse_data);
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 79bce7b7574..9001b6f0204 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -64,7 +64,7 @@ pnpbios_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
}
res->irq_resource[i].start =
res->irq_resource[i].end = (unsigned long) irq;
- pcibios_penalize_isa_irq(irq);
+ pcibios_penalize_isa_irq(irq, 1);
}
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 2d1322dd7e1..887ad893934 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -102,7 +102,7 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
for (i = 0; i < 16; i++)
if (test_bit(i, data->map))
- pcibios_penalize_isa_irq(i);
+ pcibios_penalize_isa_irq(i, 0);
}
#endif
return 0;
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 60440dbe3a2..24c0af49c25 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -428,7 +428,7 @@ claw_pack_skb(struct claw_privbk *privptr)
new_skb = NULL; /* assume no dice */
pkt_cnt = 0;
CLAW_DBF_TEXT(4,trace,"PackSKBe");
- if (skb_queue_len(&p_ch->collect_queue) > 0) {
+ if (!skb_queue_empty(&p_ch->collect_queue)) {
/* some data */
held_skb = skb_dequeue(&p_ch->collect_queue);
if (p_env->packing != DO_PACKED)
@@ -1254,7 +1254,7 @@ claw_write_next ( struct chbk * p_ch )
privptr = (struct claw_privbk *) dev->priv;
claw_free_wrt_buf( dev );
if ((privptr->write_free_count > 0) &&
- (skb_queue_len(&p_ch->collect_queue) > 0)) {
+ !skb_queue_empty(&p_ch->collect_queue)) {
pk_skb = claw_pack_skb(privptr);
while (pk_skb != NULL) {
rc = claw_hw_tx( pk_skb, dev,1);
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
index 3080393e823..968f2c113ef 100644
--- a/drivers/s390/net/ctctty.c
+++ b/drivers/s390/net/ctctty.c
@@ -156,7 +156,7 @@ ctc_tty_readmodem(ctc_tty_info *info)
skb_queue_head(&info->rx_queue, skb);
else {
kfree_skb(skb);
- ret = skb_queue_len(&info->rx_queue);
+ ret = !skb_queue_empty(&info->rx_queue);
}
}
}
@@ -530,7 +530,7 @@ ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
total += c;
count -= c;
}
- if (skb_queue_len(&info->tx_queue)) {
+ if (!skb_queue_empty(&info->tx_queue)) {
info->lsr &= ~UART_LSR_TEMT;
tasklet_schedule(&info->tasklet);
}
@@ -594,7 +594,7 @@ ctc_tty_flush_chars(struct tty_struct *tty)
return;
if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
return;
- if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
+ if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
return;
tasklet_schedule(&info->tasklet);
}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 3cb88c77003..8f4d2999af8 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -2210,7 +2210,7 @@ no_mem:
return NULL;
}
-static inline unsigned short
+static inline __be16
qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct qeth_card *card;
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 8f0f46907a8..87302fb1488 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -79,10 +79,6 @@ struct inst {
unsigned char run_length;
unsigned char repeat_byte;
-
- /* These members manage timeouts for programmed delays */
- wait_queue_head_t wait_queue;
- struct timer_list timer_list;
};
static struct inst instances[BPP_NO];
@@ -297,16 +293,10 @@ static unsigned short get_pins(unsigned minor)
#endif /* __sparc__ */
-static void bpp_wake_up(unsigned long val)
-{ wake_up(&instances[val].wait_queue); }
-
static void snooze(unsigned long snooze_time, unsigned minor)
{
- init_timer(&instances[minor].timer_list);
- instances[minor].timer_list.expires = jiffies + snooze_time + 1;
- instances[minor].timer_list.data = minor;
- add_timer(&instances[minor].timer_list);
- sleep_on (&instances[minor].wait_queue);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(snooze_time + 1);
}
static int wait_for(unsigned short set, unsigned short clr,
@@ -880,11 +870,8 @@ static void probeLptPort(unsigned idx)
instances[idx].enhanced = 0;
instances[idx].direction = 0;
instances[idx].mode = COMPATIBILITY;
- instances[idx].wait_queue = 0;
instances[idx].run_length = 0;
instances[idx].run_flag = 0;
- init_timer(&instances[idx].timer_list);
- instances[idx].timer_list.function = bpp_wake_up;
if (!request_region(lpAddr,3, dev_name)) return;
/*
@@ -977,11 +964,8 @@ static void probeLptPort(unsigned idx)
instances[idx].enhanced = 0;
instances[idx].direction = 0;
instances[idx].mode = COMPATIBILITY;
- init_waitqueue_head(&instances[idx].wait_queue);
instances[idx].run_length = 0;
instances[idx].run_flag = 0;
- init_timer(&instances[idx].timer_list);
- instances[idx].timer_list.function = bpp_wake_up;
if (!rp) return;
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 1fef92d55de..390cd67c57c 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -469,7 +469,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
goto cleanup;
}
- user_srbcmd = kmalloc(GFP_KERNEL, fibsize);
+ user_srbcmd = kmalloc(fibsize, GFP_KERNEL);
if (!user_srbcmd) {
dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n"));
rcode = -ENOMEM;
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index edd47d1f0b1..932dcf0366e 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -424,7 +424,7 @@ static struct scsi_host_template mac53c94_template = {
.use_clustering = DISABLE_CLUSTERING,
};
-static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *node = macio_get_of_node(mdev);
struct pci_dev *pdev = macio_get_pci_dev(mdev);
@@ -544,15 +544,14 @@ static int mac53c94_remove(struct macio_dev *mdev)
}
-static struct of_match mac53c94_match[] =
+static struct of_device_id mac53c94_match[] =
{
{
.name = "53c94",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{},
};
+MODULE_DEVICE_TABLE (of, mac53c94_match);
static struct macio_driver mac53c94_driver =
{
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index b05737ae5ef..ff1933298da 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1847,7 +1847,7 @@ static struct scsi_host_template mesh_template = {
.use_clustering = DISABLE_CLUSTERING,
};
-static int mesh_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mesh = macio_get_of_node(mdev);
struct pci_dev* pdev = macio_get_pci_dev(mdev);
@@ -2012,20 +2012,18 @@ static int mesh_remove(struct macio_dev *mdev)
}
-static struct of_match mesh_match[] =
+static struct of_device_id mesh_match[] =
{
{
.name = "mesh",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
- .name = OF_ANY_MATCH,
.type = "scsi",
.compatible = "chrp,mesh0"
},
{},
};
+MODULE_DEVICE_TABLE (of, mesh_match);
static struct macio_driver mesh_driver =
{
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index f1f6bf596dc..7c530649983 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -50,7 +50,6 @@
#include <scsi/scsi_host.h>
#include "aha152x.h"
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *aha152x_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.event_handler = &aha152x_event;
- client_reg.EventMask =
- CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -334,6 +328,7 @@ static struct pcmcia_driver aha152x_cs_driver = {
.name = "aha152x_cs",
},
.attach = aha152x_attach,
+ .event = aha152x_event,
.detach = aha152x_detach,
.id_table = aha152x_ids,
};
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 853e6ee9b71..db8f5cd85ff 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -47,7 +47,6 @@
#include <scsi/scsi_host.h>
#include "fdomain.h"
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -120,11 +119,6 @@ static dev_link_t *fdomain_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.event_handler = &fdomain_event;
- client_reg.EventMask =
- CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -314,6 +308,7 @@ static struct pcmcia_driver fdomain_cs_driver = {
.name = "fdomain_cs",
},
.attach = fdomain_attach,
+ .event = fdomain_event,
.detach = fdomain_detach,
.id_table = fdomain_ids,
};
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 91b3f28e7a1..3cd3b40b1a4 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -51,7 +51,6 @@
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -1642,11 +1641,6 @@ static dev_link_t *nsp_cs_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
- client_reg.event_handler = &nsp_cs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2138,12 +2132,13 @@ static struct pcmcia_device_id nsp_cs_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
static struct pcmcia_driver nsp_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "nsp_cs",
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "nsp_cs",
},
- .attach = nsp_cs_attach,
- .detach = nsp_cs_detach,
+ .attach = nsp_cs_attach,
+ .event = nsp_cs_event,
+ .detach = nsp_cs_detach,
.id_table = nsp_cs_ids,
};
#endif
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 0dcf41102ab..7a516f35834 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -49,7 +49,6 @@
#include <scsi/scsi_host.h>
#include "../qlogicfas408.h"
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -194,8 +193,6 @@ static dev_link_t *qlogic_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.event_handler = &qlogic_event;
- client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -423,6 +420,7 @@ static struct pcmcia_driver qlogic_cs_driver = {
.name = "qlogic_cs",
},
.attach = qlogic_attach,
+ .event = qlogic_event,
.detach = qlogic_detach,
.id_table = qlogic_ids,
};
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 7d4b16b6797..b4b3a1a8a0c 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -979,10 +979,6 @@ SYM53C500_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.event_handler = &SYM53C500_event;
- client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1013,6 +1009,7 @@ static struct pcmcia_driver sym53c500_cs_driver = {
.name = "sym53c500_cs",
},
.attach = SYM53C500_attach,
+ .event = SYM53C500_event,
.detach = SYM53C500_detach,
.id_table = sym53c500_ids,
};
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index de26cf7b003..7911912f50c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
}
+#ifdef CONFIG_MPC885ADS
+ /* Enable SMC1 transceivers */
+ {
+ volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4);
+ uint tmp;
+
+ tmp = in_be32(bcsr1);
+ tmp &= ~BCSR1_RS232EN_1;
+ out_be32(bcsr1, tmp);
+ iounmap(bcsr1);
+ }
+#endif
+
pinfo->brg = 1;
}
void smc2_lineif(struct uart_cpm_port *pinfo)
{
- /* XXX SMC2: insert port configuration here */
+#ifdef CONFIG_MPC885ADS
+ volatile cpm8xx_t *cp = cpmp;
+ volatile uint __iomem *bcsr1;
+ uint tmp;
+
+ cp->cp_pepar |= 0x00000c00;
+ cp->cp_pedir &= ~0x00000c00;
+ cp->cp_peso &= ~0x00000400;
+ cp->cp_peso |= 0x00000800;
+
+ /* Enable SMC2 transceivers */
+ bcsr1 = ioremap(BCSR1, 4);
+ tmp = in_be32(bcsr1);
+ tmp &= ~BCSR1_RS232EN_2;
+ out_be32(bcsr1, tmp);
+ iounmap(bcsr1);
+#endif
+
pinfo->brg = 2;
}
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 1c9f7161712..7db2f37532c 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap)
/*
* Called upon match with an escc node in the devive-tree.
*/
-static int pmz_attach(struct macio_dev *mdev, const struct of_match *match)
+static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
int i;
@@ -1850,20 +1850,17 @@ err_out:
return rc;
}
-static struct of_match pmz_match[] =
+static struct of_device_id pmz_match[] =
{
{
.name = "ch-a",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
.name = "ch-b",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{},
};
+MODULE_DEVICE_TABLE (of, pmz_match);
static struct macio_driver pmz_driver =
{
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 5c4678478b1..7365d4b50b9 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
static int s3c24xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
- unsigned long flags;
int ret;
dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
port->mapbase, port->membase);
- local_irq_save(flags);
-
rx_enabled(port) = 1;
ret = request_irq(RX_IRQ(port),
@@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port)
/* the port reset code should have done the correct
* register setup for the port controls */
- local_irq_restore(flags);
return ret;
err:
s3c24xx_serial_shutdown(port);
- local_irq_restore(flags);
return ret;
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 139863a787f..54699c3a00a 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1808,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co,
struct termios termios;
int i;
+ /*
+ * Ensure that the serial console lock is initialised
+ * early.
+ */
+ spin_lock_init(&port->lock);
+
memset(&termios, 0, sizeof(struct termios));
termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2196,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
state->port = port;
- spin_lock_init(&port->lock);
port->cons = drv->cons;
port->info = state->info;
+ /*
+ * If this port is a console, then the spinlock is already
+ * initialised.
+ */
+ if (!uart_console(port))
+ spin_lock_init(&port->lock);
+
uart_configure_port(drv, state, port);
/*
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 73a34b18866..de0136cc593 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -45,7 +45,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -232,11 +231,6 @@ static dev_link_t *serial_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &serial_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -883,6 +877,7 @@ static struct pcmcia_driver serial_cs_driver = {
.name = "serial_cs",
},
.attach = serial_attach,
+ .event = serial_event,
.detach = serial_detach,
.id_table = serial_ids,
};
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index ce5ebfe4af2..57c0c6e3fbe 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -9,7 +9,6 @@
#include <linux/errno.h> /* error codes */
#include <linux/slab.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -69,11 +68,6 @@ static dev_link_t *ixj_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &ixj_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -307,6 +301,7 @@ static struct pcmcia_driver ixj_driver = {
.name = "ixj_cs",
},
.attach = ixj_attach,
+ .event = ixj_event,
.detach = ixj_detach,
.id_table = ixj_ids,
};
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index d79cd218a55..df014c2a7c5 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -65,12 +65,14 @@ obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/
obj-$(CONFIG_USB_IDMOUSE) += misc/
obj-$(CONFIG_USB_LCD) += misc/
+obj-$(CONFIG_USB_LD) += misc/
obj-$(CONFIG_USB_LED) += misc/
obj-$(CONFIG_USB_LEGOTOWER) += misc/
obj-$(CONFIG_USB_RIO500) += misc/
obj-$(CONFIG_USB_TEST) += misc/
obj-$(CONFIG_USB_USS720) += misc/
obj-$(CONFIG_USB_PHIDGETSERVO) += misc/
+obj-$(CONFIG_USB_SISUSBVGA) += misc/
obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index cbd4a7d25d0..8e184e2641c 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -427,7 +427,7 @@ static void cxacru_poll_status(struct cxacru_data *instance)
atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
atm_dev->signal = ATM_PHY_SIG_FOUND;
- dev_info(dev, "ADSL line: up (%d Kib/s down | %d Kib/s up)\n",
+ dev_info(dev, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
break;
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 6a6eaa2a3b1..d0cbbb7f038 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -100,6 +100,8 @@ struct speedtch_instance_data {
struct work_struct status_checker;
+ unsigned char last_status;
+
int poll_delay; /* milliseconds */
struct timer_list resubmit_timer;
@@ -423,52 +425,48 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
struct usbatm_data *usbatm = instance->usbatm;
struct atm_dev *atm_dev = usbatm->atm_dev;
unsigned char *buf = instance->scratch_buffer;
- int ret;
+ int down_speed, up_speed, ret;
+ unsigned char status;
atm_dbg(usbatm, "%s entered\n", __func__);
ret = speedtch_read_status(instance);
if (ret < 0) {
atm_warn(usbatm, "error %d fetching device status\n", ret);
- if (instance->poll_delay < MAX_POLL_DELAY)
- instance->poll_delay *= 2;
+ instance->poll_delay = min(2 * instance->poll_delay, MAX_POLL_DELAY);
return;
}
- if (instance->poll_delay > MIN_POLL_DELAY)
- instance->poll_delay /= 2;
+ instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY);
- atm_dbg(usbatm, "%s: line state %02x\n", __func__, buf[OFFSET_7]);
+ status = buf[OFFSET_7];
- switch (buf[OFFSET_7]) {
- case 0:
- if (atm_dev->signal != ATM_PHY_SIG_LOST) {
+ atm_dbg(usbatm, "%s: line state %02x\n", __func__, status);
+
+ if ((status != instance->last_status) || !status) {
+ switch (status) {
+ case 0:
atm_dev->signal = ATM_PHY_SIG_LOST;
- atm_info(usbatm, "ADSL line is down\n");
- /* It'll never resync again unless we ask it to... */
+ if (instance->last_status)
+ atm_info(usbatm, "ADSL line is down\n");
+ /* It may never resync again unless we ask it to... */
ret = speedtch_start_synchro(instance);
- }
- break;
+ break;
- case 0x08:
- if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
+ case 0x08:
atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
atm_info(usbatm, "ADSL line is blocked?\n");
- }
- break;
+ break;
- case 0x10:
- if (atm_dev->signal != ATM_PHY_SIG_LOST) {
+ case 0x10:
atm_dev->signal = ATM_PHY_SIG_LOST;
atm_info(usbatm, "ADSL line is synchronising\n");
- }
- break;
+ break;
- case 0x20:
- if (atm_dev->signal != ATM_PHY_SIG_FOUND) {
- int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
+ case 0x20:
+ down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
| (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
- int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
+ up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
| (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24);
if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) {
@@ -480,17 +478,17 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
atm_dev->signal = ATM_PHY_SIG_FOUND;
atm_info(usbatm,
- "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
+ "ADSL line is up (%d kb/s down | %d kb/s up)\n",
down_speed, up_speed);
- }
- break;
+ break;
- default:
- if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
+ default:
atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
- atm_info(usbatm, "Unknown line state %02x\n", buf[OFFSET_7]);
+ atm_info(usbatm, "Unknown line state %02x\n", status);
+ break;
}
- break;
+
+ instance->last_status = status;
}
}
@@ -730,6 +728,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
instance->status_checker.timer.function = speedtch_status_poll;
instance->status_checker.timer.data = (unsigned long)instance;
+ instance->last_status = 0xff;
instance->poll_delay = MIN_POLL_DELAY;
init_timer(&instance->resubmit_timer);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 69e859e0f51..adff5a77e31 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -422,6 +422,17 @@ bail_out:
return -EIO;
}
+static void acm_tty_unregister(struct acm *acm)
+{
+ tty_unregister_device(acm_tty_driver, acm->minor);
+ usb_put_intf(acm->control);
+ acm_table[acm->minor] = NULL;
+ usb_free_urb(acm->ctrlurb);
+ usb_free_urb(acm->readurb);
+ usb_free_urb(acm->writeurb);
+ kfree(acm);
+}
+
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
{
struct acm *acm = tty->driver_data;
@@ -436,14 +447,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
usb_kill_urb(acm->ctrlurb);
usb_kill_urb(acm->writeurb);
usb_kill_urb(acm->readurb);
- } else {
- tty_unregister_device(acm_tty_driver, acm->minor);
- acm_table[acm->minor] = NULL;
- usb_free_urb(acm->ctrlurb);
- usb_free_urb(acm->readurb);
- usb_free_urb(acm->writeurb);
- kfree(acm);
- }
+ } else
+ acm_tty_unregister(acm);
}
up(&open_sem);
}
@@ -905,7 +910,8 @@ skip_normal_probe:
usb_driver_claim_interface(&acm_driver, data_interface, acm);
- tty_register_device(acm_tty_driver, minor, &intf->dev);
+ usb_get_intf(control_interface);
+ tty_register_device(acm_tty_driver, minor, &control_interface->dev);
acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
@@ -954,12 +960,7 @@ static void acm_disconnect(struct usb_interface *intf)
usb_driver_release_interface(&acm_driver, acm->data);
if (!acm->used) {
- tty_unregister_device(acm_tty_driver, acm->minor);
- acm_table[acm->minor] = NULL;
- usb_free_urb(acm->ctrlurb);
- usb_free_urb(acm->readurb);
- usb_free_urb(acm->writeurb);
- kfree(acm);
+ acm_tty_unregister(acm);
up(&open_sem);
return;
}
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index b7827df21f4..fc15b4acc8a 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd)
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
- int mem_flags,
+ unsigned mem_flags,
dma_addr_t *dma
)
{
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 71b4a8d6631..fc056062c96 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -380,6 +380,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
usb_hc_died (hcd);
}
+ pci_enable_device(dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 83e732a0d64..8616356f55e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1112,7 +1112,7 @@ static void urb_unlink (struct urb *urb)
* expects usb_submit_urb() to have sanity checked and conditioned all
* inputs in the urb
*/
-static int hcd_submit_urb (struct urb *urb, int mem_flags)
+static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
{
int status;
struct usb_hcd *hcd = urb->dev->bus->hcpriv;
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 8dc13cde2f7..67db4a999b9 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -142,12 +142,12 @@ struct hcd_timeout { /* timeouts we allocate */
struct usb_operations {
int (*get_frame_number) (struct usb_device *usb_dev);
- int (*submit_urb) (struct urb *urb, int mem_flags);
+ int (*submit_urb) (struct urb *urb, unsigned mem_flags);
int (*unlink_urb) (struct urb *urb, int status);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
- int mem_flags,
+ unsigned mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
@@ -200,7 +200,7 @@ struct hc_driver {
int (*urb_enqueue) (struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- int mem_flags);
+ unsigned mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
@@ -247,7 +247,7 @@ int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
- int mem_flags, dma_addr_t *dma);
+ unsigned mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 32ff3218185..c3e46d24a37 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
#include <linux/ioctl.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
+#include <linux/kthread.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -47,8 +48,7 @@ static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */
/* Wakes up khubd */
static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
-static pid_t khubd_pid = 0; /* PID of khubd */
-static DECLARE_COMPLETION(khubd_exited);
+static struct task_struct *khubd_task;
/* cycle leds on hubs that aren't blinking for attention */
static int blinkenlights = 0;
@@ -2807,23 +2807,16 @@ loop:
static int hub_thread(void *__unused)
{
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources
- */
-
- daemonize("khubd");
- allow_signal(SIGKILL);
-
- /* Send me a signal to get me die (for debugging) */
do {
hub_events();
- wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
+ wait_event_interruptible(khubd_wait,
+ !list_empty(&hub_event_list) ||
+ kthread_should_stop());
try_to_freeze();
- } while (!signal_pending(current));
+ } while (!kthread_should_stop() || !list_empty(&hub_event_list));
- pr_debug ("%s: khubd exiting\n", usbcore_name);
- complete_and_exit(&khubd_exited, 0);
+ pr_debug("%s: khubd exiting\n", usbcore_name);
+ return 0;
}
static struct usb_device_id hub_id_table [] = {
@@ -2849,20 +2842,15 @@ static struct usb_driver hub_driver = {
int usb_hub_init(void)
{
- pid_t pid;
-
if (usb_register(&hub_driver) < 0) {
printk(KERN_ERR "%s: can't register hub driver\n",
usbcore_name);
return -1;
}
- pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL);
- if (pid >= 0) {
- khubd_pid = pid;
-
+ khubd_task = kthread_run(hub_thread, NULL, "khubd");
+ if (!IS_ERR(khubd_task))
return 0;
- }
/* Fall through if kernel_thread failed */
usb_deregister(&hub_driver);
@@ -2873,12 +2861,7 @@ int usb_hub_init(void)
void usb_hub_cleanup(void)
{
- int ret;
-
- /* Kill the thread */
- ret = kill_proc(khubd_pid, SIGKILL, 1);
-
- wait_for_completion(&khubd_exited);
+ kthread_stop(khubd_task);
/*
* Hub resources are freed for us by usb_deregister. It calls
@@ -2890,7 +2873,6 @@ void usb_hub_cleanup(void)
usb_deregister(&hub_driver);
} /* usb_hub_cleanup() */
-
static int config_descriptors_changed(struct usb_device *udev)
{
unsigned index;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index f50aaf25c98..a428ef479bd 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -320,7 +320,7 @@ int usb_sg_init (
struct scatterlist *sg,
int nents,
size_t length,
- int mem_flags
+ unsigned mem_flags
)
{
int i;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 740cb4c668d..00297f11384 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -196,6 +196,7 @@ usb_descriptor_attr (bDeviceClass, "%02x\n")
usb_descriptor_attr (bDeviceSubClass, "%02x\n")
usb_descriptor_attr (bDeviceProtocol, "%02x\n")
usb_descriptor_attr (bNumConfigurations, "%d\n")
+usb_descriptor_attr (bMaxPacketSize0, "%d\n")
static struct attribute *dev_attrs[] = {
/* current configuration's attributes */
@@ -211,6 +212,7 @@ static struct attribute *dev_attrs[] = {
&dev_attr_bDeviceSubClass.attr,
&dev_attr_bDeviceProtocol.attr,
&dev_attr_bNumConfigurations.attr,
+ &dev_attr_bMaxPacketSize0.attr,
&dev_attr_speed.attr,
&dev_attr_devnum.attr,
&dev_attr_version.attr,
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 0faf18d511d..c0feee25ff0 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb)
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
-struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
+struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags)
{
struct urb *urb;
@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb)
* GFP_NOIO, unless b) or c) apply
*
*/
-int usb_submit_urb(struct urb *urb, int mem_flags)
+int usb_submit_urb(struct urb *urb, unsigned mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index a3c42203213..99c85d2f92d 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1129,7 +1129,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
void *usb_buffer_alloc (
struct usb_device *dev,
size_t size,
- int mem_flags,
+ unsigned mem_flags,
dma_addr_t *dma
)
{
@@ -1532,6 +1532,9 @@ EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
EXPORT_SYMBOL(usb_disabled);
+EXPORT_SYMBOL_GPL(usb_get_intf);
+EXPORT_SYMBOL_GPL(usb_put_intf);
+
EXPORT_SYMBOL(usb_alloc_dev);
EXPORT_SYMBOL(usb_put_dev);
EXPORT_SYMBOL(usb_get_dev);
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 4d692670f28..583db7c38cf 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -470,7 +470,7 @@ static int dummy_disable (struct usb_ep *_ep)
}
static struct usb_request *
-dummy_alloc_request (struct usb_ep *_ep, int mem_flags)
+dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -507,7 +507,7 @@ dummy_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- int mem_flags
+ unsigned mem_flags
) {
char *retval;
struct dummy_ep *ep;
@@ -540,7 +540,8 @@ fifo_complete (struct usb_ep *ep, struct usb_request *req)
}
static int
-dummy_queue (struct usb_ep *_ep, struct usb_request *_req, int mem_flags)
+dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
+ unsigned mem_flags)
{
struct dummy_ep *ep;
struct dummy_request *req;
@@ -998,7 +999,7 @@ static int dummy_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
) {
struct dummy *dum;
struct urbp *urbp;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 5bb53ae8896..8509e955007 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -945,15 +945,16 @@ config_buf (enum usb_device_speed speed,
/*-------------------------------------------------------------------------*/
-static void eth_start (struct eth_dev *dev, int gfp_flags);
-static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags);
+static void eth_start (struct eth_dev *dev, unsigned gfp_flags);
+static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags);
static int
-set_ether_config (struct eth_dev *dev, int gfp_flags)
+set_ether_config (struct eth_dev *dev, unsigned gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
+#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
/* status endpoint used for RNDIS and (optionally) CDC */
if (!subset_active(dev) && dev->status_ep) {
dev->status = ep_desc (gadget, &hs_status_desc,
@@ -967,6 +968,7 @@ set_ether_config (struct eth_dev *dev, int gfp_flags)
goto done;
}
}
+#endif
dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
dev->in_ep->driver_data = dev;
@@ -1079,7 +1081,7 @@ static void eth_reset_config (struct eth_dev *dev)
* that returns config descriptors, and altsetting code.
*/
static int
-eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
+eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
@@ -1596,7 +1598,7 @@ static void defer_kevent (struct eth_dev *dev, int flag)
static void rx_complete (struct usb_ep *ep, struct usb_request *req);
static int
-rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
+rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags)
{
struct sk_buff *skb;
int retval = -ENOMEM;
@@ -1722,7 +1724,7 @@ clean:
}
static int prealloc (struct list_head *list, struct usb_ep *ep,
- unsigned n, int gfp_flags)
+ unsigned n, unsigned gfp_flags)
{
unsigned i;
struct usb_request *req;
@@ -1761,7 +1763,7 @@ extra:
return 0;
}
-static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags)
+static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags)
{
int status;
@@ -1777,7 +1779,7 @@ fail:
return status;
}
-static void rx_fill (struct eth_dev *dev, int gfp_flags)
+static void rx_fill (struct eth_dev *dev, unsigned gfp_flags)
{
struct usb_request *req;
unsigned long flags;
@@ -2022,7 +2024,7 @@ static int rndis_control_ack (struct net_device *net)
#endif /* RNDIS */
-static void eth_start (struct eth_dev *dev, int gfp_flags)
+static void eth_start (struct eth_dev *dev, unsigned gfp_flags)
{
DEBUG (dev, "%s\n", __FUNCTION__);
@@ -2428,7 +2430,7 @@ autoconf_fail:
dev->req->complete = eth_setup_complete;
/* ... and maybe likewise for status transfer */
-#ifdef DEV_CONFIG_CDC
+#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
if (dev->status_ep) {
dev->stat_req = eth_req_alloc (dev->status_ep,
STATUS_BYTECOUNT, GFP_KERNEL);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index ed773a9111d..eaab26f4ed3 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-goku_alloc_request(struct usb_ep *_ep, int gfp_flags)
+goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
{
struct goku_request *req;
@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, int gfp_flags)
+ dma_addr_t *dma, unsigned gfp_flags)
{
void *retval;
struct goku_ep *ep;
@@ -789,7 +789,7 @@ finished:
/*-------------------------------------------------------------------------*/
static int
-goku_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
{
struct goku_request *req;
struct goku_ep *ep;
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index df75ab65a5e..4842577789c 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -1106,7 +1106,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep)
}
static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
- int gfp_flags)
+ unsigned gfp_flags)
{
struct lh7a40x_request *req;
@@ -1134,7 +1134,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
}
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
- dma_addr_t * dma, int gfp_flags)
+ dma_addr_t * dma, unsigned gfp_flags)
{
char *retval;
@@ -1158,7 +1158,7 @@ static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma,
* NOTE: Sets INDEX register
*/
static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
- int gfp_flags)
+ unsigned gfp_flags)
{
struct lh7a40x_request *req;
struct lh7a40x_ep *ep;
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 13a3dbc9949..477fab2e74d 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-net2280_alloc_request (struct usb_ep *_ep, int gfp_flags)
+net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
{
struct net2280_ep *ep;
struct net2280_request *req;
@@ -463,7 +463,7 @@ net2280_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- int gfp_flags
+ unsigned gfp_flags
)
{
void *retval;
@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2280_request *req, int status)
/*-------------------------------------------------------------------------*/
static int
-net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
{
struct net2280_request *req;
struct net2280_ep *ep;
@@ -1490,7 +1490,7 @@ show_registers (struct device *_dev, struct device_attribute *attr, char *buf)
unsigned long flags;
int i;
u32 t1, t2;
- char *s;
+ const char *s;
dev = dev_get_drvdata (_dev);
next = buf;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index a2b812af6e6..ff5533e6956 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -269,7 +269,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
/*-------------------------------------------------------------------------*/
static struct usb_request *
-omap_alloc_request(struct usb_ep *ep, int gfp_flags)
+omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags)
{
struct omap_req *req;
@@ -298,7 +298,7 @@ omap_alloc_buffer(
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
- int gfp_flags
+ unsigned gfp_flags
)
{
void *retval;
@@ -937,7 +937,7 @@ static void dma_channel_release(struct omap_ep *ep)
/*-------------------------------------------------------------------------*/
static int
-omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
{
struct omap_ep *ep = container_of(_ep, struct omap_ep, ep);
struct omap_req *req = container_of(_req, struct omap_req, req);
@@ -2908,6 +2908,7 @@ static int __exit omap_udc_remove(struct device *dev)
* make host resumes and VBUS detection trigger OMAP wakeup events; that
* may involve talking to an external transceiver (e.g. isp1301).
*/
+
static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
{
u32 devstat;
@@ -2936,8 +2937,6 @@ static int omap_udc_resume(struct device *dev, u32 level)
return 0;
DBG("resume + wakeup/SRP\n");
- udc->gadget.dev.parent->power.power_state = PMSG_ON;
- udc->gadget.dev.power.power_state = PMSG_ON;
omap_pullup(&udc->gadget, 1);
/* maybe the host would enumerate us if we nudged it */
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 6a0b957af33..1507738337c 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -332,7 +332,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
* pxa2xx_ep_alloc_request - allocate a request data structure
*/
static struct usb_request *
-pxa2xx_ep_alloc_request (struct usb_ep *_ep, int gfp_flags)
+pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
{
struct pxa2xx_request *req;
@@ -367,7 +367,7 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
*/
static void *
pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
- dma_addr_t *dma, int gfp_flags)
+ dma_addr_t *dma, unsigned gfp_flags)
{
char *retval;
@@ -874,7 +874,7 @@ done:
/*-------------------------------------------------------------------------*/
static int
-pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
{
struct pxa2xx_request *req;
struct pxa2xx_ep *ep;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index a6e035e2447..bb9b2d94eed 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -612,7 +612,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
}
static struct usb_request *
-source_sink_start_ep (struct usb_ep *ep, int gfp_flags)
+source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
{
struct usb_request *req;
int status;
@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep, int gfp_flags)
}
static int
-set_source_sink_config (struct zero_dev *dev, int gfp_flags)
+set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -744,7 +744,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
}
static int
-set_loopback_config (struct zero_dev *dev, int gfp_flags)
+set_loopback_config (struct zero_dev *dev, unsigned gfp_flags)
{
int result = 0;
struct usb_ep *ep;
@@ -845,7 +845,7 @@ static void zero_reset_config (struct zero_dev *dev)
* by limiting configuration choices (like the pxa2xx).
*/
static int
-zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
+zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 35248a37b71..149b13fc0a7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -960,7 +960,7 @@ static int ehci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
) {
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct list_head qtd_list;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 45d89a7083b..d74b2d68a50 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -898,7 +898,7 @@ submit_async (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- int mem_flags
+ unsigned mem_flags
) {
struct ehci_qtd *qtd;
int epnum;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index c2104cad403..9af4f64532a 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -588,7 +588,7 @@ static int intr_submit (
struct usb_host_endpoint *ep,
struct urb *urb,
struct list_head *qtd_list,
- int mem_flags
+ unsigned mem_flags
) {
unsigned epnum;
unsigned long flags;
@@ -633,7 +633,7 @@ done:
/* ehci_iso_stream ops work with both ITD and SITD */
static struct ehci_iso_stream *
-iso_stream_alloc (int mem_flags)
+iso_stream_alloc (unsigned mem_flags)
{
struct ehci_iso_stream *stream;
@@ -846,7 +846,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
/* ehci_iso_sched ops can be ITD-only or SITD-only */
static struct ehci_iso_sched *
-iso_sched_alloc (unsigned packets, int mem_flags)
+iso_sched_alloc (unsigned packets, unsigned mem_flags)
{
struct ehci_iso_sched *iso_sched;
int size = sizeof *iso_sched;
@@ -919,7 +919,7 @@ itd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
)
{
struct ehci_itd *itd;
@@ -1412,7 +1412,8 @@ itd_complete (
/*-------------------------------------------------------------------------*/
-static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
+ unsigned mem_flags)
{
int status = -EINVAL;
unsigned long flags;
@@ -1523,7 +1524,7 @@ sitd_urb_transaction (
struct ehci_iso_stream *stream,
struct ehci_hcd *ehci,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
)
{
struct ehci_sitd *sitd;
@@ -1772,7 +1773,8 @@ sitd_complete (
}
-static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
+ unsigned mem_flags)
{
int status = -EINVAL;
unsigned long flags;
@@ -1822,7 +1824,8 @@ done:
#else
static inline int
-sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
+ unsigned mem_flags)
{
ehci_dbg (ehci, "split iso support is disabled\n");
return -ENOSYS;
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index d9883d774d3..81f8f6b7fdc 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -463,7 +463,8 @@ static void etrax_usb_free_epid(int epid);
static int etrax_remove_from_sb_list(struct urb *urb);
-static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma);
+static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
+ unsigned mem_flags, dma_addr_t *dma);
static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma);
static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid);
@@ -476,7 +477,7 @@ static int etrax_usb_submit_ctrl_urb(struct urb *urb);
static int etrax_usb_submit_intr_urb(struct urb *urb);
static int etrax_usb_submit_isoc_urb(struct urb *urb);
-static int etrax_usb_submit_urb(struct urb *urb, int mem_flags);
+static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags);
static int etrax_usb_unlink_urb(struct urb *urb, int status);
static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
@@ -1262,7 +1263,7 @@ static int etrax_usb_allocate_epid(void)
return -1;
}
-static int etrax_usb_submit_urb(struct urb *urb, int mem_flags)
+static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags)
{
etrax_hc_t *hc;
int ret = -EINVAL;
@@ -4277,7 +4278,8 @@ etrax_usb_bulk_eot_timer_func(unsigned long dummy)
}
static void*
-etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma)
+etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
+ unsigned mem_flags, dma_addr_t *dma)
{
return kmalloc(size, mem_flags);
}
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index ff0a168e8ee..50b1970fe6b 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -17,7 +17,7 @@
* The driver basically works. A number of people have used it with a range
* of devices.
*
- *The driver passes all usbtests 1-14.
+ * The driver passes all usbtests 1-14.
*
* Suspending/resuming of root hub via sysfs works. Remote wakeup works too.
* And suspending/resuming of platform device works too. Suspend/resume
@@ -229,7 +229,7 @@ static void preproc_atl_queue(struct isp116x *isp116x)
struct isp116x_ep *ep;
struct urb *urb;
struct ptd *ptd;
- u16 toggle, dir, len;
+ u16 toggle = 0, dir = PTD_DIR_SETUP, len;
for (ep = isp116x->atl_active; ep; ep = ep->active) {
BUG_ON(list_empty(&ep->hep->urb_list));
@@ -251,8 +251,6 @@ static void preproc_atl_queue(struct isp116x *isp116x)
dir = PTD_DIR_OUT;
break;
case USB_PID_SETUP:
- toggle = 0;
- dir = PTD_DIR_SETUP;
len = sizeof(struct usb_ctrlrequest);
ep->data = urb->setup_packet;
break;
@@ -264,11 +262,9 @@ static void preproc_atl_queue(struct isp116x *isp116x)
? PTD_DIR_OUT : PTD_DIR_IN;
break;
default:
- /* To please gcc */
- toggle = dir = 0;
ERR("%s %d: ep->nextpid %d\n", __func__, __LINE__,
ep->nextpid);
- BUG_ON(1);
+ BUG();
}
ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
@@ -697,7 +693,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load)
static int isp116x_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *hep, struct urb *urb,
- int mem_flags)
+ unsigned mem_flags)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
struct usb_device *udev = urb->dev;
@@ -719,7 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
}
/* avoid all allocations within spinlocks: request or endpoint */
if (!hep->hcpriv) {
- ep = kcalloc(1, sizeof *ep, (__force unsigned)mem_flags);
+ ep = kcalloc(1, sizeof *ep, mem_flags);
if (!ep)
return -ENOMEM;
}
@@ -1054,7 +1050,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
break;
case GetHubStatus:
DBG("GetHubStatus\n");
- *(__le32 *) buf = cpu_to_le32(0);
+ *(__le32 *) buf = 0;
break;
case GetPortStatus:
DBG("GetPortStatus\n");
@@ -1810,9 +1806,9 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
ret = usb_suspend_device(hcd->self.root_hub, state);
if (!ret) {
dev->power.power_state = state;
- INFO("%s suspended\n", (char *)hcd_name);
+ INFO("%s suspended\n", hcd_name);
} else
- ERR("%s suspend failed\n", (char *)hcd_name);
+ ERR("%s suspend failed\n", hcd_name);
return ret;
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 13cd2177b55..68decab280d 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -180,7 +180,7 @@ static int ohci_urb_enqueue (
struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ed *ed;
@@ -673,8 +673,10 @@ retry:
ohci_dump (ohci, 1);
- if (ohci_to_hcd(ohci)->self.root_hub == NULL)
+ if (ohci_to_hcd(ohci)->self.root_hub == NULL) {
+ register_reboot_notifier (&ohci->reboot_notifier);
create_debug_files (ohci);
+ }
return 0;
}
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index e2fc4129dfc..83ca4549a50 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -419,10 +419,11 @@ ohci_hub_descriptor (
/* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
rh = roothub_b (ohci);
+ memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
desc->bitmap [0] = rh & RH_B_DR;
if (ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
- desc->bitmap [2] = desc->bitmap [3] = 0xff;
+ desc->bitmap [2] = 0xff;
} else
desc->bitmap [1] = 0xff;
}
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index 23735a36af0..fd3c4d3714b 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -84,7 +84,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
/* TDs ... */
static struct td *
-td_alloc (struct ohci_hcd *hc, int mem_flags)
+td_alloc (struct ohci_hcd *hc, unsigned mem_flags)
{
dma_addr_t dma;
struct td *td;
@@ -118,7 +118,7 @@ td_free (struct ohci_hcd *hc, struct td *td)
/* EDs ... */
static struct ed *
-ed_alloc (struct ohci_hcd *hc, int mem_flags)
+ed_alloc (struct ohci_hcd *hc, unsigned mem_flags)
{
dma_addr_t dma;
struct ed *ed;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index b62d6993769..5cde76faab9 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -456,34 +456,22 @@ static int ohci_hcd_omap_drv_remove(struct device *dev)
#ifdef CONFIG_PM
-/* states match PCI usage, always suspending the root hub except that
- * 4 ~= D3cold (ACPI D3) with clock off (resume sees reset).
- *
- * FIXME: above comment is not right, and code is wrong, too :-(.
- */
-
-static int ohci_omap_suspend(struct device *dev, pm_message_t state, u32 level)
+static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level)
{
struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev));
int status = -EINVAL;
if (level != SUSPEND_POWER_DOWN)
return 0;
- if (state <= dev->power.power_state)
- return 0;
- dev_dbg(dev, "suspend to %d\n", state);
down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
status = ohci_hub_suspend(ohci_to_hcd(ohci));
if (status == 0) {
- if (state >= 4) {
- omap_ohci_clock_power(0);
- ohci_to_hcd(ohci)->self.root_hub->state =
- USB_STATE_SUSPENDED;
- state = 4;
- }
+ omap_ohci_clock_power(0);
+ ohci_to_hcd(ohci)->self.root_hub->state =
+ USB_STATE_SUSPENDED;
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
- dev->power.power_state = state;
+ dev->power.power_state = PMSG_SUSPEND;
}
up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
return status;
@@ -497,29 +485,20 @@ static int ohci_omap_resume(struct device *dev, u32 level)
if (level != RESUME_POWER_ON)
return 0;
- switch (dev->power.power_state) {
- case 0:
- break;
- case 4:
- if (time_before(jiffies, ohci->next_statechange))
- msleep(5);
- ohci->next_statechange = jiffies;
- omap_ohci_clock_power(1);
- /* FALLTHROUGH */
- default:
- dev_dbg(dev, "resume from %d\n", dev->power.power_state);
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+ omap_ohci_clock_power(1);
#ifdef CONFIG_USB_SUSPEND
- /* get extra cleanup even if remote wakeup isn't in use */
- status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
+ /* get extra cleanup even if remote wakeup isn't in use */
+ status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
#else
- down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
- status = ohci_hub_resume(ohci_to_hcd(ohci));
- up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+ down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+ status = ohci_hub_resume(ohci_to_hcd(ohci));
+ up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
#endif
- if (status == 0)
- dev->power.power_state = 0;
- break;
- }
+ if (status == 0)
+ dev->power.power_state = PMSG_ON;
return status;
}
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 6c3f910bc30..7a890a65f55 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -815,7 +815,7 @@ static int sl811h_urb_enqueue(
struct usb_hcd *hcd,
struct usb_host_endpoint *hep,
struct urb *urb,
- int mem_flags
+ unsigned mem_flags
) {
struct sl811 *sl811 = hcd_to_sl811(hcd);
struct usb_device *udev = urb->dev;
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 269d8ef0145..38aebe361ca 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -20,7 +20,6 @@
#include <linux/timer.h>
#include <linux/ioport.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -389,11 +388,6 @@ static dev_link_t *sl811_cs_attach(void)
dev_list = link;
client_reg.dev_info = (dev_info_t *) &driver_name;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &sl811_cs_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -418,6 +412,7 @@ static struct pcmcia_driver sl811_cs_driver = {
.name = (char *)driver_name,
},
.attach = sl811_cs_attach,
+ .event = sl811_cs_event,
.detach = sl811_cs_detach,
.id_table = sl811_ids,
};
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 5f18084a116..bbb36cd6ed6 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1164,7 +1164,7 @@ static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb)
static int uhci_urb_enqueue(struct usb_hcd *hcd,
struct usb_host_endpoint *ep,
- struct urb *urb, int mem_flags)
+ struct urb *urb, unsigned mem_flags)
{
int ret;
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index fd59f6bdd67..298e4a25e3d 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -259,3 +259,16 @@ config USB_ATI_REMOTE
To compile this driver as a module, choose M here: the module will be
called ati_remote.
+config USB_KEYSPAN_REMOTE
+ tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
+ depends on USB && INPUT && EXPERIMENTAL
+ ---help---
+ Say Y here if you want to use a Keyspan DMR USB remote control.
+ Currently only the UIA-11 type of receiver has been tested. The tag
+ on the receiver that connects to the USB port should have a P/N that
+ will tell you what type of DMR you have. The UIA-10 type is not
+ supported at this time. This driver maps all buttons to keypress
+ events.
+
+ To compile this driver as a module, choose M here: the module will
+ be called keyspan_remote.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 831b2b0f1f0..f1547be632d 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_USB_HID) += usbhid.o
obj-$(CONFIG_USB_KBD) += usbkbd.o
obj-$(CONFIG_USB_KBTAB) += kbtab.o
+obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.o
obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o
obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 100b49bd1d3..2350e7a5ad7 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1428,6 +1428,19 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
+#define USB_VENDOR_ID_LD 0x0f11
+#define USB_DEVICE_ID_CASSY 0x1000
+#define USB_DEVICE_ID_POCKETCASSY 0x1010
+#define USB_DEVICE_ID_MOBILECASSY 0x1020
+#define USB_DEVICE_ID_JWM 0x1080
+#define USB_DEVICE_ID_DMMP 0x1081
+#define USB_DEVICE_ID_UMIP 0x1090
+#define USB_DEVICE_ID_VIDEOCOM 0x1200
+#define USB_DEVICE_ID_COM3LAB 0x2000
+#define USB_DEVICE_ID_TELEPORT 0x2010
+#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
+#define USB_DEVICE_ID_POWERCONTROL 0x2030
+
/*
* Alphabetically sorted blacklist by quirk type.
@@ -1463,6 +1476,17 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
new file mode 100644
index 00000000000..67dc9368520
--- /dev/null
+++ b/drivers/usb/input/keyspan_remote.c
@@ -0,0 +1,633 @@
+/*
+ * keyspan_remote: USB driver for the Keyspan DMR
+ *
+ * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ * This driver has been put together with the support of Innosys, Inc.
+ * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#define DRIVER_VERSION "v0.1"
+#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
+#define DRIVER_DESC "Driver for the USB Keyspan remote control."
+#define DRIVER_LICENSE "GPL"
+
+/* Parameters that can be passed to the driver. */
+static int debug;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
+
+/* Vendor and product ids */
+#define USB_KEYSPAN_VENDOR_ID 0x06CD
+#define USB_KEYSPAN_PRODUCT_UIA11 0x0202
+
+/* Defines for converting the data from the remote. */
+#define ZERO 0x18
+#define ZERO_MASK 0x1F /* 5 bits for a 0 */
+#define ONE 0x3C
+#define ONE_MASK 0x3F /* 6 bits for a 1 */
+#define SYNC 0x3F80
+#define SYNC_MASK 0x3FFF /* 14 bits for a SYNC sequence */
+#define STOP 0x00
+#define STOP_MASK 0x1F /* 5 bits for the STOP sequence */
+#define GAP 0xFF
+
+#define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */
+
+/* table of devices that work with this driver */
+static struct usb_device_id keyspan_table[] = {
+ { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
+ { } /* Terminating entry */
+};
+
+/* Structure to store all the real stuff that a remote sends to us. */
+struct keyspan_message {
+ u16 system;
+ u8 button;
+ u8 toggle;
+};
+
+/* Structure used for all the bit testing magic needed to be done. */
+struct bit_tester {
+ u32 tester;
+ int len;
+ int pos;
+ int bits_left;
+ u8 buffer[32];
+};
+
+/* Structure to hold all of our driver specific stuff */
+struct usb_keyspan {
+ char name[128];
+ char phys[64];
+ struct usb_device* udev;
+ struct input_dev input;
+ struct usb_interface* interface;
+ struct usb_endpoint_descriptor* in_endpoint;
+ struct urb* irq_urb;
+ int open;
+ dma_addr_t in_dma;
+ unsigned char* in_buffer;
+
+ /* variables used to parse messages from remote. */
+ struct bit_tester data;
+ int stage;
+ int toggle;
+};
+
+/*
+ * Table that maps the 31 possible keycodes to input keys.
+ * Currently there are 15 and 17 button models so RESERVED codes
+ * are blank areas in the mapping.
+ */
+static int keyspan_key_table[] = {
+ KEY_RESERVED, /* 0 is just a place holder. */
+ KEY_RESERVED,
+ KEY_STOP,
+ KEY_PLAYCD,
+ KEY_RESERVED,
+ KEY_PREVIOUSSONG,
+ KEY_REWIND,
+ KEY_FORWARD,
+ KEY_NEXTSONG,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_PAUSE,
+ KEY_VOLUMEUP,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_VOLUMEDOWN,
+ KEY_RESERVED,
+ KEY_UP,
+ KEY_RESERVED,
+ KEY_MUTE,
+ KEY_LEFT,
+ KEY_ENTER,
+ KEY_RIGHT,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_DOWN,
+ KEY_RESERVED,
+ KEY_KPASTERISK,
+ KEY_RESERVED,
+ KEY_MENU
+};
+
+static struct usb_driver keyspan_driver;
+
+/*
+ * Debug routine that prints out what we've received from the remote.
+ */
+static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
+{
+ char codes[4*RECV_SIZE];
+ int i;
+
+ for (i = 0; i < RECV_SIZE; i++) {
+ snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
+ }
+
+ dev_info(&dev->udev->dev, "%s\n", codes);
+}
+
+/*
+ * Routine that manages the bit_tester structure. It makes sure that there are
+ * at least bits_needed bits loaded into the tester.
+ */
+static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
+{
+ if (dev->data.bits_left >= bits_needed)
+ return(0);
+
+ /*
+ * Somehow we've missed the last message. The message will be repeated
+ * though so it's not too big a deal
+ */
+ if (dev->data.pos >= dev->data.len) {
+ dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
+ __FUNCTION__, dev->data.pos, dev->data.len);
+ return(-1);
+ }
+
+ /* Load as much as we can into the tester. */
+ while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&
+ (dev->data.pos < dev->data.len)) {
+ dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);
+ dev->data.bits_left += 8;
+ }
+
+ return(0);
+}
+
+/*
+ * Routine that handles all the logic needed to parse out the message from the remote.
+ */
+static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
+{
+ int i;
+ int found = 0;
+ struct keyspan_message message;
+
+ switch(remote->stage) {
+ case 0:
+ /*
+ * In stage 0 we want to find the start of a message. The remote sends a 0xFF as filler.
+ * So the first byte that isn't a FF should be the start of a new message.
+ */
+ for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i);
+
+ if (i < RECV_SIZE) {
+ memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);
+ remote->data.len = RECV_SIZE;
+ remote->data.pos = 0;
+ remote->data.tester = 0;
+ remote->data.bits_left = 0;
+ remote->stage = 1;
+ }
+ break;
+
+ case 1:
+ /*
+ * Stage 1 we should have 16 bytes and should be able to detect a
+ * SYNC. The SYNC is 14 bits, 7 0's and then 7 1's.
+ */
+ memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+ remote->data.len += RECV_SIZE;
+
+ found = 0;
+ while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {
+ for (i = 0; i < 8; ++i) {
+ if (keyspan_load_tester(remote, 14) != 0) {
+ remote->stage = 0;
+ return;
+ }
+
+ if ((remote->data.tester & SYNC_MASK) == SYNC) {
+ remote->data.tester = remote->data.tester >> 14;
+ remote->data.bits_left -= 14;
+ found = 1;
+ break;
+ } else {
+ remote->data.tester = remote->data.tester >> 1;
+ --remote->data.bits_left;
+ }
+ }
+ }
+
+ if (!found) {
+ remote->stage = 0;
+ remote->data.len = 0;
+ } else {
+ remote->stage = 2;
+ }
+ break;
+
+ case 2:
+ /*
+ * Stage 2 we should have 24 bytes which will be enough for a full
+ * message. We need to parse out the system code, button code,
+ * toggle code, and stop.
+ */
+ memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+ remote->data.len += RECV_SIZE;
+
+ message.system = 0;
+ for (i = 0; i < 9; i++) {
+ keyspan_load_tester(remote, 6);
+
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.system = message.system << 1;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.system = (message.system << 1) + 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
+ remote->stage = 0;
+ return;
+ }
+ }
+
+ message.button = 0;
+ for (i = 0; i < 5; i++) {
+ keyspan_load_tester(remote, 6);
+
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.button = message.button << 1;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.button = (message.button << 1) + 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
+ remote->stage = 0;
+ return;
+ }
+ }
+
+ keyspan_load_tester(remote, 6);
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.toggle = 0;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.toggle = 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
+ }
+
+ keyspan_load_tester(remote, 5);
+ if ((remote->data.tester & STOP_MASK) == STOP) {
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else {
+ err("Bad message recieved, no stop bit found.\n");
+ }
+
+ dev_dbg(&remote->udev,
+ "%s found valid message: system: %d, button: %d, toggle: %d\n",
+ __FUNCTION__, message.system, message.button, message.toggle);
+
+ if (message.toggle != remote->toggle) {
+ input_regs(&remote->input, regs);
+ input_report_key(&remote->input, keyspan_key_table[message.button], 1);
+ input_report_key(&remote->input, keyspan_key_table[message.button], 0);
+ input_sync(&remote->input);
+ remote->toggle = message.toggle;
+ }
+
+ remote->stage = 0;
+ break;
+ }
+}
+
+/*
+ * Routine for sending all the initialization messages to the remote.
+ */
+static int keyspan_setup(struct usb_device* dev)
+{
+ int retval = 0;
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
+ return(retval);
+}
+
+/*
+ * Routine used to handle a new message that has come in.
+ */
+static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_keyspan *dev = urb->context;
+ int retval;
+
+ /* Check our status in case we need to bail out early. */
+ switch (urb->status) {
+ case 0:
+ break;
+
+ /* Device went away so don't keep trying to read from it. */
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ goto resubmit;
+ break;
+ }
+
+ if (debug)
+ keyspan_print(dev);
+
+ keyspan_check_data(dev, regs);
+
+resubmit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
+}
+
+static int keyspan_open(struct input_dev *dev)
+{
+ struct usb_keyspan *remote = dev->private;
+
+ if (remote->open++)
+ return 0;
+
+ remote->irq_urb->dev = remote->udev;
+ if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
+ remote->open--;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void keyspan_close(struct input_dev *dev)
+{
+ struct usb_keyspan *remote = dev->private;
+
+ if (!--remote->open)
+ usb_kill_urb(remote->irq_urb);
+}
+
+/*
+ * Routine that sets up the driver to handle a specific USB device detected on the bus.
+ */
+static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+ int i;
+ int retval = -ENOMEM;
+ char path[64];
+ char *buf;
+ struct usb_keyspan *remote = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* See if the offered device matches what we can accept */
+ if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
+ (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
+ return -ENODEV;
+
+ /* allocate memory for our device state and initialize it */
+ remote = kmalloc(sizeof(*remote), GFP_KERNEL);
+ if (remote == NULL) {
+ err("Out of memory\n");
+ goto error;
+ }
+ memset(remote, 0x00, sizeof(*remote));
+
+ remote->udev = udev;
+ remote->interface = interface;
+ remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
+
+ /* set up the endpoint information */
+ /* use only the first in interrupt endpoint */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!remote->in_endpoint &&
+ (endpoint->bEndpointAddress & USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+ /* we found our interrupt in endpoint */
+ remote->in_endpoint = endpoint;
+
+ remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+ if (!remote->in_buffer) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ }
+ }
+
+ if (!remote->in_endpoint) {
+ err("Could not find interrupt input endpoint.\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!remote->irq_urb) {
+ err("Failed to allocate urb.\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ retval = keyspan_setup(remote->udev);
+ if (retval) {
+ err("Failed to setup device.\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /*
+ * Setup the input system with the bits we are going to be reporting
+ */
+ remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
+ for (i = 0; i < 32; ++i) {
+ if (keyspan_key_table[i] != KEY_RESERVED) {
+ set_bit(keyspan_key_table[i], remote->input.keybit);
+ }
+ }
+
+ remote->input.private = remote;
+ remote->input.open = keyspan_open;
+ remote->input.close = keyspan_close;
+
+ usb_make_path(remote->udev, path, 64);
+ sprintf(remote->phys, "%s/input0", path);
+
+ remote->input.name = remote->name;
+ remote->input.phys = remote->phys;
+ remote->input.id.bustype = BUS_USB;
+ remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
+ remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
+ remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
+
+ if (!(buf = kmalloc(63, GFP_KERNEL))) {
+ usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ kfree(remote);
+ return -ENOMEM;
+ }
+
+ if (remote->udev->descriptor.iManufacturer &&
+ usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
+ strcat(remote->name, buf);
+
+ if (remote->udev->descriptor.iProduct &&
+ usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
+ sprintf(remote->name, "%s %s", remote->name, buf);
+
+ if (!strlen(remote->name))
+ sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
+ remote->input.id.vendor, remote->input.id.product);
+
+ kfree(buf);
+
+ /*
+ * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
+ */
+ usb_fill_int_urb(remote->irq_urb,
+ remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress),
+ remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote,
+ remote->in_endpoint->bInterval);
+ remote->irq_urb->transfer_dma = remote->in_dma;
+ remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ /* we can register the device now, as it is ready */
+ input_register_device(&remote->input);
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, remote);
+
+ /* let the user know what node this device is now attached to */
+ info("connected: %s on %s", remote->name, path);
+ return 0;
+
+error:
+ /*
+ * In case of error we need to clean up any allocated buffers
+ */
+ if (remote->irq_urb)
+ usb_free_urb(remote->irq_urb);
+
+ if (remote->in_buffer)
+ usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+
+ if (remote)
+ kfree(remote);
+
+ return retval;
+}
+
+/*
+ * Routine called when a device is disconnected from the USB.
+ */
+static void keyspan_disconnect(struct usb_interface *interface)
+{
+ struct usb_keyspan *remote;
+
+ /* prevent keyspan_open() from racing keyspan_disconnect() */
+ lock_kernel();
+
+ remote = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ if (remote) { /* We have a valid driver structure so clean up everything we allocated. */
+ input_unregister_device(&remote->input);
+ usb_kill_urb(remote->irq_urb);
+ usb_free_urb(remote->irq_urb);
+ usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+ kfree(remote);
+ }
+
+ unlock_kernel();
+
+ info("USB Keyspan now disconnected");
+}
+
+/*
+ * Standard driver set up sections
+ */
+static struct usb_driver keyspan_driver =
+{
+ .owner = THIS_MODULE,
+ .name = "keyspan_remote",
+ .probe = keyspan_probe,
+ .disconnect = keyspan_disconnect,
+ .id_table = keyspan_table
+};
+
+static int __init usb_keyspan_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&keyspan_driver);
+ if (result)
+ err("usb_register failed. Error number %d\n", result);
+
+ return result;
+}
+
+static void __exit usb_keyspan_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&keyspan_driver);
+}
+
+module_init(usb_keyspan_init);
+module_exit(usb_keyspan_exit);
+
+MODULE_DEVICE_TABLE(usb, keyspan_table);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
index 2b76df7005f..d83adffa925 100644
--- a/drivers/usb/media/Makefile
+++ b/drivers/usb/media/Makefile
@@ -2,7 +2,7 @@
# Makefile for USB Media drivers
#
-sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
+sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
index 8b8a4c8743f..e5cea0e2eb5 100644
--- a/drivers/usb/media/sn9c102.h
+++ b/drivers/usb/media/sn9c102.h
@@ -56,7 +56,7 @@
#define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.24"
+#define SN9C102_MODULE_VERSION "1:1.24a"
#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24)
enum sn9c102_bridge {
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index 31d57400d5b..cf8cfbabefd 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -429,7 +429,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
}
-static int
+int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
struct sn9c102_sensor* sensor, u8 address, u8 value)
{
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c
new file mode 100644
index 00000000000..d27c5aedeaf
--- /dev/null
+++ b/drivers/usb/media/sn9c102_ov7630.c
@@ -0,0 +1,394 @@
+/***************************************************************************
+ * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static struct sn9c102_sensor ov7630;
+
+
+static int ov7630_init(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ err += sn9c102_write_reg(cam, 0x00, 0x14);
+ err += sn9c102_write_reg(cam, 0x60, 0x17);
+ err += sn9c102_write_reg(cam, 0x0f, 0x18);
+ err += sn9c102_write_reg(cam, 0x50, 0x19);
+
+ err += sn9c102_i2c_write(cam, 0x12, 0x8d);
+ err += sn9c102_i2c_write(cam, 0x11, 0x00);
+ err += sn9c102_i2c_write(cam, 0x15, 0x34);
+ err += sn9c102_i2c_write(cam, 0x16, 0x03);
+ err += sn9c102_i2c_write(cam, 0x17, 0x1c);
+ err += sn9c102_i2c_write(cam, 0x18, 0xbd);
+ err += sn9c102_i2c_write(cam, 0x19, 0x06);
+ err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
+ err += sn9c102_i2c_write(cam, 0x1b, 0x04);
+ err += sn9c102_i2c_write(cam, 0x20, 0x44);
+ err += sn9c102_i2c_write(cam, 0x23, 0xee);
+ err += sn9c102_i2c_write(cam, 0x26, 0xa0);
+ err += sn9c102_i2c_write(cam, 0x27, 0x9a);
+ err += sn9c102_i2c_write(cam, 0x28, 0x20);
+ err += sn9c102_i2c_write(cam, 0x29, 0x30);
+ err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
+ err += sn9c102_i2c_write(cam, 0x30, 0x24);
+ err += sn9c102_i2c_write(cam, 0x32, 0x86);
+ err += sn9c102_i2c_write(cam, 0x60, 0xa9);
+ err += sn9c102_i2c_write(cam, 0x61, 0x42);
+ err += sn9c102_i2c_write(cam, 0x65, 0x00);
+ err += sn9c102_i2c_write(cam, 0x69, 0x38);
+ err += sn9c102_i2c_write(cam, 0x6f, 0x88);
+ err += sn9c102_i2c_write(cam, 0x70, 0x0b);
+ err += sn9c102_i2c_write(cam, 0x71, 0x00);
+ err += sn9c102_i2c_write(cam, 0x74, 0x21);
+ err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
+
+ return err;
+}
+
+
+static int ov7630_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2);
+ err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x02, ctrl->value);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x03, ctrl->value);
+ break;
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+ break;
+ case V4L2_CID_CONTRAST:
+ err += ctrl->value ? sn9c102_i2c_write(cam, 0x05,
+ (ctrl->value-1) | 0x20)
+ : sn9c102_i2c_write(cam, 0x05, 0x00);
+ break;
+ case V4L2_CID_BRIGHTNESS:
+ err += sn9c102_i2c_write(cam, 0x06, ctrl->value);
+ break;
+ case V4L2_CID_SATURATION:
+ err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4);
+ break;
+ case V4L2_CID_HUE:
+ err += ctrl->value ? sn9c102_i2c_write(cam, 0x04,
+ (ctrl->value-1) | 0x20)
+ : sn9c102_i2c_write(cam, 0x04, 0x00);
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
+ break;
+ case V4L2_CID_WHITENESS:
+ err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x09);
+ break;
+ case V4L2_CID_AUTOGAIN:
+ err += sn9c102_i2c_write(cam, 0x13, ctrl->value);
+ break;
+ case V4L2_CID_VFLIP:
+ err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
+ break;
+ case V4L2_CID_BLACK_LEVEL:
+ err += sn9c102_i2c_write(cam, 0x25, ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_BRIGHT_LEVEL:
+ err += sn9c102_i2c_write(cam, 0x24, ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_GAMMA:
+ err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80);
+ break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int ov7630_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = &ov7630;
+ int err = 0;
+ u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int ov7630_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x20, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0x50, 0x19);
+
+ return err;
+}
+
+
+static struct sn9c102_sensor ov7630 = {
+ .name = "OV7630",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .sysfs_ops = SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x21,
+ .init = &ov7630_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x14,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "hue",
+ .minimum = 0x00,
+ .maximum = 0x1f+1,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "saturation",
+ .minimum = 0x00,
+ .maximum = 0x0f,
+ .step = 0x01,
+ .default_value = 0x08,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "contrast",
+ .minimum = 0x00,
+ .maximum = 0x1f+1,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x000,
+ .maximum = 0x3ff,
+ .step = 0x001,
+ .default_value = 0x83<<2,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = 0x3a,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = 0x77,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "brightness",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = 0xa0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_DO_WHITE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "white balance background: blue",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x20,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_WHITENESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "white balance background: red",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x20,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto white balance",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x01,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain & exposure mode",
+ .minimum = 0x00,
+ .maximum = 0x03,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x01,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLACK_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "black pixel ratio",
+ .minimum = 0x01,
+ .maximum = 0x9a,
+ .step = 0x01,
+ .default_value = 0x8a,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_BRIGHT_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "bright pixel ratio",
+ .minimum = 0x01,
+ .maximum = 0x9a,
+ .step = 0x01,
+ .default_value = 0x10,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_BAND_FILTER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "band filter",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "rgb gamma",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ },
+ .set_ctrl = &ov7630_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &ov7630_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &ov7630_set_pix_format
+};
+
+
+int sn9c102_probe_ov7630(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ sn9c102_attach_sensor(cam, &ov7630);
+
+ if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
+ le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c)
+ return -ENODEV;
+
+ err += sn9c102_write_reg(cam, 0x01, 0x01);
+ err += sn9c102_write_reg(cam, 0x00, 0x01);
+ err += sn9c102_write_reg(cam, 0x28, 0x17);
+
+ if (err)
+ return -EIO;
+
+ err += sn9c102_i2c_write(cam, 0x0b, 0);
+ if (err)
+ return -ENODEV;
+
+ return 0;
+}
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
index 6a7adebcb4b..a45166c3488 100644
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -64,6 +64,7 @@ struct sn9c102_sensor;
*/
extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
+extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
@@ -80,6 +81,7 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \
&sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \
&sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \
&sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \
+ &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \
&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \
&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \
NULL, \
@@ -103,7 +105,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \
{ USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \
{ USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \
{ USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \
- { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \
+ { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \
+ { USB_DEVICE(0x0c45, 0x602d), }, \
{ USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \
{ USB_DEVICE(0x0c45, 0x6080), }, \
{ USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \
@@ -145,6 +148,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \
*/
/* The "try" I2C I/O versions are used when probing the sensor */
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
+ u8 address, u8 value);
extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
u8 address);
@@ -201,6 +206,8 @@ enum sn9c102_i2c_interface {
SN9C102_I2C_3WIRES,
};
+#define SN9C102_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
+
struct sn9c102_sensor {
char name[32], /* sensor name */
maintainer[64]; /* name of the mantainer <email> */
@@ -243,7 +250,7 @@ struct sn9c102_sensor {
sensor according to the default configuration structures below.
*/
- struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
+ struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
/*
Optional list of default controls, defined as indicated in the
V4L2 API. Menu type controls are not handled by this interface.
@@ -356,7 +363,7 @@ struct sn9c102_sensor {
core module to store successfully updated values of the above
settings, for rollbacks..etc..in case of errors during atomic I/O
*/
- struct v4l2_queryctrl _qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
+ struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
struct v4l2_rect _rect;
};
@@ -367,5 +374,8 @@ struct sn9c102_sensor {
#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
#define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2
#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3
+#define SN9C102_V4L2_CID_GAMMA V4L2_CID_PRIVATE_BASE + 4
+#define SN9C102_V4L2_CID_BAND_FILTER V4L2_CID_PRIVATE_BASE + 5
+#define SN9C102_V4L2_CID_BRIGHT_LEVEL V4L2_CID_PRIVATE_BASE + 6
#endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
index 690d6219227..8775999b5af 100644
--- a/drivers/usb/media/sn9c102_tas5110c1b.c
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -24,8 +24,6 @@
static struct sn9c102_sensor tas5110c1b;
-static struct v4l2_control tas5110c1b_gain;
-
static int tas5110c1b_init(struct sn9c102_device* cam)
{
@@ -46,21 +44,6 @@ static int tas5110c1b_init(struct sn9c102_device* cam)
}
-static int tas5110c1b_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = tas5110c1b_gain.value;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
static int tas5110c1b_set_ctrl(struct sn9c102_device* cam,
const struct v4l2_control* ctrl)
{
@@ -68,8 +51,7 @@ static int tas5110c1b_set_ctrl(struct sn9c102_device* cam,
switch (ctrl->id) {
case V4L2_CID_GAIN:
- if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
- tas5110c1b_gain.value = ctrl->value;
+ err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
break;
default:
return -EINVAL;
@@ -147,7 +129,6 @@ static struct sn9c102_sensor tas5110c1b = {
.height = 288,
},
},
- .get_ctrl = &tas5110c1b_get_ctrl,
.set_crop = &tas5110c1b_set_crop,
.pix_format = {
.width = 352,
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
index b378e941bbe..927eafdd8c7 100644
--- a/drivers/usb/media/sn9c102_tas5130d1b.c
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -24,8 +24,6 @@
static struct sn9c102_sensor tas5130d1b;
-static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure;
-
static int tas5130d1b_init(struct sn9c102_device* cam)
{
@@ -44,24 +42,6 @@ static int tas5130d1b_init(struct sn9c102_device* cam)
}
-static int tas5130d1b_get_ctrl(struct sn9c102_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = tas5130d1b_gain.value;
- break;
- case V4L2_CID_EXPOSURE:
- ctrl->value = tas5130d1b_exposure.value;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
static int tas5130d1b_set_ctrl(struct sn9c102_device* cam,
const struct v4l2_control* ctrl)
{
@@ -69,12 +49,10 @@ static int tas5130d1b_set_ctrl(struct sn9c102_device* cam,
switch (ctrl->id) {
case V4L2_CID_GAIN:
- if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
- tas5130d1b_gain.value = ctrl->value;
+ err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
break;
case V4L2_CID_EXPOSURE:
- if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value)))
- tas5130d1b_exposure.value = ctrl->value;
+ err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value);
break;
default:
return -EINVAL;
@@ -147,7 +125,6 @@ static struct sn9c102_sensor tas5130d1b = {
.flags = 0,
},
},
- .get_ctrl = &tas5130d1b_get_ctrl,
.set_ctrl = &tas5130d1b_set_ctrl,
.cropcap = {
.bounds = {
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 3a896954b3a..6649531fa82 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -139,6 +139,16 @@ config USB_IDMOUSE
source "drivers/usb/misc/sisusbvga/Kconfig"
+config USB_LD
+ tristate "USB LD driver"
+ depends on USB && EXPERIMENTAL
+ help
+ This driver is for generic USB devices that use interrupt transfers,
+ like LD Didactic's USB devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ldusb.
+
config USB_TEST
tristate "USB testing driver (DEVELOPMENT)"
depends on USB && USB_DEVICEFS && EXPERIMENTAL
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 4a3814cbd48..862e40a8368 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_EMI26) += emi26.o
obj-$(CONFIG_USB_EMI62) += emi62.o
obj-$(CONFIG_USB_IDMOUSE) += idmouse.o
obj-$(CONFIG_USB_LCD) += usblcd.o
+obj-$(CONFIG_USB_LD) += ldusb.o
obj-$(CONFIG_USB_LED) += usbled.o
obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
new file mode 100644
index 00000000000..66ec88354b9
--- /dev/null
+++ b/drivers/usb/misc/ldusb.c
@@ -0,0 +1,794 @@
+/**
+ * Generic USB driver for report based interrupt in/out devices
+ * like LD Didactic's USB devices. LD Didactic's USB devices are
+ * HID devices which do not use HID report definitons (they use
+ * raw interrupt in and our reports only for communication).
+ *
+ * This driver uses a ring buffer for time critical reading of
+ * interrupt in reports and provides read and write methods for
+ * raw interrupt reports (similar to the Windows HID driver).
+ * Devices based on the book USB COMPLETE by Jan Axelson may need
+ * such a compatibility to the Windows HID driver.
+ *
+ * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * Derived from Lego USB Tower driver
+ * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net>
+ * 2001-2004 Juergen Stuber <starblue@users.sourceforge.net>
+ *
+ * V0.1 (mh) Initial version
+ * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/poll.h>
+
+/* Define these values to match your devices */
+#define USB_VENDOR_ID_LD 0x0f11 /* USB Vendor ID of LD Didactic GmbH */
+#define USB_DEVICE_ID_CASSY 0x1000 /* USB Product ID for all CASSY-S modules */
+#define USB_DEVICE_ID_POCKETCASSY 0x1010 /* USB Product ID for Pocket-CASSY */
+#define USB_DEVICE_ID_MOBILECASSY 0x1020 /* USB Product ID for Mobile-CASSY */
+#define USB_DEVICE_ID_JWM 0x1080 /* USB Product ID for Joule and Wattmeter */
+#define USB_DEVICE_ID_DMMP 0x1081 /* USB Product ID for Digital Multimeter P (reserved) */
+#define USB_DEVICE_ID_UMIP 0x1090 /* USB Product ID for UMI P */
+#define USB_DEVICE_ID_VIDEOCOM 0x1200 /* USB Product ID for VideoCom */
+#define USB_DEVICE_ID_COM3LAB 0x2000 /* USB Product ID for COM3LAB */
+#define USB_DEVICE_ID_TELEPORT 0x2010 /* USB Product ID for Terminal Adapter */
+#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 /* USB Product ID for Network Analyser */
+#define USB_DEVICE_ID_POWERCONTROL 0x2030 /* USB Product ID for Controlling device for Power Electronics */
+
+#define USB_VENDOR_ID_VERNIER 0x08f7
+#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
+#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
+#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
+#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
+
+
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define USB_LD_MINOR_BASE 0
+#else
+#define USB_LD_MINOR_BASE 176
+#endif
+
+/* table of devices that work with this driver */
+static struct usb_device_id ld_usb_table [] = {
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL) },
+ { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
+ { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
+ { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
+ { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ld_usb_table);
+MODULE_VERSION("V0.11");
+MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>");
+MODULE_DESCRIPTION("LD USB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("LD USB Devices");
+
+#ifdef CONFIG_USB_DEBUG
+ static int debug = 1;
+#else
+ static int debug = 0;
+#endif
+
+/* Use our own dbg macro */
+#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+
+/* Module parameters */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+/* All interrupt in transfers are collected in a ring buffer to
+ * avoid racing conditions and get better performance of the driver.
+ */
+static int ring_buffer_size = 128;
+module_param(ring_buffer_size, int, 0);
+MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
+
+/* The write_buffer can contain more than one interrupt out transfer.
+ */
+static int write_buffer_size = 10;
+module_param(write_buffer_size, int, 0);
+MODULE_PARM_DESC(write_buffer_size, "Write buffer size in reports");
+
+/* As of kernel version 2.6.4 ehci-hcd uses an
+ * "only one interrupt transfer per frame" shortcut
+ * to simplify the scheduling of periodic transfers.
+ * This conflicts with our standard 1ms intervals for in and out URBs.
+ * We use default intervals of 2ms for in and 2ms for out transfers,
+ * which should be fast enough.
+ * Increase the interval to allow more devices that do interrupt transfers,
+ * or set to 1 to use the standard interval from the endpoint descriptors.
+ */
+static int min_interrupt_in_interval = 2;
+module_param(min_interrupt_in_interval, int, 0);
+MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+
+static int min_interrupt_out_interval = 2;
+module_param(min_interrupt_out_interval, int, 0);
+MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
+
+/* Structure to hold all of our device specific stuff */
+struct ld_usb {
+ struct semaphore sem; /* locks this structure */
+ struct usb_interface* intf; /* save off the usb interface pointer */
+
+ int open_count; /* number of times this port has been opened */
+
+ char* ring_buffer;
+ unsigned int ring_head;
+ unsigned int ring_tail;
+
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+
+ char* interrupt_in_buffer;
+ struct usb_endpoint_descriptor* interrupt_in_endpoint;
+ struct urb* interrupt_in_urb;
+ int interrupt_in_interval;
+ size_t interrupt_in_endpoint_size;
+ int interrupt_in_running;
+ int interrupt_in_done;
+
+ char* interrupt_out_buffer;
+ struct usb_endpoint_descriptor* interrupt_out_endpoint;
+ struct urb* interrupt_out_urb;
+ int interrupt_out_interval;
+ size_t interrupt_out_endpoint_size;
+ int interrupt_out_busy;
+};
+
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX(disconnect_sem);
+
+static struct usb_driver ld_usb_driver;
+
+/**
+ * ld_usb_abort_transfers
+ * aborts transfers and frees associated data structures
+ */
+static void ld_usb_abort_transfers(struct ld_usb *dev)
+{
+ /* shutdown transfer */
+ if (dev->interrupt_in_running) {
+ dev->interrupt_in_running = 0;
+ if (dev->intf)
+ usb_kill_urb(dev->interrupt_in_urb);
+ }
+ if (dev->interrupt_out_busy)
+ if (dev->intf)
+ usb_kill_urb(dev->interrupt_out_urb);
+}
+
+/**
+ * ld_usb_delete
+ */
+static void ld_usb_delete(struct ld_usb *dev)
+{
+ ld_usb_abort_transfers(dev);
+
+ /* free data structures */
+ usb_free_urb(dev->interrupt_in_urb);
+ usb_free_urb(dev->interrupt_out_urb);
+ kfree(dev->ring_buffer);
+ kfree(dev->interrupt_in_buffer);
+ kfree(dev->interrupt_out_buffer);
+ kfree(dev);
+}
+
+/**
+ * ld_usb_interrupt_in_callback
+ */
+static void ld_usb_interrupt_in_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct ld_usb *dev = urb->context;
+ size_t *actual_buffer;
+ unsigned int next_ring_head;
+ int retval;
+
+ if (urb->status) {
+ if (urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN) {
+ goto exit;
+ } else {
+ dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
+ __FUNCTION__, urb->status);
+ goto resubmit; /* maybe we can recover */
+ }
+ }
+
+ if (urb->actual_length > 0) {
+ next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+ if (next_ring_head != dev->ring_tail) {
+ actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_head*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
+ /* actual_buffer gets urb->actual_length + interrupt_in_buffer */
+ *actual_buffer = urb->actual_length;
+ memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length);
+ dev->ring_head = next_ring_head;
+ dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
+ __FUNCTION__, urb->actual_length);
+ } else
+ dev_warn(&dev->intf->dev,
+ "Ring buffer overflow, %d bytes dropped\n",
+ urb->actual_length);
+ }
+
+resubmit:
+ /* resubmit if we're still running */
+ if (dev->interrupt_in_running && dev->intf) {
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(&dev->intf->dev,
+ "usb_submit_urb failed (%d)\n", retval);
+ }
+
+exit:
+ dev->interrupt_in_done = 1;
+ wake_up_interruptible(&dev->read_wait);
+}
+
+/**
+ * ld_usb_interrupt_out_callback
+ */
+static void ld_usb_interrupt_out_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct ld_usb *dev = urb->context;
+
+ /* sync/async unlink faults aren't errors */
+ if (urb->status && !(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
+ dbg_info(&dev->intf->dev,
+ "%s - nonzero write interrupt status received: %d\n",
+ __FUNCTION__, urb->status);
+
+ dev->interrupt_out_busy = 0;
+ wake_up_interruptible(&dev->write_wait);
+}
+
+/**
+ * ld_usb_open
+ */
+static int ld_usb_open(struct inode *inode, struct file *file)
+{
+ struct ld_usb *dev;
+ int subminor;
+ int retval = 0;
+ struct usb_interface *interface;
+
+ nonseekable_open(inode, file);
+ subminor = iminor(inode);
+
+ down(&disconnect_sem);
+
+ interface = usb_find_interface(&ld_usb_driver, subminor);
+
+ if (!interface) {
+ err("%s - error, can't find device for minor %d\n",
+ __FUNCTION__, subminor);
+ retval = -ENODEV;
+ goto unlock_disconnect_exit;
+ }
+
+ dev = usb_get_intfdata(interface);
+
+ if (!dev) {
+ retval = -ENODEV;
+ goto unlock_disconnect_exit;
+ }
+
+ /* lock this device */
+ if (down_interruptible(&dev->sem)) {
+ retval = -ERESTARTSYS;
+ goto unlock_disconnect_exit;
+ }
+
+ /* allow opening only once */
+ if (dev->open_count) {
+ retval = -EBUSY;
+ goto unlock_exit;
+ }
+ dev->open_count = 1;
+
+ /* initialize in direction */
+ dev->ring_head = 0;
+ dev->ring_tail = 0;
+ usb_fill_int_urb(dev->interrupt_in_urb,
+ interface_to_usbdev(interface),
+ usb_rcvintpipe(interface_to_usbdev(interface),
+ dev->interrupt_in_endpoint->bEndpointAddress),
+ dev->interrupt_in_buffer,
+ dev->interrupt_in_endpoint_size,
+ ld_usb_interrupt_in_callback,
+ dev,
+ dev->interrupt_in_interval);
+
+ dev->interrupt_in_running = 1;
+ dev->interrupt_in_done = 0;
+
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (retval) {
+ dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev->interrupt_in_running = 0;
+ dev->open_count = 0;
+ goto unlock_exit;
+ }
+
+ /* save device in the file's private structure */
+ file->private_data = dev;
+
+unlock_exit:
+ up(&dev->sem);
+
+unlock_disconnect_exit:
+ up(&disconnect_sem);
+
+ return retval;
+}
+
+/**
+ * ld_usb_release
+ */
+static int ld_usb_release(struct inode *inode, struct file *file)
+{
+ struct ld_usb *dev;
+ int retval = 0;
+
+ dev = file->private_data;
+
+ if (dev == NULL) {
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ if (down_interruptible(&dev->sem)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+
+ if (dev->open_count != 1) {
+ retval = -ENODEV;
+ goto unlock_exit;
+ }
+ if (dev->intf == NULL) {
+ /* the device was unplugged before the file was released */
+ up(&dev->sem);
+ /* unlock here as ld_usb_delete frees dev */
+ ld_usb_delete(dev);
+ goto exit;
+ }
+
+ /* wait until write transfer is finished */
+ if (dev->interrupt_out_busy)
+ wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+ ld_usb_abort_transfers(dev);
+ dev->open_count = 0;
+
+unlock_exit:
+ up(&dev->sem);
+
+exit:
+ return retval;
+}
+
+/**
+ * ld_usb_poll
+ */
+static unsigned int ld_usb_poll(struct file *file, poll_table *wait)
+{
+ struct ld_usb *dev;
+ unsigned int mask = 0;
+
+ dev = file->private_data;
+
+ poll_wait(file, &dev->read_wait, wait);
+ poll_wait(file, &dev->write_wait, wait);
+
+ if (dev->ring_head != dev->ring_tail)
+ mask |= POLLIN | POLLRDNORM;
+ if (!dev->interrupt_out_busy)
+ mask |= POLLOUT | POLLWRNORM;
+
+ return mask;
+}
+
+/**
+ * ld_usb_read
+ */
+static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
+ loff_t *ppos)
+{
+ struct ld_usb *dev;
+ size_t *actual_buffer;
+ size_t bytes_to_read;
+ int retval = 0;
+
+ dev = file->private_data;
+
+ /* verify that we actually have some data to read */
+ if (count == 0)
+ goto exit;
+
+ /* lock this object */
+ if (down_interruptible(&dev->sem)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+
+ /* verify that the device wasn't unplugged */
+ if (dev->intf == NULL) {
+ retval = -ENODEV;
+ err("No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+ }
+
+ /* wait for data */
+ if (dev->ring_head == dev->ring_tail) {
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto unlock_exit;
+ }
+ retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
+ if (retval < 0)
+ goto unlock_exit;
+ }
+
+ /* actual_buffer contains actual_length + interrupt_in_buffer */
+ actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
+ bytes_to_read = min(count, *actual_buffer);
+ if (bytes_to_read < *actual_buffer)
+ dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n",
+ *actual_buffer-bytes_to_read);
+
+ /* copy one interrupt_in_buffer from ring_buffer into userspace */
+ if (copy_to_user(buffer, actual_buffer+1, bytes_to_read)) {
+ retval = -EFAULT;
+ goto unlock_exit;
+ }
+ dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
+
+ retval = bytes_to_read;
+
+unlock_exit:
+ /* unlock the device */
+ up(&dev->sem);
+
+exit:
+ return retval;
+}
+
+/**
+ * ld_usb_write
+ */
+static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct ld_usb *dev;
+ size_t bytes_to_write;
+ int retval = 0;
+
+ dev = file->private_data;
+
+ /* verify that we actually have some data to write */
+ if (count == 0)
+ goto exit;
+
+ /* lock this object */
+ if (down_interruptible(&dev->sem)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+
+ /* verify that the device wasn't unplugged */
+ if (dev->intf == NULL) {
+ retval = -ENODEV;
+ err("No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+ }
+
+ /* wait until previous transfer is finished */
+ if (dev->interrupt_out_busy) {
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto unlock_exit;
+ }
+ retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
+ if (retval < 0) {
+ goto unlock_exit;
+ }
+ }
+
+ /* write the data into interrupt_out_buffer from userspace */
+ bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+ if (bytes_to_write < count)
+ dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write);
+ dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write);
+
+ if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
+ retval = -EFAULT;
+ goto unlock_exit;
+ }
+
+ if (dev->interrupt_out_endpoint == NULL) {
+ /* try HID_REQ_SET_REPORT=9 on control_endpoint instead of interrupt_out_endpoint */
+ retval = usb_control_msg(interface_to_usbdev(dev->intf),
+ usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0),
+ 9,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 1 << 8, 0,
+ dev->interrupt_out_buffer,
+ bytes_to_write,
+ USB_CTRL_SET_TIMEOUT * HZ);
+ if (retval < 0)
+ err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
+ goto unlock_exit;
+ }
+
+ /* send off the urb */
+ usb_fill_int_urb(dev->interrupt_out_urb,
+ interface_to_usbdev(dev->intf),
+ usb_sndintpipe(interface_to_usbdev(dev->intf),
+ dev->interrupt_out_endpoint->bEndpointAddress),
+ dev->interrupt_out_buffer,
+ bytes_to_write,
+ ld_usb_interrupt_out_callback,
+ dev,
+ dev->interrupt_out_interval);
+
+ dev->interrupt_out_busy = 1;
+ wmb();
+
+ retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
+ if (retval) {
+ dev->interrupt_out_busy = 0;
+ err("Couldn't submit interrupt_out_urb %d\n", retval);
+ goto unlock_exit;
+ }
+ retval = bytes_to_write;
+
+unlock_exit:
+ /* unlock the device */
+ up(&dev->sem);
+
+exit:
+ return retval;
+}
+
+/* file operations needed when we register this driver */
+static struct file_operations ld_usb_fops = {
+ .owner = THIS_MODULE,
+ .read = ld_usb_read,
+ .write = ld_usb_write,
+ .open = ld_usb_open,
+ .release = ld_usb_release,
+ .poll = ld_usb_poll,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with devfs and the driver core
+ */
+static struct usb_class_driver ld_usb_class = {
+ .name = "ldusb%d",
+ .fops = &ld_usb_fops,
+ .minor_base = USB_LD_MINOR_BASE,
+};
+
+/**
+ * ld_usb_probe
+ *
+ * Called by the usb core when a new device is connected that it thinks
+ * this driver might be interested in.
+ */
+static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct ld_usb *dev = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ char *buffer;
+ int i;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and intialize it */
+
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&intf->dev, "Out of memory\n");
+ goto exit;
+ }
+ memset(dev, 0x00, sizeof(*dev));
+ init_MUTEX(&dev->sem);
+ dev->intf = intf;
+ init_waitqueue_head(&dev->read_wait);
+ init_waitqueue_head(&dev->write_wait);
+
+ /* workaround for early firmware versions on fast computers */
+ if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) &&
+ ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) ||
+ (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) &&
+ (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
+ buffer = kmalloc(256, GFP_KERNEL);
+ /* usb_string makes SETUP+STALL to leave always ControlReadLoop */
+ usb_string(udev, 255, buffer, 256);
+ kfree(buffer);
+ }
+
+ iface_desc = intf->cur_altsetting;
+
+ /* set up the endpoint information */
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+ dev->interrupt_in_endpoint = endpoint;
+ }
+
+ if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+ dev->interrupt_out_endpoint = endpoint;
+ }
+ }
+ if (dev->interrupt_in_endpoint == NULL) {
+ dev_err(&intf->dev, "Interrupt in endpoint not found\n");
+ goto error;
+ }
+ if (dev->interrupt_out_endpoint == NULL)
+ dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+
+ dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+ dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL);
+ if (!dev->ring_buffer) {
+ dev_err(&intf->dev, "Couldn't allocate ring_buffer\n");
+ goto error;
+ }
+ dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+ if (!dev->interrupt_in_buffer) {
+ dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
+ goto error;
+ }
+ dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->interrupt_in_urb) {
+ dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
+ goto error;
+ }
+ dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
+ udev->descriptor.bMaxPacketSize0;
+ dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+ if (!dev->interrupt_out_buffer) {
+ dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
+ goto error;
+ }
+ dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->interrupt_out_urb) {
+ dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
+ goto error;
+ }
+ dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+ if (dev->interrupt_out_endpoint)
+ dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+
+ /* we can register the device now, as it is ready */
+ usb_set_intfdata(intf, dev);
+
+ retval = usb_register_dev(intf, &ld_usb_class);
+ if (retval) {
+ /* something prevented us from registering this driver */
+ dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ usb_set_intfdata(intf, NULL);
+ goto error;
+ }
+
+ /* let the user know what node this device is now attached to */
+ dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n",
+ (intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor);
+
+exit:
+ return retval;
+
+error:
+ ld_usb_delete(dev);
+
+ return retval;
+}
+
+/**
+ * ld_usb_disconnect
+ *
+ * Called by the usb core when the device is removed from the system.
+ */
+static void ld_usb_disconnect(struct usb_interface *intf)
+{
+ struct ld_usb *dev;
+ int minor;
+
+ down(&disconnect_sem);
+
+ dev = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+
+ down(&dev->sem);
+
+ minor = intf->minor;
+
+ /* give back our minor */
+ usb_deregister_dev(intf, &ld_usb_class);
+
+ /* if the device is not opened, then we clean up right now */
+ if (!dev->open_count) {
+ up(&dev->sem);
+ ld_usb_delete(dev);
+ } else {
+ dev->intf = NULL;
+ up(&dev->sem);
+ }
+
+ up(&disconnect_sem);
+
+ dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
+ (minor - USB_LD_MINOR_BASE));
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver ld_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "ldusb",
+ .probe = ld_usb_probe,
+ .disconnect = ld_usb_disconnect,
+ .id_table = ld_usb_table,
+};
+
+/**
+ * ld_usb_init
+ */
+static int __init ld_usb_init(void)
+{
+ int retval;
+
+ /* register this driver with the USB subsystem */
+ retval = usb_register(&ld_usb_driver);
+ if (retval)
+ err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+
+ return retval;
+}
+
+/**
+ * ld_usb_exit
+ */
+static void __exit ld_usb_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&ld_usb_driver);
+}
+
+module_init(ld_usb_init);
+module_exit(ld_usb_exit);
+
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 755a4570477..26266b30028 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -19,11 +19,16 @@
#define DATA_MAX 32
/*
+ * Defined by USB 2.0 clause 9.3, table 9.2.
+ */
+#define SETUP_MAX 8
+
+/*
* This limit exists to prevent OOMs when the user process stops reading.
*/
#define EVENT_MAX 25
-#define PRINTF_DFL 120
+#define PRINTF_DFL 130
struct mon_event_text {
struct list_head e_link;
@@ -33,7 +38,9 @@ struct mon_event_text {
unsigned int tstamp;
int length; /* Depends on type: xfer length or act length */
int status;
+ char setup_flag;
char data_flag;
+ unsigned char setup[SETUP_MAX];
unsigned char data[DATA_MAX];
};
@@ -64,6 +71,22 @@ static void mon_text_dtor(void *, kmem_cache_t *, unsigned long);
* This is called with the whole mon_bus locked, so no additional lock.
*/
+static inline char mon_text_get_setup(struct mon_event_text *ep,
+ struct urb *urb, char ev_type)
+{
+
+ if (!usb_pipecontrol(urb->pipe) || ev_type != 'S')
+ return '-';
+
+ if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)
+ return 'D';
+ if (urb->setup_packet == NULL)
+ return 'Z'; /* '0' would be not as pretty. */
+
+ memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
+ return 0;
+}
+
static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
int len, char ev_type)
{
@@ -90,7 +113,6 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
/*
* Bulk is easy to shortcut reliably.
- * XXX Control needs setup packet taken.
* XXX Other pipe types need consideration. Currently, we overdo it
* and collect garbage for them: better more than less.
*/
@@ -144,6 +166,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
/* Collecting status makes debugging sense for submits, too */
ep->status = urb->status;
+ ep->setup_flag = mon_text_get_setup(ep, urb, ev_type);
ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type);
rp->nevents++;
@@ -299,10 +322,25 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
default: /* PIPE_BULK */ utype = 'B';
}
cnt += snprintf(pbuf + cnt, limit - cnt,
- "%lx %u %c %c%c:%03u:%02u %d %d",
+ "%lx %u %c %c%c:%03u:%02u",
ep->id, ep->tstamp, ep->type,
- utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe),
- ep->status, ep->length);
+ utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
+
+ if (ep->setup_flag == 0) { /* Setup packet is present and captured */
+ cnt += snprintf(pbuf + cnt, limit - cnt,
+ " s %02x %02x %04x %04x %04x",
+ ep->setup[0],
+ ep->setup[1],
+ (ep->setup[3] << 8) | ep->setup[2],
+ (ep->setup[5] << 8) | ep->setup[4],
+ (ep->setup[7] << 8) | ep->setup[6]);
+ } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
+ cnt += snprintf(pbuf + cnt, limit - cnt,
+ " %c __ __ ____ ____ ____", ep->setup_flag);
+ } else { /* No setup for this kind of URB */
+ cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status);
+ }
+ cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length);
if ((data_len = ep->length) > 0) {
if (ep->data_flag == 0) {
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index fd6ff4cb2c6..7ffa99b9760 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -477,7 +477,7 @@ static int kaweth_reset(struct kaweth_device *kaweth)
}
static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
-static int kaweth_resubmit_rx_urb(struct kaweth_device *, int);
+static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned);
/****************************************************************
int_callback
@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d)
* kaweth_resubmit_rx_urb
****************************************************************/
static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
- int mem_flags)
+ unsigned mem_flags)
{
int result;
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 8a945f4f369..576f3b852fc 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -3227,9 +3227,9 @@ static int usbnet_stop (struct net_device *net)
temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
// maybe wait for deletions to finish.
- while (skb_queue_len (&dev->rxq)
- && skb_queue_len (&dev->txq)
- && skb_queue_len (&dev->done)) {
+ while (!skb_queue_empty(&dev->rxq) &&
+ !skb_queue_empty(&dev->txq) &&
+ !skb_queue_empty(&dev->done)) {
msleep(UNLINK_TIMEOUT_MS);
if (netif_msg_ifdown (dev))
devdbg (dev, "waited for %d urb completions", temp);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d882fa3ad19..0b03ddab53d 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -264,16 +264,26 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.4.2"
+#define DRIVER_VERSION "v1.4.3"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
#define DRIVER_DESC "USB FTDI Serial Converters Driver"
static int debug;
-static struct usb_device_id id_table_sio [] = {
- { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
- { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
- { } /* Terminating entry */
+/* struct ftdi_sio_quirk is used by devices requiring special attention. */
+struct ftdi_sio_quirk {
+ void (*setup)(struct usb_serial *); /* Special settings during startup. */
+};
+
+static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
+static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
+
+static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
+ .setup = ftdi_USB_UIRT_setup,
+};
+
+static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
+ .setup = ftdi_HE_TIRA1_setup,
};
/*
@@ -288,237 +298,11 @@ static struct usb_device_id id_table_sio [] = {
* the bcdDevice value is used to differentiate FT232BM and FT245BM from
* the earlier FT8U232AM and FT8U232BM. For now, include all known VID/PID
* combinations in both tables.
- * FIXME: perhaps bcdDevice can also identify 12MHz devices, but I don't know
- * if those ever went into mass production. [Ian Abbott]
+ * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices,
+ * but I don't know if those ever went into mass production. [Ian Abbott]
*/
-static struct usb_device_id id_table_8U232AM [] = {
- { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) },
- { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
- { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
- { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) },
- { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0, 0x3ff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0, 0x3ff) },
- { } /* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_FT232BM [] = {
- { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_PIEGROUP_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
- { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
- { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0x400, 0xffff) },
- { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
- { } /* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_USB_UIRT [] = {
- { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
- { } /* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_HE_TIRA1 [] = {
- { USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
- { } /* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_FT2232C[] = {
- { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
- { } /* Terminating entry */
-};
-
static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
@@ -540,14 +324,14 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
@@ -597,35 +381,37 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
{ USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
{ USB_DEVICE(OCT_VID, OCT_US101_PID) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
- { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_USB_UIRT_quirk },
{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) },
{ USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
- { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) },
- { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
+ { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
@@ -642,7 +428,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
- { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
+ { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
{ } /* Terminating entry */
};
@@ -705,12 +491,8 @@ struct ftdi_private {
ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP )
/* function prototypes for a FTDI serial converter */
-static int ftdi_SIO_startup (struct usb_serial *serial);
-static int ftdi_8U232AM_startup (struct usb_serial *serial);
-static int ftdi_FT232BM_startup (struct usb_serial *serial);
-static int ftdi_FT2232C_startup (struct usb_serial *serial);
-static int ftdi_USB_UIRT_startup (struct usb_serial *serial);
-static int ftdi_HE_TIRA1_startup (struct usb_serial *serial);
+static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
+static int ftdi_sio_attach (struct usb_serial *serial);
static void ftdi_shutdown (struct usb_serial *serial);
static int ftdi_open (struct usb_serial_port *port, struct file *filp);
static void ftdi_close (struct usb_serial_port *port, struct file *filp);
@@ -733,14 +515,16 @@ static unsigned short int ftdi_232am_baud_to_divisor (int baud);
static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
static __u32 ftdi_232bm_baud_to_divisor (int baud);
-static struct usb_serial_device_type ftdi_SIO_device = {
+static struct usb_serial_device_type ftdi_sio_device = {
.owner = THIS_MODULE,
- .name = "FTDI SIO",
- .id_table = id_table_sio,
+ .name = "FTDI USB Serial Device",
+ .short_name = "ftdi_sio",
+ .id_table = id_table_combined,
.num_interrupt_in = 0,
.num_bulk_in = 1,
.num_bulk_out = 1,
.num_ports = 1,
+ .probe = ftdi_sio_probe,
.open = ftdi_open,
.close = ftdi_close,
.throttle = ftdi_throttle,
@@ -755,143 +539,10 @@ static struct usb_serial_device_type ftdi_SIO_device = {
.ioctl = ftdi_ioctl,
.set_termios = ftdi_set_termios,
.break_ctl = ftdi_break_ctl,
- .attach = ftdi_SIO_startup,
+ .attach = ftdi_sio_attach,
.shutdown = ftdi_shutdown,
};
-static struct usb_serial_device_type ftdi_8U232AM_device = {
- .owner = THIS_MODULE,
- .name = "FTDI 8U232AM Compatible",
- .id_table = id_table_8U232AM,
- .num_interrupt_in = 0,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .open = ftdi_open,
- .close = ftdi_close,
- .throttle = ftdi_throttle,
- .unthrottle = ftdi_unthrottle,
- .write = ftdi_write,
- .write_room = ftdi_write_room,
- .chars_in_buffer = ftdi_chars_in_buffer,
- .read_bulk_callback = ftdi_read_bulk_callback,
- .write_bulk_callback = ftdi_write_bulk_callback,
- .tiocmget = ftdi_tiocmget,
- .tiocmset = ftdi_tiocmset,
- .ioctl = ftdi_ioctl,
- .set_termios = ftdi_set_termios,
- .break_ctl = ftdi_break_ctl,
- .attach = ftdi_8U232AM_startup,
- .shutdown = ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_FT232BM_device = {
- .owner = THIS_MODULE,
- .name = "FTDI FT232BM Compatible",
- .id_table = id_table_FT232BM,
- .num_interrupt_in = 0,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .open = ftdi_open,
- .close = ftdi_close,
- .throttle = ftdi_throttle,
- .unthrottle = ftdi_unthrottle,
- .write = ftdi_write,
- .write_room = ftdi_write_room,
- .chars_in_buffer = ftdi_chars_in_buffer,
- .read_bulk_callback = ftdi_read_bulk_callback,
- .write_bulk_callback = ftdi_write_bulk_callback,
- .tiocmget = ftdi_tiocmget,
- .tiocmset = ftdi_tiocmset,
- .ioctl = ftdi_ioctl,
- .set_termios = ftdi_set_termios,
- .break_ctl = ftdi_break_ctl,
- .attach = ftdi_FT232BM_startup,
- .shutdown = ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_FT2232C_device = {
- .owner = THIS_MODULE,
- .name = "FTDI FT2232C Compatible",
- .id_table = id_table_FT2232C,
- .num_interrupt_in = 0,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .open = ftdi_open,
- .close = ftdi_close,
- .throttle = ftdi_throttle,
- .unthrottle = ftdi_unthrottle,
- .write = ftdi_write,
- .write_room = ftdi_write_room,
- .chars_in_buffer = ftdi_chars_in_buffer,
- .read_bulk_callback = ftdi_read_bulk_callback,
- .write_bulk_callback = ftdi_write_bulk_callback,
- .tiocmget = ftdi_tiocmget,
- .tiocmset = ftdi_tiocmset,
- .ioctl = ftdi_ioctl,
- .set_termios = ftdi_set_termios,
- .break_ctl = ftdi_break_ctl,
- .attach = ftdi_FT2232C_startup,
- .shutdown = ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_USB_UIRT_device = {
- .owner = THIS_MODULE,
- .name = "USB-UIRT Infrared Tranceiver",
- .id_table = id_table_USB_UIRT,
- .num_interrupt_in = 0,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .open = ftdi_open,
- .close = ftdi_close,
- .throttle = ftdi_throttle,
- .unthrottle = ftdi_unthrottle,
- .write = ftdi_write,
- .write_room = ftdi_write_room,
- .chars_in_buffer = ftdi_chars_in_buffer,
- .read_bulk_callback = ftdi_read_bulk_callback,
- .write_bulk_callback = ftdi_write_bulk_callback,
- .tiocmget = ftdi_tiocmget,
- .tiocmset = ftdi_tiocmset,
- .ioctl = ftdi_ioctl,
- .set_termios = ftdi_set_termios,
- .break_ctl = ftdi_break_ctl,
- .attach = ftdi_USB_UIRT_startup,
- .shutdown = ftdi_shutdown,
-};
-
-/* The TIRA1 is based on a FT232BM which requires a fixed baud rate of 100000
- * and which requires RTS-CTS to be enabled. */
-static struct usb_serial_device_type ftdi_HE_TIRA1_device = {
- .owner = THIS_MODULE,
- .name = "Home-Electronics TIRA-1 IR Transceiver",
- .id_table = id_table_HE_TIRA1,
- .num_interrupt_in = 0,
- .num_bulk_in = 1,
- .num_bulk_out = 1,
- .num_ports = 1,
- .open = ftdi_open,
- .close = ftdi_close,
- .throttle = ftdi_throttle,
- .unthrottle = ftdi_unthrottle,
- .write = ftdi_write,
- .write_room = ftdi_write_room,
- .chars_in_buffer = ftdi_chars_in_buffer,
- .read_bulk_callback = ftdi_read_bulk_callback,
- .write_bulk_callback = ftdi_write_bulk_callback,
- .tiocmget = ftdi_tiocmget,
- .tiocmset = ftdi_tiocmset,
- .ioctl = ftdi_ioctl,
- .set_termios = ftdi_set_termios,
- .break_ctl = ftdi_break_ctl,
- .attach = ftdi_HE_TIRA1_startup,
- .shutdown = ftdi_shutdown,
-};
-
-
#define WDR_TIMEOUT 5000 /* default urb timeout */
@@ -1212,6 +863,59 @@ check_and_exit:
} /* set_serial_info */
+/* Determine type of FTDI chip based on USB config and descriptor. */
+static void ftdi_determine_type(struct usb_serial_port *port)
+{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ struct usb_serial *serial = port->serial;
+ struct usb_device *udev = serial->dev;
+ unsigned version;
+ unsigned interfaces;
+
+ /* Assume it is not the original SIO device for now. */
+ priv->baud_base = 48000000 / 16;
+ priv->write_offset = 0;
+
+ version = le16_to_cpu(udev->descriptor.bcdDevice);
+ interfaces = udev->actconfig->desc.bNumInterfaces;
+ dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __FUNCTION__,
+ version, interfaces);
+ if (interfaces > 1) {
+ int inter;
+
+ /* Multiple interfaces. Assume FT2232C. */
+ priv->chip_type = FT2232C;
+ /* Determine interface code. */
+ inter = serial->interface->altsetting->desc.bInterfaceNumber;
+ if (inter == 0) {
+ priv->interface = PIT_SIOA;
+ } else {
+ priv->interface = PIT_SIOB;
+ }
+ /* BM-type devices have a bug where bcdDevice gets set
+ * to 0x200 when iSerialNumber is 0. */
+ if (version < 0x500) {
+ dbg("%s: something fishy - bcdDevice too low for multi-interface device",
+ __FUNCTION__);
+ }
+ } else if (version < 0x200) {
+ /* Old device. Assume its the original SIO. */
+ priv->chip_type = SIO;
+ priv->baud_base = 12000000 / 16;
+ priv->write_offset = 1;
+ } else if (version < 0x400) {
+ /* Assume its an FT8U232AM (or FT8U245AM) */
+ /* (It might be a BM because of the iSerialNumber bug,
+ * but it will still work as an AM device.) */
+ priv->chip_type = FT8U232AM;
+ } else {
+ /* Assume its an FT232BM (or FT245BM) */
+ priv->chip_type = FT232BM;
+ }
+ info("Detected %s", ftdi_chip_name[priv->chip_type]);
+}
+
+
/*
* ***************************************************************************
* Sysfs Attribute
@@ -1355,12 +1059,20 @@ static void remove_sysfs_attrs(struct usb_serial *serial)
* ***************************************************************************
*/
-/* Common startup subroutine */
-/* Called from ftdi_SIO_startup, etc. */
-static int ftdi_common_startup (struct usb_serial *serial)
+/* Probe function to check for special devices */
+static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
+{
+ usb_set_serial_data(serial, (void *)id->driver_info);
+
+ return (0);
+}
+
+/* attach subroutine */
+static int ftdi_sio_attach (struct usb_serial *serial)
{
struct usb_serial_port *port = serial->port[0];
struct ftdi_private *priv;
+ struct ftdi_sio_quirk *quirk;
dbg("%s",__FUNCTION__);
@@ -1400,150 +1112,49 @@ static int ftdi_common_startup (struct usb_serial *serial)
port->bulk_out_buffer = NULL;
usb_set_serial_port_data(serial->port[0], priv);
-
- return (0);
-}
-
-
-/* Startup for the SIO chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_SIO_startup (struct usb_serial *serial)
-{
- struct ftdi_private *priv;
- int err;
-
- dbg("%s",__FUNCTION__);
-
- err = ftdi_common_startup(serial);
- if (err){
- return (err);
- }
-
- priv = usb_get_serial_port_data(serial->port[0]);
- priv->chip_type = SIO;
- priv->baud_base = 12000000 / 16;
- priv->write_offset = 1;
-
- return (0);
-}
-
-/* Startup for the 8U232AM chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_8U232AM_startup (struct usb_serial *serial)
-{ /* ftdi_8U232AM_startup */
- struct ftdi_private *priv;
- int err;
-
- dbg("%s",__FUNCTION__);
- err = ftdi_common_startup(serial);
- if (err){
- return (err);
- }
- priv = usb_get_serial_port_data(serial->port[0]);
- priv->chip_type = FT8U232AM;
- priv->baud_base = 48000000 / 2; /* Would be / 16, but FTDI supports 0.125, 0.25 and 0.5 divisor fractions! */
-
+ ftdi_determine_type (serial->port[0]);
create_sysfs_attrs(serial);
-
- return (0);
-} /* ftdi_8U232AM_startup */
-/* Startup for the FT232BM chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_FT232BM_startup (struct usb_serial *serial)
-{ /* ftdi_FT232BM_startup */
- struct ftdi_private *priv;
- int err;
-
- dbg("%s",__FUNCTION__);
- err = ftdi_common_startup(serial);
- if (err){
- return (err);
+ /* Check for device requiring special set up. */
+ quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial);
+ if (quirk && quirk->setup) {
+ quirk->setup(serial);
}
-
- priv = usb_get_serial_port_data(serial->port[0]);
- priv->chip_type = FT232BM;
- priv->baud_base = 48000000 / 2; /* Would be / 16, but FT232BM supports multiple of 0.125 divisor fractions! */
- create_sysfs_attrs(serial);
-
return (0);
-} /* ftdi_FT232BM_startup */
-
-/* Startup for the FT2232C chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_FT2232C_startup (struct usb_serial *serial)
-{ /* ftdi_FT2232C_startup */
- struct ftdi_private *priv;
- int err;
- int inter;
-
- dbg("%s",__FUNCTION__);
- err = ftdi_common_startup(serial);
- if (err){
- return (err);
- }
+} /* ftdi_sio_attach */
- priv = usb_get_serial_port_data(serial->port[0]);
- priv->chip_type = FT2232C;
- inter = serial->interface->altsetting->desc.bInterfaceNumber;
- if (inter) {
- priv->interface = PIT_SIOB;
- }
- else {
- priv->interface = PIT_SIOA;
- }
- priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */
-
- create_sysfs_attrs(serial);
-
- return (0);
-} /* ftdi_FT2232C_startup */
-
-/* Startup for the USB-UIRT device, which requires hardwired baudrate (38400 gets mapped to 312500) */
+/* Setup for the USB-UIRT device, which requires hardwired
+ * baudrate (38400 gets mapped to 312500) */
/* Called from usbserial:serial_probe */
-static int ftdi_USB_UIRT_startup (struct usb_serial *serial)
-{ /* ftdi_USB_UIRT_startup */
+static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
+{
struct ftdi_private *priv;
- int err;
dbg("%s",__FUNCTION__);
- err = ftdi_8U232AM_startup(serial);
- if (err){
- return (err);
- }
priv = usb_get_serial_port_data(serial->port[0]);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 77;
priv->force_baud = B38400;
-
- return (0);
-} /* ftdi_USB_UIRT_startup */
+} /* ftdi_USB_UIRT_setup */
-/* Startup for the HE-TIRA1 device, which requires hardwired
- * baudrate (38400 gets mapped to 100000) */
-static int ftdi_HE_TIRA1_startup (struct usb_serial *serial)
-{ /* ftdi_HE_TIRA1_startup */
+/* Setup for the HE-TIRA1 device, which requires hardwired
+ * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */
+static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
+{
struct ftdi_private *priv;
- int err;
dbg("%s",__FUNCTION__);
- err = ftdi_FT232BM_startup(serial);
- if (err){
- return (err);
- }
priv = usb_get_serial_port_data(serial->port[0]);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 240;
priv->force_baud = B38400;
priv->force_rtscts = 1;
-
- return (0);
-} /* ftdi_HE_TIRA1_startup */
+} /* ftdi_HE_TIRA1_setup */
/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
@@ -2367,60 +1978,11 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
- int ret, mask;
-
dbg("%s cmd 0x%04x", __FUNCTION__, cmd);
/* Based on code from acm.c and others */
switch (cmd) {
- case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
- dbg("%s TIOCMBIS", __FUNCTION__);
- if (get_user(mask, (unsigned long __user *) arg))
- return -EFAULT;
- if (mask & TIOCM_DTR){
- if ((ret = set_dtr(port, HIGH)) < 0) {
- err("Urb to set DTR failed");
- return(ret);
- }
- }
- if (mask & TIOCM_RTS) {
- if ((ret = set_rts(port, HIGH)) < 0){
- err("Urb to set RTS failed");
- return(ret);
- }
- }
- return(0);
- break;
-
- case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
- dbg("%s TIOCMBIC", __FUNCTION__);
- if (get_user(mask, (unsigned long __user *) arg))
- return -EFAULT;
- if (mask & TIOCM_DTR){
- if ((ret = set_dtr(port, LOW)) < 0){
- err("Urb to unset DTR failed");
- return(ret);
- }
- }
- if (mask & TIOCM_RTS) {
- if ((ret = set_rts(port, LOW)) < 0){
- err("Urb to unset RTS failed");
- return(ret);
- }
- }
- return(0);
- break;
-
- /*
- * I had originally implemented TCSET{A,S}{,F,W} and
- * TCGET{A,S} here separately, however when testing I
- * found that the higher layers actually do the termios
- * conversions themselves and pass the call onto
- * ftdi_sio_set_termios.
- *
- */
-
case TIOCGSERIAL: /* gets serial port data */
return get_serial_info(port, (struct serial_struct __user *) arg);
@@ -2516,24 +2078,9 @@ static int __init ftdi_init (void)
int retval;
dbg("%s", __FUNCTION__);
- retval = usb_serial_register(&ftdi_SIO_device);
- if (retval)
- goto failed_SIO_register;
- retval = usb_serial_register(&ftdi_8U232AM_device);
- if (retval)
- goto failed_8U232AM_register;
- retval = usb_serial_register(&ftdi_FT232BM_device);
- if (retval)
- goto failed_FT232BM_register;
- retval = usb_serial_register(&ftdi_FT2232C_device);
- if (retval)
- goto failed_FT2232C_register;
- retval = usb_serial_register(&ftdi_USB_UIRT_device);
- if (retval)
- goto failed_USB_UIRT_register;
- retval = usb_serial_register(&ftdi_HE_TIRA1_device);
+ retval = usb_serial_register(&ftdi_sio_device);
if (retval)
- goto failed_HE_TIRA1_register;
+ goto failed_sio_register;
retval = usb_register(&ftdi_driver);
if (retval)
goto failed_usb_register;
@@ -2541,18 +2088,8 @@ static int __init ftdi_init (void)
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
failed_usb_register:
- usb_serial_deregister(&ftdi_HE_TIRA1_device);
-failed_HE_TIRA1_register:
- usb_serial_deregister(&ftdi_USB_UIRT_device);
-failed_USB_UIRT_register:
- usb_serial_deregister(&ftdi_FT2232C_device);
-failed_FT2232C_register:
- usb_serial_deregister(&ftdi_FT232BM_device);
-failed_FT232BM_register:
- usb_serial_deregister(&ftdi_8U232AM_device);
-failed_8U232AM_register:
- usb_serial_deregister(&ftdi_SIO_device);
-failed_SIO_register:
+ usb_serial_deregister(&ftdi_sio_device);
+failed_sio_register:
return retval;
}
@@ -2563,12 +2100,7 @@ static void __exit ftdi_exit (void)
dbg("%s", __FUNCTION__);
usb_deregister (&ftdi_driver);
- usb_serial_deregister (&ftdi_HE_TIRA1_device);
- usb_serial_deregister (&ftdi_USB_UIRT_device);
- usb_serial_deregister (&ftdi_FT2232C_device);
- usb_serial_deregister (&ftdi_FT232BM_device);
- usb_serial_deregister (&ftdi_8U232AM_device);
- usb_serial_deregister (&ftdi_SIO_device);
+ usb_serial_deregister (&ftdi_sio_device);
}
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 9fcc7bd1fbe..bd0ab3039bd 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -697,7 +697,7 @@ UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133,
UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
"Microtech",
"USB-SCSI-HD50",
- US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
+ US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
#ifdef CONFIG_USB_STORAGE_DPCM
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 7dfbf39b4ed..ddc9443254d 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -256,7 +256,7 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
unsigned int offset = 0, i;
if (!fb_info->cmap.red || !fb_info->cmap.blue ||
- fb_info->cmap.green || fb_info->cmap.transp)
+ !fb_info->cmap.green || !fb_info->cmap.transp)
return -EINVAL;
for (i = 0; i < fb_info->cmap.len; i++) {
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 6ba10e3acef..3e9ccf370ab 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -63,5 +63,10 @@ config LOGO_SUPERH_CLUT224
depends on LOGO && SUPERH
default y
+config LOGO_M32R_CLUT224
+ bool "224-color M32R Linux logo"
+ depends on LOGO && M32R
+ default y
+
endmenu
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index b0d995020bd..d0244c04af5 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_LOGO_SUN_CLUT224) += logo_sun_clut224.o
obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_superh_mono.o
obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o
obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o
+obj-$(CONFIG_LOGO_M32R_CLUT224) += logo_m32r_clut224.o
# How to generate logo's
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 77b62207500..788fa812c87 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -33,6 +33,7 @@ extern const struct linux_logo logo_sun_clut224;
extern const struct linux_logo logo_superh_mono;
extern const struct linux_logo logo_superh_vga16;
extern const struct linux_logo logo_superh_clut224;
+extern const struct linux_logo logo_m32r_clut224;
const struct linux_logo *fb_find_logo(int depth)
@@ -97,6 +98,10 @@ const struct linux_logo *fb_find_logo(int depth)
/* SuperH Linux logo */
logo = &logo_superh_clut224;
#endif
+#ifdef CONFIG_LOGO_M32R_CLUT224
+ /* M32R Linux logo */
+ logo = &logo_m32r_clut224;
+#endif
}
return logo;
}
diff --git a/drivers/video/logo/logo_m32r_clut224.ppm b/drivers/video/logo/logo_m32r_clut224.ppm
new file mode 100644
index 00000000000..8b2983c5a0b
--- /dev/null
+++ b/drivers/video/logo/logo_m32r_clut224.ppm
@@ -0,0 +1,1292 @@
+P3
+# CREATOR: The GIMP's PNM Filter Version 1.0
+#
+# Note: how to convert ppm to pnm(ascii).
+# $ convert -posterize 224 m32r.ppm - | pnm2asc -f5 >logo_m32r_clut224.ppm
+#
+# convert - imagemagick: /usr/bin/convert
+# pnm2asc - pnm to ascii-pnm format converter
+# http://www.is.aist.go.jp/etlcdb/util/p2a.htm#English
+
+80 80
+255
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 43 43 43 75 75 75 27 27 27 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 59 59 59 123 123 123 67 67 67 27 27 27
+ 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 10 6 3 59 59 59 80 80 80 43 43 43 27 27 27
+ 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 19 19 19 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 2 2 3 10 6 3 10 6 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 10 6 3 11 11 11 11 11 11 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 2 2 3 2 2 3 27 27 27 10 6 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 19 19 19 2 2 3 2 2 3 51 51 51 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 123 123 123 196 196 196 115 115 115 2 2 3
+ 2 2 3 2 2 3 2 2 3 75 75 75 141 141 140
+ 172 172 172 196 196 196 190 189 188 2 2 3 11 11 11
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 27 27 27 164 164 164 228 228 228 221 221 220 10 6 3
+ 2 2 3 2 2 3 2 2 3 172 172 172 245 245 245
+ 254 254 252 254 254 252 221 221 220 35 35 35 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 164 164 164 228 228 228 35 35 35 236 236 236 236 236 236
+ 2 2 3 11 11 11 2 2 3 254 254 252 245 245 245
+ 2 2 3 75 75 75 245 245 245 245 245 245 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 212 212 212 2 2 3 51 51 51 11 11 11 245 245 245
+ 27 27 27 80 80 80 10 6 3 254 254 252 2 2 3
+ 2 2 3 91 91 91 19 19 19 254 254 252 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 196 196 196 10 6 3 2 2 3 11 11 11 107 107 107
+ 49 35 5 57 42 11 31 22 3 236 236 236 2 2 3
+ 2 2 3 2 2 3 2 2 3 254 254 252 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 107 107 107 221 221 220 2 2 3 64 43 7 194 148 10
+ 236 188 10 225 180 10 170 126 10 236 188 10 94 86 67
+ 2 2 3 2 2 3 204 204 204 236 236 236 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 228 228 228 182 126 10 218 164 9 236 188 10
+ 236 188 10 237 204 14 236 205 40 246 214 48 246 214 48
+ 245 189 11 209 156 9 196 196 196 11 11 11 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 165 114 10 207 148 7 229 172 9 236 180 10
+ 236 196 11 237 204 14 242 218 43 246 218 75 246 218 19
+ 246 213 13 246 218 19 244 205 11 218 164 9 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 164 109 5 192 133 7 224 165 9 236 180 10 236 188 10
+ 236 196 11 241 212 42 246 218 75 246 218 19 246 218 19
+ 246 218 19 236 196 11 150 114 10 229 172 9 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 165 114 10 201 142 7 229 172 9 242 182 11 236 188 10
+ 237 204 14 245 213 67 246 218 19 246 213 13 246 213 13
+ 154 119 10 207 148 7 218 164 9 216 156 8 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 120 78 3 225 180 10 245 189 11 236 205 40
+ 241 212 42 241 212 17 237 204 14 148 107 9 182 126 10
+ 216 156 8 218 164 9 207 148 7 82 70 43 2 2 3
+ 2 2 3 123 123 123 35 35 35 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 10 6 3 180 180 180 156 102 5 135 88 5 142 106 7
+ 126 98 11 165 114 10 185 132 9 207 148 7 215 150 13
+ 199 140 8 188 148 71 196 196 196 190 189 188 2 2 3
+ 2 2 3 11 11 11 132 132 132 75 75 75 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 10 6 3 190 189 188 190 189 188 151 97 5 192 133 7
+ 207 148 7 206 142 8 199 140 8 180 121 7 180 132 31
+ 190 189 188 190 189 188 212 212 212 212 212 212 107 107 107
+ 2 2 3 2 2 3 99 99 99 51 51 51 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 190 189 188 190 189 188 190 189 188 136 95 7
+ 151 97 5 151 97 5 151 97 5 183 156 91 190 189 188
+ 190 189 188 228 228 228 254 254 252 254 254 252 221 221 220
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 10 6 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 75 75 75 245 245 245 196 196 196 190 189 188 190 189 188
+ 190 189 188 196 196 196 190 189 188 190 189 188 204 204 204
+ 236 236 236 254 254 252 254 254 252 254 254 252 254 254 252
+ 35 35 35 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 27 27 27 2 2 3
+ 245 245 245 254 254 252 245 245 245 190 189 188 190 189 188
+ 190 189 188 190 189 188 190 189 188 212 212 212 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 10 6 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 2 2 3 132 132 132
+ 254 254 252 254 254 252 254 254 252 236 236 236 196 196 196
+ 190 189 188 204 204 204 245 245 245 245 245 245 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 80 80 80 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 2 2 3 2 2 3 2 2 3 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 2 2 3 2 2 3 212 212 212 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 2 2 3 2 2 3 204 204 204 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 245 245 245 236 236 236 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 2 2 3 11 11 11 164 164 164 212 212 212
+ 236 236 236 245 245 245 254 254 252 236 236 236 221 221 220
+ 221 221 220 228 228 228 245 245 245 245 245 245 245 245 245
+ 236 236 236 221 221 220 212 212 212 204 204 204 204 204 204
+ 196 196 196 204 204 204 59 59 59 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 2 2 3 27 27 27 172 172 172 212 212 212
+ 236 236 236 254 254 252 254 254 252 254 254 252 228 228 228
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 245 245 245 221 221 220 204 204 204 196 196 196
+ 196 196 196 196 196 196 228 228 228 19 19 19 2 2 3
+ 80 80 80 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 2 2 3 2 2 3
+ 11 11 11 2 2 3 164 164 164 236 236 236 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 236 236 236 212 212 212 196 196 196 245 245 245 2 2 3
+ 2 2 3 11 11 11 51 51 51 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 2 2 3 86 86 83
+ 2 2 3 27 27 27 236 236 236 254 254 252 254 254 252
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 212 212 212 196 196 196 91 91 91
+ 2 2 3 2 2 3 2 2 3 11 11 11 2 2 3
+ 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 2 2 3 2 2 3
+ 2 2 3 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 221 221 220 245 245 245
+ 2 2 3 11 11 11 43 43 43 19 19 19 10 6 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 2 2 3 80 80 80 2 2 3
+ 2 2 3 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 43 43 43 27 27 27 80 80 80 19 19 19 80 80 80
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
+ 245 245 245 254 254 252 254 254 252 17 11 233 254 254 252
+ 254 254 252 254 254 252 254 254 252 236 236 236 17 11 233
+ 17 11 233 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 11 11 11 11 11 11 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 2 2 3 67 67 67 2 2 3 19 19 19
+ 254 254 252 254 254 252 245 245 245 17 11 233 245 245 245
+ 254 254 252 254 254 252 17 11 233 228 228 228 17 11 233
+ 17 11 233 17 11 233 17 11 233 254 254 252 17 11 233
+ 17 11 233 254 254 252 254 254 252 17 11 233 17 11 233
+ 17 11 233 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
+ 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 10 6 3 11 11 11 2 2 3 228 228 228
+ 254 254 252 254 254 252 254 254 252 17 11 233 254 254 252
+ 254 254 252 17 11 233 17 11 233 17 11 233 245 245 245
+ 254 254 252 254 254 252 17 11 233 17 11 233 17 11 233
+ 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
+ 17 11 233 17 11 233 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
+ 27 27 27 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 2 2 3 2 2 3 2 2 3 2 2 3 254 254 252
+ 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
+ 17 11 233 17 11 233 17 11 233 17 11 233 254 254 252
+ 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
+ 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
+ 254 254 252 17 11 233 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
+ 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 19 19 19 2 2 3 2 2 3 254 254 252
+ 254 254 252 254 254 252 17 11 233 245 245 245 17 11 233
+ 17 11 233 245 245 245 254 254 252 17 11 233 254 254 252
+ 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
+ 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
+ 17 11 233 17 11 233 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
+ 2 2 3 19 19 19 2 2 3 19 19 19 254 254 252
+ 254 254 252 245 245 245 17 11 233 254 254 252 17 11 233
+ 17 11 233 254 254 252 254 254 252 17 11 233 254 254 252
+ 254 254 252 254 254 252 17 11 233 17 11 233 254 254 252
+ 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
+ 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 43 43 43 2 2 3 43 43 43 254 254 252
+ 245 245 245 254 254 252 17 11 233 254 254 252 17 11 233
+ 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
+ 17 11 233 17 11 233 17 11 233 254 254 252 17 11 233
+ 17 11 233 17 11 233 17 11 233 17 11 233 17 11 233
+ 245 245 245 254 254 252 17 11 233 254 254 252 254 254 252
+ 245 245 245 2 2 3 2 2 3 2 2 3 11 11 11
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 75 75 75 2 2 3 99 99 99 254 254 252
+ 254 254 252 254 254 252 17 11 233 254 254 252 254 254 252
+ 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
+ 254 254 252 17 11 233 245 245 245 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 2 2 3 75 75 75
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
+ 2 2 3 2 2 3 11 11 11 107 107 107 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 245 245 245 254 254 252 245 245 245 236 236 236 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 2 2 3 11 11 11 19 19 19
+ 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 2 2 3 11 11 11
+ 140 102 3 11 11 11 10 6 3 67 67 67 254 254 252
+ 245 245 245 245 245 245 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 245 245 245 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 2 2 3 43 43 43 2 2 3 2 2 3
+ 2 2 3 11 11 11 67 67 67 11 11 11 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 185 132 9 242 182 11
+ 245 189 11 245 189 11 49 35 5 2 2 3 228 228 228
+ 254 254 252 254 254 252 254 254 252 245 245 245 254 254 252
+ 254 254 252 254 254 252 254 254 252 228 228 228 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 245 238 222 232 189 94
+ 226 186 99 43 43 43 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 59 59 59 2 2 3
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 216 156 8 236 180 22
+ 245 189 11 245 189 11 245 189 11 49 35 5 11 11 11
+ 212 212 212 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 245 245 245 254 254 252 254 254 252 229 172 9 246 218 19
+ 246 218 19 41 27 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 19 19 19 27 27 27 196 154 14
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 199 140 8 229 172 9 242 182 11
+ 245 189 11 245 189 11 245 189 11 244 196 10 2 2 3
+ 2 2 3 115 115 115 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
+ 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 224 165 9 245 189 11
+ 236 196 11 19 19 19 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 11 11 11 236 196 11
+ 244 205 11 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 182 126 10 209 156 9 215 150 13
+ 193 140 10 207 148 24 216 156 8 242 182 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 209 156 9
+ 2 2 3 2 2 3 43 43 43 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 236 236 236 216 156 8 245 189 11
+ 229 172 9 64 43 7 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 207 148 7 236 188 10
+ 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 180 121 7 216 156 8 242 182 11 236 180 10
+ 229 172 9 242 182 11 242 182 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 237 204 14
+ 170 126 10 2 2 3 2 2 3 11 11 11 236 236 236
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 204 204 204 196 196 196 216 156 8 236 180 10
+ 224 165 9 182 126 10 73 48 6 2 2 3 2 2 3
+ 2 2 3 41 27 3 199 140 8 229 172 9 236 180 10
+ 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 185 132 9 229 172 9 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 226 188 11 2 2 3 2 2 3 2 2 3 11 11 11
+ 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 196 196 196 196 196 196 215 150 13 236 180 10
+ 229 172 9 201 142 7 185 132 9 180 121 7 173 120 10
+ 180 121 7 192 133 7 229 172 9 242 182 11 245 189 11
+ 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 180 126 47 224 165 9 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 236 188 10 193 140 10 2 2 3 2 2 3 2 2 3
+ 2 2 3 212 212 212 254 254 252 245 245 245 245 245 245
+ 254 254 252 254 254 252 254 254 252 245 245 245 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 204 204 204 196 196 196 199 140 8 229 172 9
+ 236 180 10 218 164 9 215 150 13 207 148 7 207 148 7
+ 216 156 8 229 172 9 245 189 11 245 189 11 245 189 11
+ 245 189 11 242 182 11 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 185 132 9 216 156 8 242 182 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 236 196 11 19 19 19 2 2 3 2 2 3
+ 2 2 3 11 11 11 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 245 245 245 254 254 252 254 254 252
+ 245 245 245 221 221 220 196 196 196 185 132 9 229 172 9
+ 242 182 11 229 172 9 224 165 9 218 164 9 224 165 9
+ 229 172 9 236 180 10 245 189 11 245 189 11 245 189 11
+ 245 189 11 236 180 22 242 182 11 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 236 180 22 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 236 188 10 225 180 10 2 2 3 2 2 3
+ 2 2 3 11 11 11 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 221 221 220 19 19 19 185 132 9 224 165 9
+ 245 189 11 245 189 11 242 182 11 236 180 10 236 180 10
+ 242 182 11 242 182 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 196 154 14
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 207 148 7 236 180 22 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
+ 245 189 11 245 189 11 237 204 14 135 88 5 2 2 3
+ 27 27 27 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 245 245 245 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 67 67 67 19 13 3 185 132 9 229 172 9
+ 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 236 180 22 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 245 189 11 242 182 11
+ 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 236 188 10 226 188 11 104 83 48
+ 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
+ 254 254 252 254 254 252 245 245 245 254 254 252 245 245 245
+ 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
+ 2 2 3 2 2 3 56 38 5 185 132 9 229 172 9
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
+ 229 172 9 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 182 126 10 215 150 13 242 182 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 242 182 11 245 189 11 236 196 11 216 156 8
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 245 245 245 2 2 3
+ 2 2 3 2 2 3 75 54 3 182 126 10 229 172 9
+ 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 229 172 9
+ 207 148 24 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 192 133 7 229 172 9 242 182 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 242 182 11 225 180 10 224 165 9
+ 107 69 5 245 245 245 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
+ 254 254 252 236 236 236 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 91 67 9 182 126 10 229 172 9
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 242 182 11 242 182 11 216 156 8 180 126 47
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 206 142 8 224 165 9 245 189 11 242 182 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
+ 245 189 11 245 189 11 242 182 11 242 182 11 216 156 8
+ 156 102 5 19 13 3 43 43 43 196 196 196 254 254 252
+ 245 245 245 254 254 252 254 254 252 204 204 204 51 51 51
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 95 62 5 185 132 9 229 172 9
+ 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 242 182 11 245 189 11 245 189 11
+ 236 180 22 216 156 8 206 142 8 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 192 133 7 215 150 13 229 172 9 229 172 9
+ 236 180 10 236 180 22 242 182 11 242 182 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 245 189 11 245 189 11 229 172 9 216 156 8
+ 156 102 5 83 54 6 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 115 73 3 185 132 9 229 172 9
+ 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
+ 245 189 11 242 182 11 229 172 9 229 172 9 216 156 8
+ 180 121 7 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 180 121 7 182 126 10 192 133 7 199 140 8
+ 207 148 7 215 150 13 216 156 8 224 165 9 229 172 9
+ 236 180 22 245 189 11 242 182 11 245 189 11 242 182 11
+ 245 189 11 245 189 11 242 182 11 229 172 9 199 140 8
+ 151 97 5 101 67 7 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 115 73 3 180 121 7 216 156 8
+ 236 180 22 242 182 11 245 189 11 245 189 11 242 182 11
+ 236 180 10 224 165 9 215 150 13 206 142 8 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 156 102 5 164 109 5 172 114 5 180 121 7 180 121 7
+ 192 133 7 201 142 7 216 156 8 224 165 9 236 180 22
+ 245 189 11 242 182 11 229 172 9 201 142 7 172 114 5
+ 125 83 5 83 54 6 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
+ 2 2 3 2 2 3 91 58 5 156 102 5 192 133 7
+ 216 156 8 229 172 9 236 180 10 236 180 10 229 172 9
+ 215 150 13 199 140 8 164 109 5 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 120 78 3 132 82 3
+ 151 97 5 157 106 7 180 121 7 185 132 9 193 140 10
+ 207 148 7 207 148 7 192 133 7 172 114 5 132 82 3
+ 101 67 7 41 27 3 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 73 48 6 143 90 3 180 121 7
+ 192 133 7 207 148 7 207 148 7 201 142 7 185 132 9
+ 173 120 10 136 95 7 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 91 58 5 125 83 5 135 88 5
+ 144 95 7 151 97 5 132 82 3 115 73 3 95 62 5
+ 64 43 7 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 64 43 7 91 58 5 151 97 5
+ 157 106 7 172 114 5 172 114 5 164 109 5 151 97 5
+ 85 59 6 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 73 48 6
+ 91 58 5 95 62 5 95 62 5 91 58 5 56 38 5
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 83 54 6
+ 107 69 5 132 82 3 125 83 5 101 67 7 71 47 31
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
+ 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 3dd1de1539d..b00887e9851 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -523,7 +523,7 @@ int __init platinumfb_setup(char *options)
#define invalidate_cache(addr)
#endif
-static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match)
+static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match)
{
struct device_node *dp = odev->node;
struct fb_info *info;
@@ -647,12 +647,10 @@ static int __devexit platinumfb_remove(struct of_device* odev)
return 0;
}
-static struct of_match platinumfb_match[] =
+static struct of_device_id platinumfb_match[] =
{
{
.name = "platinum",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH,
},
{},
};
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 789de13f461..3848be2b9d2 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -67,12 +67,18 @@ static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = {
static inline u8
s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno)
{
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+ regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
+#endif
return readb(par->regs + regno);
}
static inline void
s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value)
{
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+ regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
+#endif
writeb(value, par->regs + regno);
}
@@ -259,7 +265,11 @@ s1d13xxxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
dbg("s1d13xxxfb_setcolreg: pseudo %d, val %08x\n",
regno, pseudo_val);
+#if defined(CONFIG_PLAT_MAPPI)
+ ((u32 *)info->pseudo_palette)[regno] = cpu_to_le16(pseudo_val);
+#else
((u32 *)info->pseudo_palette)[regno] = pseudo_val;
+#endif
break;
case FB_VISUAL_PSEUDOCOLOR:
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 8fadcdae6f4..f4633d1891f 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2113,7 +2113,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
printk(KERN_DEBUG "state: %u\n", state);
acquire_console_sem();
- fb_set_suspend(info, state);
+ fb_set_suspend(info, pci_choose_state(dev, state));
savage_disable_mmio(par);
release_console_sem();
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 312cf3220f1..8a9c4282250 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -516,6 +516,7 @@ static void w1_slave_found(unsigned long data, u64 rn)
struct w1_reg_num *tmp;
int family_found = 0;
struct w1_master *dev;
+ u64 rn_le = cpu_to_le64(rn);
dev = w1_search_master(data);
if (!dev) {
@@ -544,10 +545,8 @@ static void w1_slave_found(unsigned long data, u64 rn)
slave_count++;
}
- rn = cpu_to_le64(rn);
-
if (slave_count == dev->slave_count &&
- rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+ rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn_le, 7)) {
w1_attach_slave_device(dev, tmp);
}